Просмотр исходного кода

Merge branch 'master' of github.com:porter-dev/porter into stacks-improved-debug-flow-deploy

Feroze Mohideen 2 лет назад
Родитель
Сommit
7b400010fe

+ 149 - 50
api/server/handlers/namespace/create_stacks_env_group.go

@@ -20,6 +20,7 @@ import (
 	"github.com/porter-dev/porter/api/server/shared/config"
 	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/internal/helm"
+	"github.com/porter-dev/porter/internal/helm/loader"
 	"github.com/porter-dev/porter/internal/kubernetes"
 	"github.com/porter-dev/porter/internal/kubernetes/envgroup"
 	"github.com/porter-dev/porter/internal/models"
@@ -46,12 +47,14 @@ func NewCreateStacksEnvGroupHandler(
 
 func (c *CreateStacksEnvGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	request := &types.CreateStacksEnvGroupRequest{}
-
+	ctx := r.Context()
+	ctx, span := telemetry.NewSpan(ctx, "serve-create-env-group-stacks")
+	defer span.End()
 	if ok := c.DecodeAndValidate(w, r, request); !ok {
 		return
 	}
-	namespace := r.Context().Value(types.NamespaceScope).(string)
-	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
+	namespace := ctx.Value(types.NamespaceScope).(string)
+	cluster, _ := ctx.Value(types.ClusterScope).(*models.Cluster)
 
 	agent, err := c.GetAgent(r, cluster, namespace)
 	if err != nil {
@@ -63,7 +66,7 @@ func (c *CreateStacksEnvGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.R
 	aggregateReleases := []*release.Release{}
 	for i := range request.Apps {
 		namespaceStack := "porter-stack-" + request.Apps[i]
-		helmAgent, err := c.GetHelmAgent(r.Context(), r, cluster, namespaceStack)
+		helmAgent, err := c.GetHelmAgent(ctx, r, cluster, namespaceStack)
 		if err != nil {
 			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, 504, "error getting agent"))
 			return
@@ -77,7 +80,7 @@ func (c *CreateStacksEnvGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.R
 		aggregateReleases = append(aggregateReleases, releases...)
 	}
 
-	errors := rolloutStacksApplications(c, c.Config(), cluster, request.Name, namespace, agent, aggregateReleases, r, w)
+	errors := rolloutStacksApplications(c, c.Config(), cluster, request.Name, namespace, agent, aggregateReleases, r, ctx, w)
 
 	if len(errors) > 0 {
 		errStrArr := make([]string, 0)
@@ -101,12 +104,14 @@ func rolloutStacksApplications(
 	agent *kubernetes.Agent,
 	releases []*release.Release,
 	r *http.Request,
+	ctx context.Context,
 	w http.ResponseWriter,
 ) []error {
 	registries, err := config.Repo.Registry().ListRegistriesByProjectID(cluster.ProjectID)
 	if err != nil {
 		return []error{err}
 	}
+	ctx, span := telemetry.NewSpan(ctx, "rollout-env-group-stacks")
 	// asynchronously update releases with that image repo uri
 	var wg sync.WaitGroup
 	mu := &sync.Mutex{}
@@ -116,7 +121,12 @@ func rolloutStacksApplications(
 		index := i
 		release := rel
 		wg.Add(1)
-		cm, _, err := agent.GetLatestVersionedConfigMap(envGroupName, "porter-stack-"+releases[index].Name)
+		suffix := "-r"
+		releaseName := release.Name
+		if strings.HasSuffix(release.Name, suffix) {
+			releaseName = strings.TrimSuffix(releaseName, suffix)
+		}
+		cm, _, err := agent.GetLatestVersionedConfigMap(envGroupName, "porter-stack-"+releaseName)
 		if err != nil {
 			return []error{err}
 		}
@@ -161,57 +171,118 @@ func rolloutStacksApplications(
 			if release.Chart.Name() == "job" {
 				newConfig["paused"] = true
 			}
+			if !strings.HasSuffix(release.Name, suffix) {
+				if req := releases[index].Chart.Metadata.Dependencies; req != nil {
+					for _, dep := range req {
+						dep.Name = getType(dep.Name)
+					}
+				}
 
-			if req := releases[index].Chart.Metadata.Dependencies; req != nil {
-				for _, dep := range req {
-					dep.Name = getType(dep.Name)
+				metadata := &chart.Metadata{
+					Name:        "umbrella",
+					Description: "Web application that is exposed to external traffic.",
+					Version:     "0.96.0",
+					APIVersion:  "v2",
+					Home:        "https://getporter.dev/",
+					Icon:        "https://user-images.githubusercontent.com/65516095/111255214-07d3da80-85ed-11eb-99e2-fddcbdb99bdb.png",
+					Keywords: []string{
+						"porter",
+						"application",
+						"service",
+						"umbrella",
+					},
+					Type:         "application",
+					Dependencies: releases[index].Chart.Metadata.Dependencies,
+				}
+				charter := &chart.Chart{
+					Metadata: metadata,
+				}
+				conf := &helm.InstallChartConfig{
+					Chart:      charter,
+					Name:       releases[index].Name,
+					Namespace:  "porter-stack-" + releases[index].Name,
+					Values:     newConfig,
+					Cluster:    cluster,
+					Repo:       config.Repo,
+					Registries: registries,
 				}
-			}
 
-			metadata := &chart.Metadata{
-				Name:        "umbrella",
-				Description: "Web application that is exposed to external traffic.",
-				Version:     "0.96.0",
-				APIVersion:  "v2",
-				Home:        "https://getporter.dev/",
-				Icon:        "https://user-images.githubusercontent.com/65516095/111255214-07d3da80-85ed-11eb-99e2-fddcbdb99bdb.png",
-				Keywords: []string{
-					"porter",
-					"application",
-					"service",
-					"umbrella",
-				},
-				Type:         "application",
-				Dependencies: releases[index].Chart.Metadata.Dependencies,
-			}
-			charter := &chart.Chart{
-				Metadata: metadata,
-			}
-			conf := &helm.InstallChartConfig{
-				Chart:      charter,
-				Name:       releases[index].Name,
-				Namespace:  "porter-stack-" + releases[index].Name,
-				Values:     newConfig,
-				Cluster:    cluster,
-				Repo:       config.Repo,
-				Registries: registries,
-			}
-			helmAgent, err := c.GetHelmAgent(r.Context(), r, cluster, "porter-stack-"+releases[index].Name)
-			if err != nil {
-				fmt.Println("Could Not Get Helm Agent ")
-				return
-			}
-			_, err = helmAgent.UpgradeInstallChart(r.Context(), conf, config.DOConf, config.ServerConf.DisablePullSecretsInjection)
-			if err != nil {
-				mu.Lock()
-				errors = append(errors, err)
-				mu.Unlock()
-				return
+				helmAgent, err := c.GetHelmAgent(ctx, r, cluster, "porter-stack-"+releases[index].Name)
+				if err != nil {
+					fmt.Println("Could Not Get Helm Agent ")
+					return
+				}
+				_, err = helmAgent.UpgradeInstallChart(ctx, conf, config.DOConf, config.ServerConf.DisablePullSecretsInjection)
+				if err != nil {
+					mu.Lock()
+					errors = append(errors, err)
+					mu.Unlock()
+					return
+				}
+			} else {
+				helmAgent, err := c.GetHelmAgent(ctx, r, cluster, "porter-stack-"+releaseName)
+				if err != nil {
+					fmt.Println("Could Not Get Helm Agent ")
+					return
+				}
+				helmRelease, err := helmAgent.GetRelease(ctx, rel.Name, 0, false)
+				if err != nil {
+					telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "creating-pre-deploy-job", Value: true})
+					conf, err := createReleaseJobChart(
+						ctx,
+						releaseName,
+						newConfig,
+						c.Config().ServerConf.DefaultApplicationHelmRepoURL,
+						registries,
+						cluster,
+						c.Repo(),
+					)
+					if err != nil {
+						err = telemetry.Error(ctx, span, err, "error making config for pre-deploy job chart")
+						c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+						return
+					}
+
+					_, err = helmAgent.InstallChart(ctx, conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)
+					if err != nil {
+						err = telemetry.Error(ctx, span, err, "error installing pre-deploy job chart")
+						c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+						_, uninstallChartErr := helmAgent.UninstallChart(ctx, fmt.Sprintf("%s-r", releaseName))
+						if uninstallChartErr != nil {
+							uninstallChartErr = telemetry.Error(ctx, span, err, "error uninstalling pre-deploy job chart after failed install")
+							c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(uninstallChartErr, http.StatusInternalServerError))
+						}
+						return
+					}
+				} else {
+					telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "updating-pre-deploy-job", Value: true})
+					chart, err := loader.LoadChartPublic(ctx, c.Config().Metadata.DefaultAppHelmRepoURL, "job", "")
+					if err != nil {
+						err = telemetry.Error(ctx, span, err, "error loading latest job chart")
+						c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+						return
+					}
+
+					conf := &helm.UpgradeReleaseConfig{
+						Name:       helmRelease.Name,
+						Cluster:    cluster,
+						Repo:       c.Repo(),
+						Registries: registries,
+						Values:     newConfig,
+						Chart:      chart,
+					}
+					_, err = helmAgent.UpgradeReleaseByValues(ctx, conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
+					if err != nil {
+						err = telemetry.Error(ctx, span, err, "error upgrading pre-deploy job chart")
+						c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+						return
+					}
+				}
 			}
 		}()
 
 		app, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, releases[index].Name)
-		ctx, span := telemetry.NewSpan(r.Context(), "serve-create-porter-app")
+		ctx, span := telemetry.NewSpan(ctx, "serve-update-porter-app")
 		updatedPorterApp, err := c.Repo().PorterApp().UpdatePorterApp(app)
 		if err != nil {
 			err = telemetry.Error(ctx, span, err, "error writing updated app to DB")
@@ -486,3 +557,31 @@ func attemptToGetImageInfoFromRelease(values map[string]interface{}) types.Image
 
 	return imageInfo
 }
+
+func createReleaseJobChart(
+	ctx context.Context,
+	stackName string,
+	values map[string]interface{},
+	repoUrl string,
+	registries []*models.Registry,
+	cluster *models.Cluster,
+	repo repository.Repository,
+) (*helm.InstallChartConfig, error) {
+	chart, err := loader.LoadChartPublic(ctx, repoUrl, "job", "")
+	if err != nil {
+		return nil, err
+	}
+
+	releaseName := fmt.Sprintf("%s-r", stackName)
+	namespace := fmt.Sprintf("porter-stack-%s", stackName)
+
+	return &helm.InstallChartConfig{
+		Chart:      chart,
+		Name:       releaseName,
+		Namespace:  namespace,
+		Values:     values,
+		Cluster:    cluster,
+		Repo:       repo,
+		Registries: registries,
+	}, nil
+}

+ 12 - 2
api/server/handlers/registry/create_repository.go

@@ -11,6 +11,7 @@ import (
 	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/internal/models"
 	"github.com/porter-dev/porter/internal/registry"
+	"github.com/porter-dev/porter/internal/telemetry"
 )
 
 type RegistryCreateRepositoryHandler struct {
@@ -30,12 +31,15 @@ func NewRegistryCreateRepositoryHandler(
 func (p *RegistryCreateRepositoryHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	ctx := r.Context()
 	reg, _ := ctx.Value(types.RegistryScope).(*models.Registry)
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-create-repository")
+	defer span.End()
 
 	request := &types.CreateRegistryRepositoryRequest{}
 
 	ok := p.DecodeAndValidate(w, r, request)
-
 	if !ok {
+		err := telemetry.Error(ctx, span, nil, "error decoding request")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
 		return
 	}
 
@@ -45,10 +49,16 @@ func (p *RegistryCreateRepositoryHandler) ServeHTTP(w http.ResponseWriter, r *ht
 	// parse the name from the registry
 	nameSpl := strings.Split(request.ImageRepoURI, "/")
 	repoName := strings.ToLower(strings.ReplaceAll(nameSpl[len(nameSpl)-1], "_", "-"))
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "repo-name", Value: repoName},
+		telemetry.AttributeKV{Key: "registry-id", Value: reg.ID},
+		telemetry.AttributeKV{Key: "image-repo-uri", Value: request.ImageRepoURI},
+	)
 
 	err := regAPI.CreateRepository(ctx, p.Config(), repoName)
 	if err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err = telemetry.Error(ctx, span, err, "error creating repository")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 

+ 31 - 32
cli/cmd/preview/build_image_driver.go

@@ -135,43 +135,42 @@ func (d *BuildDriver) Apply(resource *models.Resource) (*models.Resource, error)
 		return nil, err
 	}
 
-	if d.config.Build.UsePackCache {
-		err := config.SetDockerConfig(client)
-		if err != nil {
-			return nil, err
-		}
+	// create repository if it does not exist
+	repoResp, err := client.ListRegistryRepositories(context.Background(), d.target.Project, regID)
+	if err != nil {
+		return nil, err
+	}
 
-		if d.config.Build.Method == "pack" {
-			repoResp, err := client.ListRegistryRepositories(context.Background(), d.target.Project, regID)
-			if err != nil {
-				return nil, err
-			}
+	repos := *repoResp
 
-			repos := *repoResp
+	found := false
 
-			found := false
+	for _, repo := range repos {
+		if repo.URI == imageURL {
+			found = true
+			break
+		}
+	}
 
-			for _, repo := range repos {
-				if repo.URI == imageURL {
-					found = true
-					break
-				}
-			}
+	if !found {
+		err = client.CreateRepository(
+			context.Background(),
+			d.target.Project,
+			regID,
+			&types.CreateRegistryRepositoryRequest{
+				ImageRepoURI: imageURL,
+			},
+		)
 
-			if !found {
-				err = client.CreateRepository(
-					context.Background(),
-					d.target.Project,
-					regID,
-					&types.CreateRegistryRepositoryRequest{
-						ImageRepoURI: imageURL,
-					},
-				)
-
-				if err != nil {
-					return nil, err
-				}
-			}
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	if d.config.Build.UsePackCache {
+		err := config.SetDockerConfig(client)
+		if err != nil {
+			return nil, err
 		}
 	}
 

+ 3 - 1
dashboard/src/components/ProvisionerFlow.tsx

@@ -76,7 +76,9 @@ const ProvisionerFlow: React.FC<Props> = ({}) => {
                         provider === "gcp"
                       )
                     ) {
-                      openCostConsentModal(provider);
+                      // openCostConsentModal(provider);
+                      setSelectedProvider(provider);
+                      setCurrentStep("credentials");
                     }
                   }}
                 >

+ 5 - 0
dashboard/src/hosted.index.html

@@ -155,6 +155,11 @@
       rel="stylesheet"
       href="https://cdn.jsdelivr.net/gh/devicons/devicon@v2.14.0/devicon.min.css"
     />
+
+    <script>
+      !function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
+      posthog.init('phc_Bna7PjZKfVnkjiDOHx6gUIuIbvWv4M8zsqxYxuRYVo4',{api_host:'https://app.posthog.com'})
+    </script>
   </head>
 
   <body>

+ 7 - 22
dashboard/src/main/home/cluster-dashboard/env-groups/ExpandedEnvGroup.tsx

@@ -247,14 +247,16 @@ export const ExpandedEnvGroupFC = ({
             }
           )
           .then((res) => res.data);
-        setButtonStatus("successful");
+        if (!currentProject?.simplified_view_enabled) {
+          setButtonStatus("successful");
+        }
         updateEnvGroup(updatedEnvGroup);
 
         setTimeout(() => setButtonStatus(""), 1000);
 
 
         if (currentProject?.simplified_view_enabled) {
-
+          setButtonStatus("loading");
           //Clone the env group to all applications
           try {
             // Check if updatedEnvGroup.applications is an array and it has elements
@@ -283,6 +285,7 @@ export const ExpandedEnvGroupFC = ({
 
           //Update the Stacks Env Groups with the new variables
           try {
+            setButtonStatus("loading");
             await api
               .updateStacksEnvGroup<PopulatedEnvGroup>(
                 "<token>",
@@ -298,8 +301,7 @@ export const ExpandedEnvGroupFC = ({
                   namespace,
                 }
               )
-              .then((res) => res.data);
-            setButtonStatus("successful");
+            setButtonStatus("successful")
           } catch (error) {
             setButtonStatus("Couldn't update successfully");
             setCurrentError(error);
@@ -307,30 +309,12 @@ export const ExpandedEnvGroupFC = ({
 
         }
       }
-
-
-
-
-
-
-
       catch (error) {
         setButtonStatus("Couldn't update successfully");
         setCurrentError(error);
         setTimeout(() => setButtonStatus(""), 1000);
       }
-
-
-
-
-
-
-
-
     }
-
-
-
     else {
       // SEPARATE THE TWO KINDS OF VARIABLES
       let secret = variables.filter(
@@ -585,6 +569,7 @@ const EnvGroupVariablesEditor = ({
           text="Update"
           onClick={() => handleUpdateValues()}
           status={buttonStatus}
+          disabled={buttonStatus == "loading"}
           makeFlush={true}
           clearPosition={true}
           statusPosition="right"

+ 24 - 6
internal/registry/registry.go

@@ -866,28 +866,42 @@ func (r *Registry) CreateRepository(
 	conf *config.Config,
 	name string,
 ) error {
+	ctx, span := telemetry.NewSpan(ctx, "create-repository")
+	defer span.End()
+
 	// if aws, create repository
 	if r.AWSIntegrationID != 0 {
+		telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "aws-integration-id", Value: r.AWSIntegrationID})
 		aws, err := conf.Repo.AWSIntegration().ReadAWSIntegration(
 			r.ProjectID,
 			r.AWSIntegrationID,
 		)
 		if err != nil {
-			return err
+			return telemetry.Error(ctx, span, err, "error reading aws integration")
+		}
+		err = r.createECRRepository(aws, name)
+		if err != nil {
+			return telemetry.Error(ctx, span, err, "error creating ecr repository")
 		}
-		return r.createECRRepository(aws, name)
+		return nil
 	} else if r.GCPIntegrationID != 0 && strings.Contains(r.URL, "pkg.dev") {
-		return r.createGARRepository(ctx, conf.Repo, name)
+		telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "gcp-integration-id", Value: r.GCPIntegrationID})
+		err := r.createGARRepository(ctx, conf.Repo, name)
+		if err != nil {
+			return telemetry.Error(ctx, span, err, "error creating gar repository")
+		}
+		return nil
 	}
 
 	project, err := conf.Repo.Project().ReadProject(r.ProjectID)
 	if err != nil {
-		return fmt.Errorf("error getting project for repository: %w", err)
+		return telemetry.Error(ctx, span, err, "error getting project for repository")
 	}
 
 	if project.CapiProvisionerEnabled {
 		// no need to create repository if pushing to ACR
 		if strings.Contains(r.URL, ".azurecr.") {
+			telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "skipping-create-because-azure", Value: true})
 			return nil
 		}
 
@@ -899,9 +913,10 @@ func (r *Registry) CreateRepository(
 			ProjectId:    int64(r.ProjectID),
 			AwsAccountId: accountID,
 		})
+		telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "uri", Value: uri})
 		creds, err := conf.ClusterControlPlaneClient.AssumeRoleCredentials(ctx, req)
 		if err != nil {
-			return fmt.Errorf("error getting capi credentials for repository: %w", err)
+			return telemetry.Error(ctx, span, err, "error getting capi credentials for repository")
 		}
 		aws := &ints.AWSIntegration{
 			AWSAccessKeyID:     []byte(creds.Msg.AwsAccessId),
@@ -909,7 +924,10 @@ func (r *Registry) CreateRepository(
 			AWSSessionToken:    []byte(creds.Msg.AwsSessionToken),
 			AWSRegion:          region,
 		}
-		return r.createECRRepository(aws, name)
+		err = r.createECRRepository(aws, name)
+		if err != nil {
+			return telemetry.Error(ctx, span, err, "error creating ecr repository")
+		}
 	}
 
 	// otherwise, no-op