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

call ccp for repository information on azure

David Townley 2 лет назад
Родитель
Сommit
ca6773a534

+ 7 - 6
api/server/handlers/cluster/install_agent.go

@@ -140,12 +140,13 @@ func (c *InstallAgentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 	}
 
 	conf := &helm.InstallChartConfig{
-		Chart:     chart,
-		Name:      "porter-agent",
-		Namespace: "porter-agent-system",
-		Cluster:   cluster,
-		Repo:      c.Repo(),
-		Values:    porterAgentValues,
+		Chart:                     chart,
+		Name:                      "porter-agent",
+		Namespace:                 "porter-agent-system",
+		Cluster:                   cluster,
+		Repo:                      c.Repo(),
+		Values:                    porterAgentValues,
+		ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 	}
 
 	_, err = helmAgent.InstallChart(context.Background(), conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)

+ 7 - 6
api/server/handlers/cluster/upgrade_agent.go

@@ -58,12 +58,13 @@ func (c *UpgradeAgentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 	// newValues["redis"] =
 
 	_, err = helmAgent.UpgradeReleaseByValues(context.Background(), &helm.UpgradeReleaseConfig{
-		Chart:      chart,
-		Name:       "porter-agent",
-		Values:     newValues,
-		Cluster:    cluster,
-		Repo:       c.Repo(),
-		Registries: []*models.Registry{},
+		Chart:                     chart,
+		Name:                      "porter-agent",
+		Values:                    newValues,
+		Cluster:                   cluster,
+		Repo:                      c.Repo(),
+		Registries:                []*models.Registry{},
+		ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 	}, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
 
 	if err != nil {

+ 6 - 5
api/server/handlers/namespace/create_env_group.go

@@ -179,11 +179,12 @@ func rolloutApplications(
 			}
 
 			conf := &helm.UpgradeReleaseConfig{
-				Name:       releases[index].Name,
-				Cluster:    cluster,
-				Repo:       config.Repo,
-				Registries: registries,
-				Values:     newConfig,
+				Name:                      releases[index].Name,
+				Cluster:                   cluster,
+				Repo:                      config.Repo,
+				Registries:                registries,
+				Values:                    newConfig,
+				ClusterControlPlaneClient: config.ClusterControlPlaneClient,
 			}
 
 			_, err = helmAgent.UpgradeReleaseByValues(context.Background(), conf, config.DOConf, config.ServerConf.DisablePullSecretsInjection, false)

+ 36 - 27
api/server/handlers/porter_app/create.go

@@ -7,6 +7,8 @@ import (
 	"net/http"
 	"strings"
 
+	"github.com/porter-dev/api-contracts/generated/go/porter/v1/porterv1connect"
+
 	"github.com/google/uuid"
 	"github.com/porter-dev/porter/internal/telemetry"
 
@@ -169,6 +171,7 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 				registries,
 				cluster,
 				c.Repo(),
+				c.Config().ClusterControlPlaneClient,
 			)
 			if err != nil {
 				err = telemetry.Error(ctx, span, err, "error making config for pre-deploy job chart")
@@ -190,13 +193,14 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		}
 
 		conf := &helm.InstallChartConfig{
-			Chart:      chart,
-			Name:       stackName,
-			Namespace:  namespace,
-			Values:     values,
-			Cluster:    cluster,
-			Repo:       c.Repo(),
-			Registries: registries,
+			Chart:                     chart,
+			Name:                      stackName,
+			Namespace:                 namespace,
+			Values:                    values,
+			Cluster:                   cluster,
+			Repo:                      c.Repo(),
+			Registries:                registries,
+			ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 		}
 
 		// create the app chart
@@ -289,6 +293,7 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 						registries,
 						cluster,
 						c.Repo(),
+						c.Config().ClusterControlPlaneClient,
 					)
 					if err != nil {
 						err = telemetry.Error(ctx, span, err, "error making config for pre-deploy job chart")
@@ -318,12 +323,13 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 					}
 
 					conf := &helm.UpgradeReleaseConfig{
-						Name:       helmRelease.Name,
-						Cluster:    cluster,
-						Repo:       c.Repo(),
-						Registries: registries,
-						Values:     releaseJobValues,
-						Chart:      chart,
+						Name:                      helmRelease.Name,
+						Cluster:                   cluster,
+						Repo:                      c.Repo(),
+						Registries:                registries,
+						Values:                    releaseJobValues,
+						Chart:                     chart,
+						ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 					}
 					_, err = helmAgent.UpgradeReleaseByValues(ctx, conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)
 					if err != nil {
@@ -337,13 +343,14 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 
 		// update the app chart
 		conf := &helm.InstallChartConfig{
-			Chart:      chart,
-			Name:       stackName,
-			Namespace:  namespace,
-			Values:     values,
-			Cluster:    cluster,
-			Repo:       c.Repo(),
-			Registries: registries,
+			Chart:                     chart,
+			Name:                      stackName,
+			Namespace:                 namespace,
+			Values:                    values,
+			Cluster:                   cluster,
+			Repo:                      c.Repo(),
+			Registries:                registries,
+			ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 		}
 
 		// update the chart
@@ -463,6 +470,7 @@ func createReleaseJobChart(
 	registries []*models.Registry,
 	cluster *models.Cluster,
 	repo repository.Repository,
+	ccpClient porterv1connect.ClusterControlPlaneServiceClient,
 ) (*helm.InstallChartConfig, error) {
 	chart, err := loader.LoadChartPublic(ctx, repoUrl, "job", "")
 	if err != nil {
@@ -473,12 +481,13 @@ func createReleaseJobChart(
 	namespace := fmt.Sprintf("porter-stack-%s", stackName)
 
 	return &helm.InstallChartConfig{
-		Chart:      chart,
-		Name:       releaseName,
-		Namespace:  namespace,
-		Values:     values,
-		Cluster:    cluster,
-		Repo:       repo,
-		Registries: registries,
+		Chart:                     chart,
+		Name:                      releaseName,
+		Namespace:                 namespace,
+		Values:                    values,
+		Cluster:                   cluster,
+		Repo:                      repo,
+		Registries:                registries,
+		ClusterControlPlaneClient: ccpClient,
 	}, nil
 }

+ 22 - 6
api/server/handlers/project_integration/create_azure.go

@@ -3,6 +3,8 @@ package project_integration
 import (
 	"net/http"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	"github.com/bufbuild/connect-go"
 
 	porterv1 "github.com/porter-dev/api-contracts/generated/go/porter/v1"
@@ -31,12 +33,17 @@ func NewCreateAzureHandler(
 }
 
 func (p *CreateAzureHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	user, _ := r.Context().Value(types.UserScope).(*models.User)
-	project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-create-azure-connection")
+	defer span.End()
+
+	user, _ := ctx.Value(types.UserScope).(*models.User)
+	project, _ := ctx.Value(types.ProjectScope).(*models.Project)
 
 	request := &types.CreateAzureRequest{}
 
 	if ok := p.DecodeAndValidate(w, r, request); !ok {
+		err := telemetry.Error(ctx, span, nil, "error decoding and validating request")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
@@ -44,7 +51,8 @@ func (p *CreateAzureHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 	az, err := p.Repo().AzureIntegration().CreateAzureIntegration(az)
 	if err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err := telemetry.Error(ctx, span, err, "error creating azure integration")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
@@ -59,13 +67,21 @@ func (p *CreateAzureHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		TenantId:               request.AzureTenantID,
 		ServicePrincipalSecret: []byte(request.ServicePrincipalKey),
 	})
-	_, err = p.Config().ClusterControlPlaneClient.SaveAzureCredentials(r.Context(), req)
-
+	resp, err := p.Config().ClusterControlPlaneClient.SaveAzureCredentials(r.Context(), req)
 	if err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err := telemetry.Error(ctx, span, err, "error saving azure credentials")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
+	if resp.Msg == nil || resp.Msg.CredentialsIdentifier == "" {
+		err := telemetry.Error(ctx, span, err, "no cloud credential identifier returned")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+		return
+	}
+
+	res.CloudProviderCredentialIdentifier = resp.Msg.CredentialsIdentifier
+
 	p.WriteResult(w, r, res)
 }
 

+ 58 - 16
api/server/handlers/registry/get_token.go

@@ -7,6 +7,9 @@ import (
 	"strings"
 	"time"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
+	"github.com/aws/aws-sdk-go/aws/arn"
 	"github.com/aws/aws-sdk-go/service/ecr"
 	"github.com/bufbuild/connect-go"
 	porterv1 "github.com/porter-dev/api-contracts/generated/go/porter/v1"
@@ -18,9 +21,6 @@ import (
 	"github.com/porter-dev/porter/internal/models"
 	"github.com/porter-dev/porter/internal/oauth"
 	"github.com/porter-dev/porter/internal/registry"
-	"github.com/porter-dev/porter/internal/telemetry"
-
-	"github.com/aws/aws-sdk-go/aws/arn"
 )
 
 type RegistryGetECRTokenHandler struct {
@@ -402,12 +402,18 @@ func NewRegistryGetACRTokenHandler(
 }
 
 func (c *RegistryGetACRTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-acr-token")
+	defer span.End()
+
+	proj, _ := ctx.Value(types.ProjectScope).(*models.Project)
+
+	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "project-id", Value: proj.ID})
 
 	// list registries and find one that matches the region
 	regs, err := c.Repo().Registry().ListRegistriesByProjectID(proj.ID)
 	if err != nil {
-		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err := telemetry.Error(ctx, span, err, "error getting registries by project id")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
@@ -415,22 +421,58 @@ func (c *RegistryGetACRTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Re
 	var expiresAt *time.Time
 
 	for _, reg := range regs {
-		if reg.AzureIntegrationID != 0 && strings.Contains(reg.URL, "azurecr.io") {
-			_reg := registry.Registry(*reg)
-			username, pw, err := _reg.GetACRCredentials(c.Repo())
-			if err != nil {
-				c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-				continue
-			}
+		if strings.Contains(reg.URL, "azurecr.io") {
+			telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "registry-name", Value: reg.Name})
 
-			token = base64.StdEncoding.EncodeToString([]byte(string(username) + ":" + string(pw)))
+			if proj.CapiProvisionerEnabled {
+				telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "capi-provisioned", Value: true})
 
-			// we'll just set an arbitrary 30-day expiry time (this is not enforced)
-			timeExpires := time.Now().Add(30 * 24 * 3600 * time.Second)
-			expiresAt = &timeExpires
+				tokenReq := connect.NewRequest(&porterv1.TokenForRegistryRequest{
+					ProjectId:   int64(proj.ID),
+					RegistryUri: reg.URL,
+				})
+				tokenResp, err := c.Config().ClusterControlPlaneClient.TokenForRegistry(ctx, tokenReq)
+				if err != nil {
+					err := telemetry.Error(ctx, span, err, "error getting token response from ccp")
+					c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+					return
+				}
+
+				if tokenResp.Msg == nil || tokenResp.Msg.Token == "" {
+					err := telemetry.Error(ctx, span, err, "no token found in response")
+					c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+					return
+				}
+
+				token = tokenResp.Msg.Token
+
+				// we'll just set an arbitrary 30-day expiry time (this is not enforced)
+				timeExpires := time.Now().Add(30 * 24 * 3600 * time.Second)
+				expiresAt = &timeExpires
+			} else if reg.AzureIntegrationID != 0 {
+				telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "capi-provisioned", Value: false})
+
+				_reg := registry.Registry(*reg)
+				username, pw, err := _reg.GetACRCredentials(c.Repo())
+				if err != nil {
+					c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+					continue
+				}
+
+				token = base64.StdEncoding.EncodeToString([]byte(string(username) + ":" + string(pw)))
+				// we'll just set an arbitrary 30-day expiry time (this is not enforced)
+				timeExpires := time.Now().Add(30 * 24 * 3600 * time.Second)
+				expiresAt = &timeExpires
+			}
 		}
 	}
 
+	if token == "" {
+		err := telemetry.Error(ctx, span, nil, "missing token")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+		return
+	}
+
 	resp := &types.GetRegistryTokenResponse{
 		Token:     token,
 		ExpiresAt: expiresAt,

+ 8 - 7
api/server/handlers/release/create.go

@@ -142,13 +142,14 @@ func (c *CreateReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 	}
 
 	conf := &helm.InstallChartConfig{
-		Chart:      chart,
-		Name:       request.Name,
-		Namespace:  namespace,
-		Values:     request.Values,
-		Cluster:    cluster,
-		Repo:       c.Repo(),
-		Registries: registries,
+		Chart:                     chart,
+		Name:                      request.Name,
+		Namespace:                 namespace,
+		Values:                    request.Values,
+		Cluster:                   cluster,
+		Repo:                      c.Repo(),
+		Registries:                registries,
+		ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 	}
 
 	helmRelease, err := helmAgent.InstallChart(ctx, conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)

+ 8 - 7
api/server/handlers/release/create_addon.go

@@ -83,13 +83,14 @@ func (c *CreateAddonHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	}
 
 	conf := &helm.InstallChartConfig{
-		Chart:      chart,
-		Name:       request.Name,
-		Namespace:  namespace,
-		Values:     request.Values,
-		Cluster:    cluster,
-		Repo:       c.Repo(),
-		Registries: registries,
+		Chart:                     chart,
+		Name:                      request.Name,
+		Namespace:                 namespace,
+		Values:                    request.Values,
+		Cluster:                   cluster,
+		Repo:                      c.Repo(),
+		Registries:                registries,
+		ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 	}
 
 	helmRelease, err := helmAgent.InstallChart(context.Background(), conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection)

+ 6 - 5
api/server/handlers/release/update_image_batch.go

@@ -98,11 +98,12 @@ func (c *UpdateImageBatchHandler) ServeHTTP(w http.ResponseWriter, r *http.Reque
 				rel.Config["paused"] = true
 
 				conf := &helm.UpgradeReleaseConfig{
-					Name:       releases[index].Name,
-					Cluster:    cluster,
-					Repo:       c.Repo(),
-					Registries: registries,
-					Values:     rel.Config,
+					Name:                      releases[index].Name,
+					Cluster:                   cluster,
+					Repo:                      c.Repo(),
+					Registries:                registries,
+					Values:                    rel.Config,
+					ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 				}
 
 				_, err = helmAgent.UpgradeReleaseByValues(context.Background(), conf, c.Config().DOConf, c.Config().ServerConf.DisablePullSecretsInjection, false)

+ 17 - 9
api/server/handlers/release/upgrade.go

@@ -6,6 +6,8 @@ import (
 	"net/http"
 	"net/url"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	semver "github.com/Masterminds/semver/v3"
 
 	"github.com/porter-dev/porter/api/server/authz"
@@ -41,12 +43,16 @@ func NewUpgradeReleaseHandler(
 }
 
 func (c *UpgradeReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	user, _ := r.Context().Value(types.UserScope).(*models.User)
-	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
-	helmRelease, _ := r.Context().Value(types.ReleaseScope).(*release.Release)
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-upgrade-release")
+	defer span.End()
+
+	user, _ := ctx.Value(types.UserScope).(*models.User)
+	cluster, _ := ctx.Value(types.ClusterScope).(*models.Cluster)
+	helmRelease, _ := ctx.Value(types.ReleaseScope).(*release.Release)
 
-	helmAgent, err := c.GetHelmAgent(r.Context(), r, cluster, "")
+	helmAgent, err := c.GetHelmAgent(ctx, r, cluster, "")
 	if err != nil {
+		err := telemetry.Error(ctx, span, err, "error getting helm agent")
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
 	}
@@ -59,15 +65,17 @@ func (c *UpgradeReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 
 	registries, err := c.Repo().Registry().ListRegistriesByProjectID(cluster.ProjectID)
 	if err != nil {
+		err := telemetry.Error(ctx, span, err, "error listing registries")
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
 	}
 
 	conf := &helm.UpgradeReleaseConfig{
-		Name:       helmRelease.Name,
-		Cluster:    cluster,
-		Repo:       c.Repo(),
-		Registries: registries,
+		Name:                      helmRelease.Name,
+		Cluster:                   cluster,
+		Repo:                      c.Repo(),
+		Registries:                registries,
+		ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 	}
 
 	// if the chart version is set, load a chart from the repo
@@ -234,7 +242,7 @@ func (c *UpgradeReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 
 			if gitAction != nil && gitAction.ID != 0 && gitAction.GitlabIntegrationID == 0 {
 				gaRunner, err := GetGARunner(
-					r.Context(),
+					ctx,
 					c.Config(),
 					user.ID,
 					cluster.ProjectID,

+ 6 - 5
api/server/handlers/release/upgrade_webhook.go

@@ -144,11 +144,12 @@ func (c *WebhookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	}
 
 	conf := &helm.UpgradeReleaseConfig{
-		Name:       release.Name,
-		Cluster:    cluster,
-		Repo:       c.Repo(),
-		Registries: registries,
-		Values:     rel.Config,
+		Name:                      release.Name,
+		Cluster:                   cluster,
+		Repo:                      c.Repo(),
+		Registries:                registries,
+		Values:                    rel.Config,
+		ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 	}
 
 	slackInts, _ := c.Repo().SlackIntegration().ListSlackIntegrationsByProjectID(release.ProjectID)

+ 14 - 12
api/server/handlers/stack/helpers.go

@@ -36,13 +36,14 @@ func applyAppResource(opts *applyAppResourceOpts) (*release.Release, error) {
 	}
 
 	conf := &helm.InstallChartConfig{
-		Chart:      chart,
-		Name:       opts.request.Name,
-		Namespace:  opts.namespace,
-		Values:     opts.request.Values,
-		Cluster:    opts.cluster,
-		Repo:       opts.config.Repo,
-		Registries: opts.registries,
+		Chart:                     chart,
+		Name:                      opts.request.Name,
+		Namespace:                 opts.namespace,
+		Values:                    opts.request.Values,
+		Cluster:                   opts.cluster,
+		Repo:                      opts.config.Repo,
+		Registries:                opts.registries,
+		ClusterControlPlaneClient: opts.config.ClusterControlPlaneClient,
 	}
 
 	if conf.Values == nil {
@@ -95,11 +96,12 @@ func updateAppResourceTag(opts *updateAppResourceTagOpts) error {
 	rel.Config["image"] = image
 
 	conf := &helm.UpgradeReleaseConfig{
-		Name:       opts.name,
-		Cluster:    opts.cluster,
-		Repo:       opts.config.Repo,
-		Registries: opts.registries,
-		Values:     rel.Config,
+		Name:                      opts.name,
+		Cluster:                   opts.cluster,
+		Repo:                      opts.config.Repo,
+		Registries:                opts.registries,
+		Values:                    rel.Config,
+		ClusterControlPlaneClient: opts.config.ClusterControlPlaneClient,
 
 		// stack related info
 		StackName:     opts.stackName,

+ 6 - 5
api/server/handlers/v1/env_group/create.go

@@ -195,11 +195,12 @@ func rolloutApplications(
 			}
 
 			conf := &helm.UpgradeReleaseConfig{
-				Name:       releases[index].Name,
-				Cluster:    cluster,
-				Repo:       config.Repo,
-				Registries: registries,
-				Values:     newConfig,
+				Name:                      releases[index].Name,
+				Cluster:                   cluster,
+				Repo:                      config.Repo,
+				Registries:                registries,
+				Values:                    newConfig,
+				ClusterControlPlaneClient: config.ClusterControlPlaneClient,
 			}
 
 			_, err = helmAgent.UpgradeReleaseByValues(context.Background(), conf, config.DOConf, config.ServerConf.DisablePullSecretsInjection, false)

+ 5 - 4
api/server/handlers/v1/release/upgrade.go

@@ -64,10 +64,11 @@ func (c *UpgradeReleaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 	}
 
 	conf := &helm.UpgradeReleaseConfig{
-		Name:       helmRelease.Name,
-		Cluster:    cluster,
-		Repo:       c.Repo(),
-		Registries: registries,
+		Name:                      helmRelease.Name,
+		Cluster:                   cluster,
+		Repo:                      c.Repo(),
+		Registries:                registries,
+		ClusterControlPlaneClient: c.Config().ClusterControlPlaneClient,
 	}
 
 	// if the chart version is set, load a chart from the repo

+ 1 - 0
api/types/project_integration.go

@@ -170,6 +170,7 @@ type CreateAzureRequest struct {
 
 type CreateAzureResponse struct {
 	*AzureIntegration
+	CloudProviderCredentialIdentifier string `json:"cloud_provider_credentials_id"`
 }
 
 type ListAzureResponse []*AzureIntegration

+ 1 - 1
dashboard/src/components/AzureCredentialForm.tsx

@@ -52,7 +52,7 @@ const AzureCredentialForm: React.FC<Props> = ({ goBack, proceed }) => {
       )
       .then(({ data }) => {
         setIsLoading(false);
-        proceed(data.id);
+        proceed(data.cloud_provider_credentials_id);
       })
       .catch((err) => {
         console.error(err);

+ 1 - 1
dashboard/src/components/AzureProvisionerSettings.tsx

@@ -113,7 +113,7 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
         projectId: currentProject.id,
         kind: EnumKubernetesKind.AKS,
         cloudProvider: EnumCloudProvider.AZURE,
-        cloudProviderCredentialsId: "",
+        cloudProviderCredentialsId: props.credentialId,
         kindValues: {
           case: "aksKind",
           value: new AKS({

+ 9 - 11
dashboard/src/components/ProvisionerFlow.tsx

@@ -17,7 +17,7 @@ const providers = ["aws", "gcp", "azure"];
 
 type Props = {};
 
-const ProvisionerFlow: React.FC<Props> = ({ }) => {
+const ProvisionerFlow: React.FC<Props> = ({}) => {
   const {
     usage,
     hasBillingEnabled,
@@ -40,11 +40,7 @@ const ProvisionerFlow: React.FC<Props> = ({ }) => {
 
   const markStepCostConsent = async (step: string, provider: string) => {
     try {
-      await api.updateOnboardingStep(
-        "<token>",
-        { step, provider },
-        {}
-      );
+      await api.updateOnboardingStep("<token>", { step, provider }, {});
     } catch (err) {
       console.log(err);
     }
@@ -80,7 +76,7 @@ const ProvisionerFlow: React.FC<Props> = ({ }) => {
                         provider === "gcp"
                       )
                     ) {
-                      openCostConsentModal(provider)
+                      openCostConsentModal(provider);
                     }
                   }}
                 >
@@ -101,7 +97,7 @@ const ProvisionerFlow: React.FC<Props> = ({ }) => {
               setShowCostConfirmModal={setShowCostConfirmModal}
               markCostConsentComplete={() => {
                 try {
-                  markStepCostConsent("cost-consent-complete", "aws")
+                  markStepCostConsent("cost-consent-complete", "aws");
                 } catch (err) {
                   console.log(err);
                 }
@@ -126,7 +122,7 @@ const ProvisionerFlow: React.FC<Props> = ({ }) => {
                 setShowCostConfirmModal={setShowCostConfirmModal}
                 markCostConsentComplete={() => {
                   try {
-                    markStepCostConsent("cost-consent-complete", "azure")
+                    markStepCostConsent("cost-consent-complete", "azure");
                   } catch (err) {
                     console.log(err);
                   }
@@ -141,7 +137,8 @@ const ProvisionerFlow: React.FC<Props> = ({ }) => {
                       console.log(err);
                     }
                   }
-                }} />
+                }}
+              />
             )))}
       </>
     );
@@ -169,7 +166,8 @@ const ProvisionerFlow: React.FC<Props> = ({ }) => {
       (selectedProvider === "azure" && (
         <AzureCredentialForm
           goBack={() => setCurrentStep("cloud")}
-          proceed={() => {
+          proceed={(id) => {
+            setCredentialId(id);
             setCurrentStep("cluster");
           }}
         />

+ 2 - 0
go.mod

@@ -2,6 +2,8 @@ module github.com/porter-dev/porter
 
 go 1.20
 
+replace github.com/porter-dev/api-contracts v0.0.63 => ../api-contracts
+
 require (
 	cloud.google.com/go v0.105.0 // indirect
 	github.com/AlecAivazis/survey/v2 v2.2.9

+ 301 - 0
go.work.sum

@@ -136,19 +136,320 @@ github.com/nats-io/nats.go v1.9.1 h1:ik3HbLhZ0YABLto7iX80pZLPw/6dx3T+++MZJwLnMrQ
 github.com/nats-io/nkeys v0.1.0 h1:qMd4+pRHgdr1nAClu+2h/2a5F2TmKcCzjCDazVgRoX4=
 github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
 github.com/porter-dev/api-contracts v0.0.63/go.mod h1:qr2L58mJLr5DUGV5OPw3REiSrQvJq6TgkKyEWP95dyU=
+github.com/porter-dev/api-contracts v0.0.66 h1:sqK6Xu6QtC6cvhXoI1NbsdaruQK23yw07llbn14CWbc=
+github.com/porter-dev/api-contracts v0.0.66/go.mod h1:qr2L58mJLr5DUGV5OPw3REiSrQvJq6TgkKyEWP95dyU=
+github.com/porter-dev/switchboard v0.0.0-20221019155755-67ff2bf04935/go.mod h1:xSPzqSFMQ6OSbp42fhCi4AbGbQbsm6nRvOkrblFeXU4=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
+github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
+github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
+github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
+github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/riandyrn/otelchi v0.5.1/go.mod h1:ZxVxNEl+jQ9uHseRYIxKWRb3OY8YXFEu+EkNiiSNUEA=
+github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8/go.mod h1:WIfMkQNY+oq/mWwtsjOYHIZBuwthioY2srOmljJkTnk=
+github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
+github.com/rs/zerolog v1.26.0 h1:ORM4ibhEZeTeQlCojCK2kPz1ogAY4bGs4tD+SaAdGaE=
+github.com/rs/zerolog v1.26.0/go.mod h1:yBiM87lvSqX8h0Ww4sdzNSkVYZ8dL2xjZJG1lAuGZEo=
+github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
+github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
+github.com/santhosh-tekuri/jsonschema/v5 v5.0.1/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
+github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
+github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
+github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
+github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
+github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3 h1:ZuhckGJ10ulaKkdvJtiAqsLTiPrLaXSdnVgXJKJkTxE=
+github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3/go.mod h1:9/Rh6yILuLysoQnZ2oNooD2g7aBnvM7r/fNVxRNWfBc=
+github.com/sendgrid/rest v2.6.3+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE=
+github.com/sendgrid/sendgrid-go v3.8.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
+github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
+github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/sethvargo/go-envconfig v0.8.2 h1:DDUVuG21RMgeB/bn4leclUI/837y6cQCD4w8hb5797k=
+github.com/sethvargo/go-envconfig v0.8.2/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0=
+github.com/shirou/gopsutil/v3 v3.22.12 h1:oG0ns6poeUSxf78JtOsfygNWuEHYYz8hnnNg7P04TJs=
+github.com/shirou/gopsutil/v3 v3.22.12/go.mod h1:Xd7P1kwZcp5VW52+9XsirIKd/BROzbb2wdX3Kqlz9uI=
+github.com/shurcooL/githubv4 v0.0.0-20200928013246-d292edc3691b/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
+github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg=
+github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
+github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
+github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
+github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
 github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
+github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
+github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
+github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
+github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
+github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
+github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
+github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
 github.com/tchap/go-patricia v2.2.6+incompatible h1:JvoDL7JSoIP2HDE8AbDH3zC8QBPxmzYe32HHy5yQ+Ck=
+github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
+github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
+github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
+github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk=
+github.com/tj/go-buffer v1.1.0/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj52Uc=
+github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
+github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
+github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
+github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
+github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
+github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
+github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
+github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
+github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
+github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
+github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
+github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
+github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
+github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
+github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
+github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
+github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
+github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
+github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
+github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
+github.com/xanzy/go-gitlab v0.68.0/go.mod h1:o4yExCtdaqlM8YGdDJWuZoBmfxBsmA9TPEjs9mx1UO4=
+github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
+github.com/xanzy/ssh-agent v0.3.1/go.mod h1:QIE4lCeL7nkC25x+yA3LBIYfwCc1TFziCtG7cBAac6w=
+github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
+github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g=
+github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
+github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
+github.com/yashtewari/glob-intersection v0.1.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok=
+github.com/yuin/goldmark v1.3.3/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ=
+github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
+github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
+github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
+go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
+go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
+go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
+go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
+go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
 go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0=
+go.opentelemetry.io/contrib v1.0.0 h1:khwDCxdSspjOLmFnvMuSHd/5rPzbTx0+l6aURwtQdfE=
+go.opentelemetry.io/contrib v1.0.0/go.mod h1:EH4yDYeNoaTqn/8yCWQmfNB78VHfGX2Jt2bvnvzBlGM=
+go.opentelemetry.io/contrib/instrumentation/host v0.38.0 h1:UAL4VwsGD8I87v0PUnlNvNoDK9biur6BavY6hZyHRtE=
+go.opentelemetry.io/contrib/instrumentation/host v0.38.0/go.mod h1:tVaeBxRJPU0PrChJnlb4kWolV8jgzNLonwFoa1j8JAM=
+go.opentelemetry.io/contrib/instrumentation/runtime v0.38.0 h1:uTd4XAyfZ51V5w+ZOCFPiNgzVN2Yp3ibNYKvZ7hWViM=
+go.opentelemetry.io/contrib/instrumentation/runtime v0.38.0/go.mod h1:LYI0Tb+eGfyp/IRpjSSERc3rv/3FT/IjqUeNNTZdJRQ=
+go.opentelemetry.io/contrib/propagators/b3 v1.13.0 h1:f17PBmZK60RoHvOpJVqEka8oS2EXjpjHquESD/8zZ50=
+go.opentelemetry.io/contrib/propagators/b3 v1.13.0/go.mod h1:zy2hz1TpGUoJzSwlBchVGvVAFQS8s2pglKLbrAFZ+Sc=
+go.opentelemetry.io/contrib/propagators/ot v1.13.0 h1:tHWNd0WRS6w9keZoZg9aF3zYohdaBacQfojPYZJgATQ=
+go.opentelemetry.io/contrib/propagators/ot v1.13.0/go.mod h1:R6Op9T6LxNaMRVlGD0wVwz40LSsAq296CXiEydKLQBU=
+go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
+go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
+go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
 go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg=
+go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.12.0 h1:UfDENi+LTcLjQ/JhaXimjlIgn7wWjwbEMmdREm2Gyng=
+go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.12.0/go.mod h1:rqbht/LlhVBgn5+k3M5QK96K5Xb0DvXpMJ5SFQpY6uw=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.35.0 h1:KPV7w2qbszG6XnudnWDffM4CI+KjCYajryGrhoReBR4=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.35.0/go.mod h1:HKkSo2BOMO2CUdoIUuc/e4aLeMbeZaj+gNgjBj/Qdzk=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.35.0 h1:QgnDVvLLDiLloTGHyP8wIyWtDXMx/ZHg9qNQaofry2s=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.35.0/go.mod h1:BTWTNRCV2jdeEaKP+QJWD9g86QnFzxhZfsQZ1w7cSx4=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.35.0 h1:uuJLi6mxvO5Vbynnw1fecMn/npqMQREEANf3vuwZwho=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.35.0/go.mod h1:RC2duYQUmta07UZKXeqL5yehj4CdDkyhcMLf3fYnMek=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.12.0 h1:ZVqtSAxrR4+ofzayuww0/EKamCjjnwnXTMRZzMudJoU=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.12.0/go.mod h1:IlaGLENJkAl9+Xoo3J0unkdOwtL+rmqZ3ryMjUtYA94=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.12.0 h1:+tsVdWosoqDfX6cdHAeacZozjQS94ySBd+aUXFwnNKA=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.12.0/go.mod h1:jSqjV+Knu1Jyvh+l3fx7V210Ev3HHgNQAi8YqpXaQP8=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.12.0 h1:L23MzcHDznr05xOM1Ng1F98L0nVd7hm/S7y2jW9IRB4=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.12.0/go.mod h1:C+onYX2j5QH653b3wGJwowYr8jLMjBJw35QcaCQQK0U=
+go.opentelemetry.io/otel/metric v0.35.0 h1:aPT5jk/w7F9zW51L7WgRqNKDElBdyRLGuBtI5MX34e8=
+go.opentelemetry.io/otel/metric v0.35.0/go.mod h1:qAcbhaTRFU6uG8QM7dDo7XvFsWcugziq/5YI065TokQ=
+go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs=
+go.opentelemetry.io/otel/sdk v1.13.0 h1:BHib5g8MvdqS65yo2vV1s6Le42Hm6rrw08qU6yz5JaM=
+go.opentelemetry.io/otel/sdk v1.13.0/go.mod h1:YLKPx5+6Vx/o1TCUYYs+bpymtkmazOMT6zoRrC7AQ7I=
+go.opentelemetry.io/otel/sdk/metric v0.35.0 h1:gryV4W5GzpOhKK48/lZb8ldyWIs3DRugSVlQZmCwELA=
+go.opentelemetry.io/otel/sdk/metric v0.35.0/go.mod h1:eDyp1GxSiwV98kr7w4pzrszQh/eze9MqBqPd2bCPmyE=
+go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
+go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
+go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
+go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw=
+go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
+go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
+go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
+go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
+go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
+go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
+go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
+golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
 golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
 golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
+golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
+golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210319071255-635bc2c9138d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
+golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
+golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
+google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0=
+google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
+google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
+google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
 google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
+google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
+google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk=
+google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
 google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
+gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
+gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
+gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
+gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
+gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
+gopkg.in/segmentio/analytics-go.v3 v3.1.0 h1:UzxH1uaGZRpMKDhJyBz0pexz6yUoBU3x8bJsRk/HV6U=
+gopkg.in/segmentio/analytics-go.v3 v3.1.0/go.mod h1:4QqqlTlSSpVlWA9/9nDcPw+FkM2yv1NQoYjUbL9/JAw=
+gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
+gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
+gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
+gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
+istio.io/api v0.0.0-20221109202042-b9e5d446a83d/go.mod h1:hQkF0Q19MCmfOTre/Sg4KvrwwETq45oaFplnBm2p4j8=
+istio.io/client-go v1.16.0/go.mod h1:UV8SFeM2qNime5sobkr2m8oTCPxxVt9xCY4ol50U9YQ=
+k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
+k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
+k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
+k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
+k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
+k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
+k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
+k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
+k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
+k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
+k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
+k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
+k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0=
+k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
+k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
+k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
+k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
+k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
+k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
+k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
+k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
+k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
+k8s.io/helm v2.17.0+incompatible h1:Bpn6o1wKLYqKM3+Osh8e+1/K2g/GsQJ4F4yNF2+deao=
+k8s.io/helm v2.17.0+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI=
+k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
+k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
+k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
+k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
+k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
+sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
+sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=

+ 19 - 12
internal/helm/agent.go

@@ -9,6 +9,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/porter-dev/api-contracts/generated/go/porter/v1/porterv1connect"
+
 	"github.com/porter-dev/porter/internal/telemetry"
 
 	"github.com/pkg/errors"
@@ -196,11 +198,12 @@ func (a *Agent) GetReleaseHistory(
 }
 
 type UpgradeReleaseConfig struct {
-	Name       string
-	Values     map[string]interface{}
-	Cluster    *models.Cluster
-	Repo       repository.Repository
-	Registries []*models.Registry
+	Name                      string
+	Values                    map[string]interface{}
+	Cluster                   *models.Cluster
+	Repo                      repository.Repository
+	Registries                []*models.Registry
+	ClusterControlPlaneClient porterv1connect.ClusterControlPlaneServiceClient
 
 	// Optional, if chart should be overriden
 	Chart *chart.Chart
@@ -282,6 +285,7 @@ func (a *Agent) UpgradeReleaseByValues(
 		conf.Registries,
 		doAuth,
 		disablePullSecretsInjection,
+		conf.ClusterControlPlaneClient,
 	)
 
 	if err != nil {
@@ -425,13 +429,14 @@ func (a *Agent) UpgradeReleaseByValues(
 
 // InstallChartConfig is the config required to install a chart
 type InstallChartConfig struct {
-	Chart      *chart.Chart
-	Name       string
-	Namespace  string
-	Values     map[string]interface{}
-	Cluster    *models.Cluster
-	Repo       repository.Repository
-	Registries []*models.Registry
+	Chart                     *chart.Chart
+	Name                      string
+	Namespace                 string
+	Values                    map[string]interface{}
+	Cluster                   *models.Cluster
+	Repo                      repository.Repository
+	Registries                []*models.Registry
+	ClusterControlPlaneClient porterv1connect.ClusterControlPlaneServiceClient
 }
 
 // InstallChartFromValuesBytes reads the raw values and calls Agent.InstallChart
@@ -509,6 +514,7 @@ func (a *Agent) InstallChart(
 		conf.Registries,
 		doAuth,
 		disablePullSecretsInjection,
+		conf.ClusterControlPlaneClient,
 	)
 
 	if err != nil {
@@ -576,6 +582,7 @@ func (a *Agent) UpgradeInstallChart(
 		conf.Registries,
 		doAuth,
 		disablePullSecretsInjection,
+		conf.ClusterControlPlaneClient,
 	)
 
 	if err != nil {

+ 9 - 2
internal/helm/postrenderer.go

@@ -9,6 +9,8 @@ import (
 	"sort"
 	"strings"
 
+	"github.com/porter-dev/api-contracts/generated/go/porter/v1/porterv1connect"
+
 	"github.com/aws/aws-sdk-go/aws/arn"
 	"github.com/porter-dev/porter/internal/kubernetes"
 	"github.com/porter-dev/porter/internal/models"
@@ -23,6 +25,7 @@ import (
 type PorterPostrenderer struct {
 	DockerSecretsPostRenderer       *DockerSecretsPostRenderer
 	EnvironmentVariablePostrenderer *EnvironmentVariablePostrenderer
+	ClusterControlPlaneClient       porterv1connect.ClusterControlPlaneServiceClient
 }
 
 func NewPorterPostrenderer(
@@ -33,6 +36,7 @@ func NewPorterPostrenderer(
 	regs []*models.Registry,
 	doAuth *oauth2.Config,
 	disablePullSecretsInjection bool,
+	ccpClient porterv1connect.ClusterControlPlaneServiceClient,
 ) (postrender.PostRenderer, error) {
 	var dockerSecretsPostrenderer *DockerSecretsPostRenderer
 	var err error
@@ -53,6 +57,7 @@ func NewPorterPostrenderer(
 	return &PorterPostrenderer{
 		DockerSecretsPostRenderer:       dockerSecretsPostrenderer,
 		EnvironmentVariablePostrenderer: envVarPostrenderer,
+		ClusterControlPlaneClient:       ccpClient,
 	}, nil
 }
 
@@ -60,7 +65,7 @@ func (p *PorterPostrenderer) Run(
 	renderedManifests *bytes.Buffer,
 ) (modifiedManifests *bytes.Buffer, err error) {
 	if p.DockerSecretsPostRenderer != nil {
-		renderedManifests, err = p.DockerSecretsPostRenderer.Run(renderedManifests)
+		renderedManifests, err = p.DockerSecretsPostRenderer.Run(renderedManifests, p.ClusterControlPlaneClient)
 
 		if err != nil {
 			return nil, err
@@ -142,6 +147,7 @@ func NewDockerSecretsPostRenderer(
 
 func (d *DockerSecretsPostRenderer) Run(
 	renderedManifests *bytes.Buffer,
+	ccpClient porterv1connect.ClusterControlPlaneServiceClient,
 ) (modifiedManifests *bytes.Buffer, err error) {
 	bufCopy := bytes.NewBuffer(renderedManifests.Bytes())
 
@@ -205,7 +211,7 @@ func (d *DockerSecretsPostRenderer) Run(
 					resources:  make([]resource, 0),
 				}
 
-				newData, err := dCopy.Run(bytes.NewBufferString(manifestDataStr))
+				newData, err := dCopy.Run(bytes.NewBufferString(manifestDataStr), ccpClient)
 				if err != nil {
 					continue
 				}
@@ -223,6 +229,7 @@ func (d *DockerSecretsPostRenderer) Run(
 		d.Namespace,
 		linkedRegs,
 		d.DOAuth,
+		ccpClient,
 	)
 	if err != nil {
 		return renderedManifests, nil

+ 4 - 1
internal/kubernetes/agent.go

@@ -15,6 +15,8 @@ import (
 	"sync"
 	"time"
 
+	"github.com/porter-dev/api-contracts/generated/go/porter/v1/porterv1connect"
+
 	goerrors "errors"
 
 	"github.com/porter-dev/porter/api/server/shared/websocket"
@@ -1908,13 +1910,14 @@ func (a *Agent) CreateImagePullSecrets(
 	namespace string,
 	linkedRegs map[string]*models.Registry,
 	doAuth *oauth2.Config,
+	ccpClient porterv1connect.ClusterControlPlaneServiceClient,
 ) (map[string]string, error) {
 	res := make(map[string]string)
 
 	for key, val := range linkedRegs {
 		_reg := registry.Registry(*val)
 
-		data, err := _reg.GetDockerConfigJSON(repo, doAuth)
+		data, err := _reg.GetDockerConfigJSON(repo, doAuth, ccpClient)
 		if err != nil {
 			return nil, err
 		}

+ 1 - 1
internal/models/registry.go

@@ -52,7 +52,7 @@ func (r *Registry) ToRegistryType() *types.Registry {
 		}
 	} else if r.DOIntegrationID != 0 {
 		serv = types.DOCR
-	} else if r.AzureIntegrationID != 0 {
+	} else if r.AzureIntegrationID != 0 || strings.Contains(r.URL, "azurecr") {
 		serv = types.ACR
 	} else if strings.Contains(r.URL, "index.docker.io") {
 		serv = types.DockerHub

+ 81 - 12
internal/registry/registry.go

@@ -12,6 +12,8 @@ import (
 	"sync"
 	"time"
 
+	"github.com/porter-dev/api-contracts/generated/go/porter/v1/porterv1connect"
+
 	"github.com/porter-dev/porter/internal/telemetry"
 
 	artifactregistry "cloud.google.com/go/artifactregistry/apiv1beta2"
@@ -157,22 +159,32 @@ func (r *Registry) ListRepositories(
 	if project.CapiProvisionerEnabled {
 		if strings.Contains(r.URL, ".azurecr.") {
 			telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "auth-mechanism", Value: "capi-azure"})
-			creds, err := conf.Repo.AzureIntegration().ListAzureIntegrationsByProjectID(r.ProjectID)
+
+			req := connect.NewRequest(&porterv1.ListRepositoriesForRegistryRequest{
+				ProjectId:   int64(r.ProjectID),
+				RegistryUri: r.URL,
+			})
+
+			resp, err := conf.ClusterControlPlaneClient.ListRepositoriesForRegistry(ctx, req)
 			if err != nil {
-				return nil, telemetry.Error(ctx, span, err, "error getting azure credentials for capi cluster")
-			}
-			if len(creds) == 0 {
-				return nil, telemetry.Error(ctx, span, err, "no azure credentials for capi cluster")
+				return nil, telemetry.Error(ctx, span, err, "error listing ecr repositories")
 			}
-			r.AzureIntegrationID = creds[0].ID
-			telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "azure-integration-id", Value: r.AzureIntegrationID})
 
-			repos, err := r.listACRRepositories(ctx, repo)
+			res := make([]*ptypes.RegistryRepository, 0)
+
+			parsedURL, err := url.Parse("https://" + r.URL)
 			if err != nil {
-				return nil, telemetry.Error(ctx, span, err, "error listing acr repositories")
+				return nil, err
 			}
 
-			return repos, nil
+			for _, repo := range resp.Msg.Repositories {
+				res = append(res, &ptypes.RegistryRepository{
+					Name: repo.Name,
+					URI:  parsedURL.Host + "/" + repo.Name,
+				})
+			}
+
+			return res, nil
 		} else {
 			telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "auth-mechanism", Value: "capi-aws"})
 			uri := strings.TrimPrefix(r.URL, "https://")
@@ -1677,36 +1689,93 @@ func (r *Registry) listDockerHubImages(repoName string, repo repository.Reposito
 func (r *Registry) GetDockerConfigJSON(
 	repo repository.Repository,
 	doAuth *oauth2.Config, // only required if using DOCR
+	ccpClient porterv1connect.ClusterControlPlaneServiceClient,
 ) ([]byte, error) {
+	ctx, span := telemetry.NewSpan(context.Background(), "docker-config-json")
+	defer span.End()
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "project-id", Value: r.ProjectID},
+		telemetry.AttributeKV{Key: "registry-url", Value: r.URL},
+	)
+
 	var conf *configfile.ConfigFile
 	var err error
 
 	// switch on the auth mechanism to get a token
 	if r.AWSIntegrationID != 0 {
 		conf, err = r.getECRDockerConfigFile(repo)
+
+		if err != nil {
+			return nil, telemetry.Error(ctx, span, err, "error getting ECR docker config file")
+		}
+
+		return json.Marshal(conf)
 	}
 
 	if r.GCPIntegrationID != 0 {
 		conf, err = r.getGCRDockerConfigFile(repo)
+
+		if err != nil {
+			return nil, telemetry.Error(ctx, span, err, "error getting GCP docker config file")
+		}
+
+		return json.Marshal(conf)
 	}
 
 	if r.DOIntegrationID != 0 {
 		conf, err = r.getDOCRDockerConfigFile(repo, doAuth)
+
+		if err != nil {
+			return nil, telemetry.Error(ctx, span, err, "error getting DO docker config file")
+		}
+
+		return json.Marshal(conf)
 	}
 
 	if r.BasicIntegrationID != 0 {
 		conf, err = r.getPrivateRegistryDockerConfigFile(repo)
+
+		if err != nil {
+			return nil, telemetry.Error(ctx, span, err, "error getting private docker config file")
+		}
+
+		return json.Marshal(conf)
 	}
 
 	if r.AzureIntegrationID != 0 {
 		conf, err = r.getACRDockerConfigFile(repo)
+
+		if err != nil {
+			return nil, telemetry.Error(ctx, span, err, "error getting ACR docker config file")
+		}
+
+		return json.Marshal(conf)
 	}
 
+	proj, err := repo.Project().ReadProject(r.ProjectID)
 	if err != nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, err, "error reading project id")
+	}
+
+	if proj.CapiProvisionerEnabled {
+		dockerConfigReq := connect.NewRequest(&porterv1.DockerConfigFileForRegistryRequest{
+			ProjectId:   int64(proj.ID),
+			RegistryUri: r.URL,
+		})
+		dockerConfigResp, err := ccpClient.DockerConfigFileForRegistry(ctx, dockerConfigReq)
+		if err != nil {
+			return nil, telemetry.Error(ctx, span, err, "error getting token response from ccp")
+		}
+
+		if dockerConfigResp.Msg == nil || dockerConfigResp.Msg.DockerConfigFile == nil {
+			return nil, telemetry.Error(ctx, span, err, "no docker config found in response")
+		}
+
+		return dockerConfigResp.Msg.DockerConfigFile, nil
 	}
 
-	return json.Marshal(conf)
+	return nil, telemetry.Error(ctx, span, nil, "no docker config file found")
 }
 
 func (r *Registry) getECRDockerConfigFile(

+ 5 - 0
package.json

@@ -0,0 +1,5 @@
+{
+  "dependencies": {
+    "@porter-dev/api-contracts": "file:../api-contracts/generated/js"
+  }
+}