Przeglądaj źródła

change exported env group methods to return secret variables as dummy value (#3587)

Co-authored-by: David Townley <davidtownley@Davids-MacBook-Air.local>
d-g-town 2 lat temu
rodzic
commit
dbc7bbd905

+ 6 - 5
api/server/handlers/porter_app/update_app_environment_group.go

@@ -161,18 +161,19 @@ func (c *UpdateAppEnvironmentHandler) ServeHTTP(w http.ResponseWriter, r *http.R
 			}
 		}
 		for key, newValue := range request.Secrets {
-			if existingValue, ok := latestEnvironmentGroup.SecretVariables[key]; !ok || string(existingValue) != newValue {
+			// We cannot check if the values are the same because the existing secrets are substituted with dummy values. However, if the new value is a dummy value, then it is unchanged.
+			if _, ok := latestEnvironmentGroup.SecretVariables[key]; !ok || newValue != environment_groups.EnvGroupSecretDummyValue {
 				sameEnvGroup = false
 			}
 		}
 		if request.HardUpdate {
-			for key, existingValue := range latestEnvironmentGroup.Variables {
-				if newValue, ok := request.Variables[key]; !ok || existingValue != newValue {
+			for key := range latestEnvironmentGroup.Variables {
+				if _, ok := request.Variables[key]; !ok {
 					sameEnvGroup = false
 				}
 			}
-			for key, existingValue := range latestEnvironmentGroup.SecretVariables {
-				if newValue, ok := request.Secrets[key]; !ok || string(existingValue) != newValue {
+			for key := range latestEnvironmentGroup.SecretVariables {
+				if _, ok := request.Secrets[key]; !ok {
 					sameEnvGroup = false
 				}
 			}

+ 1 - 1
dashboard/package.json

@@ -147,4 +147,4 @@
     "webpack-cli": "^3.3.12",
     "webpack-dev-server": "^3.11.0"
   }
-}
+}

+ 1 - 1
go.mod

@@ -73,6 +73,7 @@ require (
 	github.com/Azure/azure-sdk-for-go/sdk/azcore v0.23.1
 	github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v0.5.0
 	github.com/briandowns/spinner v1.18.1
+	github.com/cloudflare/cloudflare-go v0.76.0
 	github.com/glebarez/sqlite v1.6.0
 	github.com/go-chi/chi/v5 v5.0.8
 	github.com/honeycombio/otel-config-go v1.11.0
@@ -123,7 +124,6 @@ require (
 	github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220517224237-e6f29200ae04 // indirect
 	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
 	github.com/chrismellard/docker-credential-acr-env v0.0.0-20220327082430-c57b701bfc08 // indirect
-	github.com/cloudflare/cloudflare-go v0.76.0 // indirect
 	github.com/dimchansky/utfbom v1.1.1 // indirect
 	github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect
 	github.com/emicklei/go-restful/v3 v3.9.0 // indirect

+ 0 - 13
go.sum

@@ -960,7 +960,6 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
 github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
 github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
 github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
-github.com/hashicorp/go-hclog v1.0.0 h1:bkKf0BeBXcSYa7f5Fyi9gMuQ8gNsxeiNpZjR6VxNZeo=
 github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
 github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
 github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
@@ -968,8 +967,6 @@ github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:
 github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
 github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
 github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
-github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ=
-github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
 github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
 github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
 github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
@@ -1993,8 +1990,6 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
-golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
 golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
 golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -2105,8 +2100,6 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
 golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -2273,8 +2266,6 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@@ -2285,8 +2276,6 @@ golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9sn
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
 golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2299,8 +2288,6 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
 golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

+ 2 - 0
go.work.sum

@@ -982,6 +982,7 @@ 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/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
 golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
 golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
@@ -991,6 +992,7 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
 golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=

+ 17 - 1
internal/kubernetes/environment_groups/create.go

@@ -1,6 +1,7 @@
 package environment_groups
 
 import (
+	"bytes"
 	"context"
 	"fmt"
 	"strconv"
@@ -38,11 +39,26 @@ func CreateOrUpdateBaseEnvironmentGroup(ctx context.Context, a *kubernetes.Agent
 	}
 	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "environment-group-namespace", Value: Namespace_EnvironmentGroups})
 
-	latestEnvironmentGroup, err := LatestBaseEnvironmentGroup(ctx, a, environmentGroup.Name)
+	latestEnvironmentGroup, err := latestBaseEnvironmentGroup(ctx, a, environmentGroup.Name)
 	if err != nil {
 		return telemetry.Error(ctx, span, err, "unable to get latest base environment group by name")
 	}
 
+	// If any of the secret variables are set to the dummy value (i.e. are unchanged), replace them with the existing value.
+	for k, v := range environmentGroup.SecretVariables {
+		if bytes.Equal(v, []byte(EnvGroupSecretDummyValue)) {
+			existingValue, ok := latestEnvironmentGroup.SecretVariables[k]
+			if !ok {
+				return telemetry.Error(ctx, span, nil, "secret variable does not exist in latest environment group")
+			}
+			if string(existingValue) == "" {
+				return telemetry.Error(ctx, span, nil, "secret variable value is empty")
+			}
+
+			environmentGroup.SecretVariables[k] = existingValue
+		}
+	}
+
 	newEnvironmentGroup := EnvironmentGroup{
 		Name:            environmentGroup.Name,
 		Variables:       environmentGroup.Variables,

+ 33 - 1
internal/kubernetes/environment_groups/get.go

@@ -7,7 +7,9 @@ import (
 	"github.com/porter-dev/porter/internal/telemetry"
 )
 
-// LatestBaseEnvironmentGroup returns the most recent version of an environment group stored in the porter-env-group namespace
+// LatestBaseEnvironmentGroup returns the most recent version of an environment group stored in the porter-env-group namespace.
+// It replaces all secret values with a dummy variable and can be used to return values to the user.  If you need access to the true secret values,
+// use the private latestBaseEnvironmentGroup function instead.
 func LatestBaseEnvironmentGroup(ctx context.Context, a *kubernetes.Agent, environmentGroupName string) (EnvironmentGroup, error) {
 	ctx, span := telemetry.NewSpan(ctx, "latest-base-env-group")
 	defer span.End()
@@ -35,6 +37,36 @@ func LatestBaseEnvironmentGroup(ctx context.Context, a *kubernetes.Agent, enviro
 	return highestVersionEnvironmentGroup, nil
 }
 
+// latestBaseEnvironmentGroup returns the most recent version of an environment group stored in the porter-env-group namespace.
+// This is a private function because it returns all secret values.  If you are trying to retrieve the latest base environment group to return to the user,
+// use the exported LatestBaseEnvironmentGroup instead.
+func latestBaseEnvironmentGroup(ctx context.Context, a *kubernetes.Agent, environmentGroupName string) (EnvironmentGroup, error) {
+	ctx, span := telemetry.NewSpan(ctx, "latest-base-env-group-private")
+	defer span.End()
+	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "environment-group-name", Value: environmentGroupName})
+
+	var eg EnvironmentGroup
+
+	baseEnvironmentGroupVersions, err := listEnvironmentGroups(ctx, a, WithEnvironmentGroupName(environmentGroupName), WithNamespace(Namespace_EnvironmentGroups))
+	if err != nil {
+		return eg, telemetry.Error(ctx, span, err, "unable to list base environment groups")
+	}
+
+	var highestVersionEnvironmentGroup EnvironmentGroup
+	for _, baseEnvironmentGroup := range baseEnvironmentGroupVersions {
+		if baseEnvironmentGroup.Version > highestVersionEnvironmentGroup.Version {
+			highestVersionEnvironmentGroup = baseEnvironmentGroup
+		}
+	}
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "highest-version", Value: highestVersionEnvironmentGroup.Version},
+		telemetry.AttributeKV{Key: "highest-version-name", Value: highestVersionEnvironmentGroup.Name},
+	)
+
+	return highestVersionEnvironmentGroup, nil
+}
+
 // EnvironmentGroupInTargetNamespaceInput contains all information required to check if an environment group exists in a target namespace.
 // If you are looking for envrionment groups in the base namespace, consider using LatestBaseEnvironmentGroup or ListBaseEnvironmentGroups instead
 type EnvironmentGroupInTargetNamespaceInput struct {

+ 29 - 3
internal/kubernetes/environment_groups/list.go

@@ -66,9 +66,11 @@ func WithEnvironmentGroupVersion(version int) EnvironmentGroupOption {
 	}
 }
 
-// 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")
+// listEnvironmentGroups returns all environment groups stored in the provided namespace. If none is set, it will use the namespace "porter-env-group".
+// This method returns all secret values, which should never be returned out of this package.  If you are trying to get the environment group values to return to the user,
+// use the exported ListEnvironmentGroups instead.
+func listEnvironmentGroups(ctx context.Context, a *kubernetes.Agent, listOpts ...EnvironmentGroupOption) ([]EnvironmentGroup, error) {
+	ctx, span := telemetry.NewSpan(ctx, "list-environment-groups-private")
 	defer span.End()
 
 	var opts environmentGroupOptions
@@ -166,6 +168,30 @@ func ListEnvironmentGroups(ctx context.Context, a *kubernetes.Agent, listOpts ..
 	return envGroups, nil
 }
 
+// EnvGroupSecretDummyValue is the value that will be returned for secret variables in environment groups
+const EnvGroupSecretDummyValue = "********"
+
+// ListEnvironmentGroups returns all environment groups stored in the provided namespace. If none is set, it will use the namespace "porter-env-group".
+// This method replaces all secret values with a dummy value so that they are not exposed to the user.  If you need access to the true secret values,
+// use the unexported listEnvironmentGroups instead.
+func ListEnvironmentGroups(ctx context.Context, a *kubernetes.Agent, listOpts ...EnvironmentGroupOption) ([]EnvironmentGroup, error) {
+	ctx, span := telemetry.NewSpan(ctx, "list-environment-groups")
+	defer span.End()
+
+	envGroups, err := listEnvironmentGroups(ctx, a, listOpts...)
+	if err != nil {
+		return nil, telemetry.Error(ctx, span, err, "unable to list environment groups")
+	}
+
+	for _, envGroup := range envGroups {
+		for k := range envGroup.SecretVariables {
+			envGroup.SecretVariables[k] = []byte(EnvGroupSecretDummyValue)
+		}
+	}
+
+	return envGroups, nil
+}
+
 // LinkedPorterApplication represents an application which was linked to an environment group
 type LinkedPorterApplication struct {
 	Name      string

+ 1 - 1
internal/kubernetes/environment_groups/sync.go

@@ -44,7 +44,7 @@ func SyncLatestVersionToNamespace(ctx context.Context, a *kubernetes.Agent, inp
 		telemetry.AttributeKV{Key: "target-environment-namespace", Value: inp.TargetNamespace},
 	)
 
-	baseEnvironmentGroup, err := LatestBaseEnvironmentGroup(ctx, a, inp.BaseEnvironmentGroupName)
+	baseEnvironmentGroup, err := latestBaseEnvironmentGroup(ctx, a, inp.BaseEnvironmentGroupName)
 	if err != nil {
 		return output, telemetry.Error(ctx, span, err, "unable to find latest environment group version")
 	}