| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package cluster
- import (
- "encoding/base64"
- "fmt"
- "net/http"
- "regexp"
- "github.com/porter-dev/porter/api/server/handlers"
- "github.com/porter-dev/porter/api/server/shared"
- "github.com/porter-dev/porter/api/server/shared/apierrors"
- "github.com/porter-dev/porter/api/server/shared/config"
- "github.com/porter-dev/porter/api/types"
- "github.com/porter-dev/porter/internal/kubernetes/resolver"
- "github.com/porter-dev/porter/internal/models"
- "github.com/porter-dev/porter/internal/repository"
- )
- type CreateClusterManualHandler struct {
- handlers.PorterHandlerReadWriter
- }
- func NewCreateClusterManualHandler(
- config *config.Config,
- decoderValidator shared.RequestDecoderValidator,
- writer shared.ResultWriter,
- ) *CreateClusterManualHandler {
- return &CreateClusterManualHandler{
- PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
- }
- }
- func (c *CreateClusterManualHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- // read the project from context
- proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
- request := &types.CreateClusterManualRequest{}
- if ok := c.DecodeAndValidate(w, r, request); !ok {
- return
- }
- cluster, err := getClusterModelFromManualRequest(c.Repo(), proj, request)
- if err != nil {
- c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
- return
- }
- cluster, err = c.Repo().Cluster().CreateCluster(cluster)
- if err != nil {
- c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
- return
- }
- c.WriteResult(w, r, cluster.ToClusterType())
- }
- func getClusterModelFromManualRequest(
- repo repository.Repository,
- project *models.Project,
- request *types.CreateClusterManualRequest,
- ) (*models.Cluster, error) {
- var authMechanism models.ClusterAuth
- if request.GCPIntegrationID != 0 {
- authMechanism = models.GCP
- // check that the integration exists
- _, err := repo.GCPIntegration().ReadGCPIntegration(project.ID, request.GCPIntegrationID)
- if err != nil {
- return nil, fmt.Errorf("gcp integration not found")
- }
- } else if request.AWSIntegrationID != 0 {
- authMechanism = models.AWS
- // check that the integration exists
- _, err := repo.AWSIntegration().ReadAWSIntegration(project.ID, request.AWSIntegrationID)
- if err != nil {
- return nil, fmt.Errorf("aws integration not found")
- }
- } else {
- return nil, fmt.Errorf("must include aws or gcp integration id")
- }
- cert := make([]byte, 0)
- if request.CertificateAuthorityData != "" {
- // determine if data is base64 decoded using regex
- re := regexp.MustCompile(`^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$`)
- // if it matches the base64 regex, decode it
- if re.MatchString(request.CertificateAuthorityData) {
- decoded, err := base64.StdEncoding.DecodeString(request.CertificateAuthorityData)
- if err != nil {
- return nil, err
- }
- cert = []byte(decoded)
- }
- }
- return &models.Cluster{
- ProjectID: project.ID,
- AuthMechanism: authMechanism,
- Name: request.Name,
- Server: request.Server,
- GCPIntegrationID: request.GCPIntegrationID,
- AWSIntegrationID: request.AWSIntegrationID,
- CertificateAuthorityData: cert,
- }, nil
- }
- func createClusterFromCandidate(
- repo repository.Repository,
- project *models.Project,
- user *models.User,
- candidate *models.ClusterCandidate,
- clResolver *types.ClusterResolverAll,
- ) (*models.Cluster, *models.ClusterCandidate, error) {
- // we query the repo again to get the decrypted version of the cluster candidate
- cc, err := repo.Cluster().ReadClusterCandidate(project.ID, candidate.ID)
- if err != nil {
- return nil, nil, err
- }
- cResolver := &resolver.CandidateResolver{
- Resolver: clResolver,
- ClusterCandidateID: cc.ID,
- ProjectID: project.ID,
- UserID: user.ID,
- }
- err = cResolver.ResolveIntegration(repo)
- if err != nil {
- return nil, nil, err
- }
- cluster, err := cResolver.ResolveCluster(repo)
- if err != nil {
- return nil, nil, err
- }
- cc, err = repo.Cluster().UpdateClusterCandidateCreatedClusterID(cc.ID, cluster.ID)
- if err != nil {
- return nil, nil, err
- }
- return cluster, cc, nil
- }
|