From d5a233061bfbf2f7dbde30f385a25b84613bdb23 Mon Sep 17 00:00:00 2001 From: David Townley Date: Fri, 15 Sep 2023 17:35:41 -0400 Subject: [PATCH 1/2] filter default app environments --- .../handlers/environment_groups/create.go | 2 +- api/server/handlers/porter_app/parse.go | 2 +- .../update_app_environment_group.go | 22 +++++++++++-- .../kubernetes/environment_groups/create.go | 14 +++++--- .../kubernetes/environment_groups/list.go | 33 +++++++++++++++++-- .../kubernetes/environment_groups/sync.go | 4 +-- 6 files changed, 63 insertions(+), 14 deletions(-) diff --git a/api/server/handlers/environment_groups/create.go b/api/server/handlers/environment_groups/create.go index 5d0c748f30..ad9114e8ed 100644 --- a/api/server/handlers/environment_groups/create.go +++ b/api/server/handlers/environment_groups/create.go @@ -87,7 +87,7 @@ func (c *UpdateEnvironmentGroupHandler) ServeHTTP(w http.ResponseWriter, r *http CreatedAtUTC: time.Now().UTC(), } - err = environment_groups.CreateOrUpdateBaseEnvironmentGroup(ctx, agent, envGroup) + err = environment_groups.CreateOrUpdateBaseEnvironmentGroup(ctx, agent, envGroup, nil) if err != nil { err := telemetry.Error(ctx, span, err, "unable to create or update environment group") c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError)) diff --git a/api/server/handlers/porter_app/parse.go b/api/server/handlers/porter_app/parse.go index 01b77eddd4..327327a92e 100644 --- a/api/server/handlers/porter_app/parse.go +++ b/api/server/handlers/porter_app/parse.go @@ -349,7 +349,7 @@ func syncEnvironmentGroupToNamespaceIfLabelsExist(ctx context.Context, agent *ku TargetNamespace: targetNamespace, } - syncedEnvironment, err := environment_groups.SyncLatestVersionToNamespace(ctx, agent, inp) + syncedEnvironment, err := environment_groups.SyncLatestVersionToNamespace(ctx, agent, inp, nil) if err != nil { return fmt.Errorf("error syncing environment group: %w", err) } diff --git a/api/server/handlers/porter_app/update_app_environment_group.go b/api/server/handlers/porter_app/update_app_environment_group.go index 46f5d272b9..9180f8ca78 100644 --- a/api/server/handlers/porter_app/update_app_environment_group.go +++ b/api/server/handlers/porter_app/update_app_environment_group.go @@ -43,6 +43,17 @@ func NewUpdateAppEnvironmentHandler( } } +const ( + // LabelKey_AppName is the label key for the app name + LabelKey_AppName = "porter.run/app-name" + // LabelKey_DeploymentTargetID is the label key for the deployment target id + LabelKey_DeploymentTargetID = "porter.run/deployment-target-id" + // LabelKey_DefaultAppEnvironment is the label key for the default app environment + LabelKey_DefaultAppEnvironment = "porter.run/default-app-environment" + // LabelKey_DefaultAppEnvironment is the label key signifying the resource is managed by porter + LabelKey_PorterManaged = "porter.run/managed" +) + // UpdateAppEnvironmentRequest represents the accepted fields on a request to the /apps/{porter_app_name}/environment-group endpoint type UpdateAppEnvironmentRequest struct { DeploymentTargetID string `json:"deployment_target_id"` @@ -216,7 +227,14 @@ func (c *UpdateAppEnvironmentHandler) ServeHTTP(w http.ResponseWriter, r *http.R CreatedAtUTC: time.Now().UTC(), } - err = environment_groups.CreateOrUpdateBaseEnvironmentGroup(ctx, agent, envGroup) + additionalEnvGroupLabels := map[string]string{ + LabelKey_AppName: appName, + LabelKey_DeploymentTargetID: request.DeploymentTargetID, + LabelKey_DefaultAppEnvironment: "true", + LabelKey_PorterManaged: "true", + } + + err = environment_groups.CreateOrUpdateBaseEnvironmentGroup(ctx, agent, envGroup, additionalEnvGroupLabels) if err != nil { err := telemetry.Error(ctx, span, err, "unable to create or update base environment group") c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError)) @@ -228,7 +246,7 @@ func (c *UpdateAppEnvironmentHandler) ServeHTTP(w http.ResponseWriter, r *http.R TargetNamespace: namespace, } - syncedEnvironment, err := environment_groups.SyncLatestVersionToNamespace(ctx, agent, inp) + syncedEnvironment, err := environment_groups.SyncLatestVersionToNamespace(ctx, agent, inp, additionalEnvGroupLabels) if err != nil { err := telemetry.Error(ctx, span, err, "unable to create or update synced environment group") c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError)) diff --git a/internal/kubernetes/environment_groups/create.go b/internal/kubernetes/environment_groups/create.go index b8b61e96d9..72d3ccbfcd 100644 --- a/internal/kubernetes/environment_groups/create.go +++ b/internal/kubernetes/environment_groups/create.go @@ -16,7 +16,7 @@ import ( // If no existing environmentGroup exists by this name, a new one will be created as version 1, denoted by the label "porter.run/environment-group-version: 1". // If an environmentGroup already exists by this name, a new version will be created, and the label will be updated to reflect the new version. // Providing the Version field to this function will be ignored in order to not accidentally overwrite versions -func CreateOrUpdateBaseEnvironmentGroup(ctx context.Context, a *kubernetes.Agent, environmentGroup EnvironmentGroup) error { +func CreateOrUpdateBaseEnvironmentGroup(ctx context.Context, a *kubernetes.Agent, environmentGroup EnvironmentGroup, additionalLabels map[string]string) error { ctx, span := telemetry.NewSpan(ctx, "create-environment-group") defer span.End() telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "environment-group", Value: environmentGroup.Name}) @@ -51,7 +51,7 @@ func CreateOrUpdateBaseEnvironmentGroup(ctx context.Context, a *kubernetes.Agent CreatedAtUTC: environmentGroup.CreatedAtUTC, } - err = createVersionedEnvironmentGroupInNamespace(ctx, a, newEnvironmentGroup, Namespace_EnvironmentGroups) + err = createVersionedEnvironmentGroupInNamespace(ctx, a, newEnvironmentGroup, Namespace_EnvironmentGroups, additionalLabels) if err != nil { return telemetry.Error(ctx, span, err, "unable to create new versioned environment group") } @@ -62,7 +62,7 @@ func CreateOrUpdateBaseEnvironmentGroup(ctx context.Context, a *kubernetes.Agent // createEnvironmentGroupInTargetNamespace creates a new environment group in the target namespace. If you want to create a new base environment group, use CreateOrUpdateBaseEnvironmentGroup instead. // This should only be used for sync from a base environment to a target environment. // If the target namespace does not exist, it will be created for you. -func createEnvironmentGroupInTargetNamespace(ctx context.Context, a *kubernetes.Agent, namespace string, environmentGroup EnvironmentGroup) (string, error) { +func createEnvironmentGroupInTargetNamespace(ctx context.Context, a *kubernetes.Agent, namespace string, environmentGroup EnvironmentGroup, additionalLabels map[string]string) (string, error) { ctx, span := telemetry.NewSpan(ctx, "create-environment-group-in-target") defer span.End() telemetry.WithAttributes(span, @@ -95,7 +95,7 @@ func createEnvironmentGroupInTargetNamespace(ctx context.Context, a *kubernetes. } telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "environment-group-namespace", Value: namespace}) - err = createVersionedEnvironmentGroupInNamespace(ctx, a, environmentGroup, namespace) + err = createVersionedEnvironmentGroupInNamespace(ctx, a, environmentGroup, namespace, additionalLabels) if err != nil { return configMapName, telemetry.Error(ctx, span, err, "error creating environment group clone in target namespace") } @@ -104,7 +104,7 @@ func createEnvironmentGroupInTargetNamespace(ctx context.Context, a *kubernetes. } // createVersionedEnvironmentGroupInNamespace creates a new environment group in the target namespace. This is used to keep the configmap and secret version for an environment variable in sync -func createVersionedEnvironmentGroupInNamespace(ctx context.Context, a *kubernetes.Agent, environmentGroup EnvironmentGroup, targetNamespace string) error { +func createVersionedEnvironmentGroupInNamespace(ctx context.Context, a *kubernetes.Agent, environmentGroup EnvironmentGroup, targetNamespace string, additionalLabels map[string]string) error { ctx, span := telemetry.NewSpan(ctx, "create-environment-group-on-cluster") defer span.End() @@ -119,6 +119,10 @@ func createVersionedEnvironmentGroupInNamespace(ctx context.Context, a *kubernet }, Data: environmentGroup.Variables, } + for k, v := range additionalLabels { + configMap.Labels[k] = v + } + err := createConfigMapWithVersion(ctx, a, configMap, environmentGroup.Version) if err != nil { return telemetry.Error(ctx, span, err, "unable to create new environment group variables version") diff --git a/internal/kubernetes/environment_groups/list.go b/internal/kubernetes/environment_groups/list.go index 533c9ff7ce..575e6ee3c1 100644 --- a/internal/kubernetes/environment_groups/list.go +++ b/internal/kubernetes/environment_groups/list.go @@ -17,6 +17,8 @@ const ( LabelKey_EnvironmentGroupVersion = "porter.run/environment-group-version" LabelKey_EnvironmentGroupName = "porter.run/environment-group-name" + LabelKey_DefaultAppEnvironment = "porter.run/default-app-environment" + // Namespace_EnvironmentGroups is the base namespace for storing all environment groups. // The configmaps and secrets here should be considered the source's of truth for a given version Namespace_EnvironmentGroups = "porter-env-group" @@ -37,9 +39,10 @@ type EnvironmentGroup struct { } type environmentGroupOptions struct { - namespace string - environmentGroupLabelName string - environmentGroupLabelVersion int + namespace string + environmentGroupLabelName string + environmentGroupLabelVersion int + includeDefaultAppEnvironmentGroups bool } // EnvironmentGroupOption is a function that modifies ListEnvironmentGroups @@ -66,6 +69,13 @@ func WithEnvironmentGroupVersion(version int) EnvironmentGroupOption { } } +// WithDefaultAppEnvironmentGroup includes default app environment groups in the list +func WithDefaultAppEnvironmentGroup() EnvironmentGroupOption { + return func(opts *environmentGroupOptions) { + opts.includeDefaultAppEnvironmentGroups = true + } +} + // ListEnvironmentGroups returns all environment groups stored in the provided namespace. If none is set, it will use the namespace "porter-env-group" func ListEnvironmentGroups(ctx context.Context, a *kubernetes.Agent, listOpts ...EnvironmentGroupOption) ([]EnvironmentGroup, error) { ctx, span := telemetry.NewSpan(ctx, "list-environment-groups") @@ -108,6 +118,8 @@ func ListEnvironmentGroups(ctx context.Context, a *kubernetes.Agent, listOpts .. // envGroupSet's key is the environment group's versioned name envGroupSet := make(map[string]EnvironmentGroup) for _, cm := range configMapListResp.Items { + fmt.Printf("cm: %+v\n", cm) + name, ok := cm.Labels[LabelKey_EnvironmentGroupName] if !ok { continue // missing name label, not an environment group @@ -121,6 +133,13 @@ func ListEnvironmentGroups(ctx context.Context, a *kubernetes.Agent, listOpts .. continue // invalid version label as it should be an int, not an environment group } + if !opts.includeDefaultAppEnvironmentGroups { + value, _ := cm.Labels[LabelKey_DefaultAppEnvironment] + if value == "true" { + continue // do not include default app environment groups + } + } + if _, ok := envGroupSet[cm.Name]; !ok { envGroupSet[cm.Name] = EnvironmentGroup{} } @@ -146,6 +165,14 @@ func ListEnvironmentGroups(ctx context.Context, a *kubernetes.Agent, listOpts .. if err != nil { continue // invalid version label as it should be an int, not an environment group } + + if !opts.includeDefaultAppEnvironmentGroups { + value, ok := secret.Labels[LabelKey_DefaultAppEnvironment] + if ok && value == "true" { + continue // do not include default app environment groups + } + } + if _, ok := envGroupSet[secret.Name]; !ok { envGroupSet[secret.Name] = EnvironmentGroup{} } diff --git a/internal/kubernetes/environment_groups/sync.go b/internal/kubernetes/environment_groups/sync.go index da106672fd..32928ae0b4 100644 --- a/internal/kubernetes/environment_groups/sync.go +++ b/internal/kubernetes/environment_groups/sync.go @@ -26,7 +26,7 @@ type SyncLatestVersionToNamespaceOutput struct { // SyncLatestVersionToNamespace gets the latest version of a given environment group, and makes a copy of it in the target // namespace. If the versions match, no changes will be made. In either case, the name of an environment group in the target namespace will be returned // unless an error has occurred. -func SyncLatestVersionToNamespace(ctx context.Context, a *kubernetes.Agent, inp SyncLatestVersionToNamespaceInput) (SyncLatestVersionToNamespaceOutput, error) { +func SyncLatestVersionToNamespace(ctx context.Context, a *kubernetes.Agent, inp SyncLatestVersionToNamespaceInput, additionalLabels map[string]string) (SyncLatestVersionToNamespaceOutput, error) { ctx, span := telemetry.NewSpan(ctx, "sync-env-group-version-to-namespace") defer span.End() @@ -65,7 +65,7 @@ func SyncLatestVersionToNamespace(ctx context.Context, a *kubernetes.Agent, inp }, nil } - targetConfigmapName, err := createEnvironmentGroupInTargetNamespace(ctx, a, inp.TargetNamespace, baseEnvironmentGroup) + targetConfigmapName, err := createEnvironmentGroupInTargetNamespace(ctx, a, inp.TargetNamespace, baseEnvironmentGroup, additionalLabels) if err != nil { return output, telemetry.Error(ctx, span, err, "unable to create environment group in target namespace") } From c41ed4126e514e82bb447175ce10bdcc6f54bf35 Mon Sep 17 00:00:00 2001 From: David Townley Date: Fri, 15 Sep 2023 17:38:25 -0400 Subject: [PATCH 2/2] address lint --- .../porter_app/update_app_environment_group.go | 12 +++++------- internal/kubernetes/environment_groups/list.go | 4 +--- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/api/server/handlers/porter_app/update_app_environment_group.go b/api/server/handlers/porter_app/update_app_environment_group.go index 9180f8ca78..935e31f561 100644 --- a/api/server/handlers/porter_app/update_app_environment_group.go +++ b/api/server/handlers/porter_app/update_app_environment_group.go @@ -48,9 +48,7 @@ const ( LabelKey_AppName = "porter.run/app-name" // LabelKey_DeploymentTargetID is the label key for the deployment target id LabelKey_DeploymentTargetID = "porter.run/deployment-target-id" - // LabelKey_DefaultAppEnvironment is the label key for the default app environment - LabelKey_DefaultAppEnvironment = "porter.run/default-app-environment" - // LabelKey_DefaultAppEnvironment is the label key signifying the resource is managed by porter + // LabelKey_PorterManaged is the label key signifying the resource is managed by porter LabelKey_PorterManaged = "porter.run/managed" ) @@ -228,10 +226,10 @@ func (c *UpdateAppEnvironmentHandler) ServeHTTP(w http.ResponseWriter, r *http.R } additionalEnvGroupLabels := map[string]string{ - LabelKey_AppName: appName, - LabelKey_DeploymentTargetID: request.DeploymentTargetID, - LabelKey_DefaultAppEnvironment: "true", - LabelKey_PorterManaged: "true", + LabelKey_AppName: appName, + LabelKey_DeploymentTargetID: request.DeploymentTargetID, + environment_groups.LabelKey_DefaultAppEnvironment: "true", + LabelKey_PorterManaged: "true", } err = environment_groups.CreateOrUpdateBaseEnvironmentGroup(ctx, agent, envGroup, additionalEnvGroupLabels) diff --git a/internal/kubernetes/environment_groups/list.go b/internal/kubernetes/environment_groups/list.go index 575e6ee3c1..50561a3dc1 100644 --- a/internal/kubernetes/environment_groups/list.go +++ b/internal/kubernetes/environment_groups/list.go @@ -118,8 +118,6 @@ func ListEnvironmentGroups(ctx context.Context, a *kubernetes.Agent, listOpts .. // envGroupSet's key is the environment group's versioned name envGroupSet := make(map[string]EnvironmentGroup) for _, cm := range configMapListResp.Items { - fmt.Printf("cm: %+v\n", cm) - name, ok := cm.Labels[LabelKey_EnvironmentGroupName] if !ok { continue // missing name label, not an environment group @@ -134,7 +132,7 @@ func ListEnvironmentGroups(ctx context.Context, a *kubernetes.Agent, listOpts .. } if !opts.includeDefaultAppEnvironmentGroups { - value, _ := cm.Labels[LabelKey_DefaultAppEnvironment] + value := cm.Labels[LabelKey_DefaultAppEnvironment] if value == "true" { continue // do not include default app environment groups }