Skip to content

Commit

Permalink
DEVPROD-11883: ignore Parameter Store feature flag for GitHub app keys (
Browse files Browse the repository at this point in the history
  • Loading branch information
Kimchelly authored Jan 9, 2025
1 parent 705d8f6 commit 5e0e6e2
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 8 deletions.
6 changes: 6 additions & 0 deletions cloud/parameterstore/fakeparameter/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ var (

// FindOneID finds a single fake parameter by its name.
func FindOneID(ctx context.Context, id string) (*FakeParameter, error) {
checkTestingEnvironment()

var p FakeParameter
err := evergreen.GetEnvironment().DB().Collection(Collection).FindOne(ctx, bson.M{NameKey: id}).Decode(&p)
if adb.ResultsNotFound(err) {
Expand All @@ -35,6 +37,8 @@ func FindOneID(ctx context.Context, id string) (*FakeParameter, error) {

// FindByIDs finds one or more fake parameters by their names.
func FindByIDs(ctx context.Context, ids ...string) ([]FakeParameter, error) {
checkTestingEnvironment()

if len(ids) == 0 {
return nil, nil
}
Expand All @@ -52,6 +56,8 @@ func FindByIDs(ctx context.Context, ids ...string) ([]FakeParameter, error) {
// DeleteOneID deletes a fake parameter with the given ID. Returns whether any
// matching parameter was deleted.
func DeleteOneID(ctx context.Context, id string) (bool, error) {
checkTestingEnvironment()

res, err := evergreen.GetEnvironment().DB().Collection(Collection).DeleteOne(ctx, bson.M{NameKey: id})
if err != nil {
return false, errors.Wrap(err, "deleting fake parameter by ID")
Expand Down
9 changes: 8 additions & 1 deletion cloud/parameterstore/fakeparameter/fake_parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import (
// to "test".
var ExecutionEnvironmentType = "production"

func init() {
// checkTestingEnvironment performs a safety check to verify that logic in this
// package is only called in a testing environment. If this is called in a
// non-testing environment, the process will exit with a fatal error.
func checkTestingEnvironment() {
if ExecutionEnvironmentType != "test" {
grip.EmergencyFatal(message.Fields{
"message": "fake Parameter Store testing code called in a non-testing environment",
Expand All @@ -41,13 +44,17 @@ type FakeParameter struct {

// Insert inserts a single parameter into the fake parameter store.
func (p *FakeParameter) Insert(ctx context.Context) error {
checkTestingEnvironment()

_, err := evergreen.GetEnvironment().DB().Collection(Collection).InsertOne(ctx, p)
return err
}

// Upsert inserts a single parameter into the fake parameter store or replaces
// an one if one with the same ID already exists.
func (p *FakeParameter) Upsert(ctx context.Context) error {
checkTestingEnvironment()

_, err := evergreen.GetEnvironment().DB().Collection(Collection).ReplaceOne(ctx, bson.M{NameKey: p.Name}, p, options.Replace().SetUpsert(true))
return err
}
11 changes: 11 additions & 0 deletions cloud/parameterstore/fakeparameter/ssm_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ type FakeSSMClient struct{}
// NewFakeSSMClient returns a fake SSM client implementation backed by the DB.
// This should only be used in testing.
func NewFakeSSMClient() *FakeSSMClient {
checkTestingEnvironment()
return &FakeSSMClient{}
}

// PutParameter inserts a parameter into the fake parameter store.
func (c *FakeSSMClient) PutParameter(ctx context.Context, input *ssm.PutParameterInput) (*ssm.PutParameterOutput, error) {
checkTestingEnvironment()

name := utility.FromStringPtr(input.Name)
value := utility.FromStringPtr(input.Value)
catcher := grip.NewBasicCatcher()
Expand Down Expand Up @@ -55,6 +58,8 @@ func (c *FakeSSMClient) PutParameter(ctx context.Context, input *ssm.PutParamete
// DeleteParametersSimple is the same as DeleteParameters but only returns the
// deleted parameter names.
func (c *FakeSSMClient) DeleteParametersSimple(ctx context.Context, input *ssm.DeleteParametersInput) ([]string, error) {
checkTestingEnvironment()

output, err := c.DeleteParameters(ctx, input)
if err != nil {
return nil, err
Expand All @@ -70,6 +75,8 @@ func (c *FakeSSMClient) DeleteParametersSimple(ctx context.Context, input *ssm.D
// DeleteParameters deletes the specified parameters from the fake parameter
// store.
func (c *FakeSSMClient) DeleteParameters(ctx context.Context, input *ssm.DeleteParametersInput) ([]*ssm.DeleteParametersOutput, error) {
checkTestingEnvironment()

names := input.Names
if len(names) == 0 {
return nil, nil
Expand Down Expand Up @@ -98,6 +105,8 @@ func (c *FakeSSMClient) DeleteParameters(ctx context.Context, input *ssm.DeleteP
// GetParametersSimple is the same as GetParameters but only returns the
// parameters.
func (c *FakeSSMClient) GetParametersSimple(ctx context.Context, input *ssm.GetParametersInput) ([]ssmTypes.Parameter, error) {
checkTestingEnvironment()

outputs, err := c.GetParameters(ctx, input)
if err != nil {
return nil, err
Expand All @@ -113,6 +122,8 @@ func (c *FakeSSMClient) GetParametersSimple(ctx context.Context, input *ssm.GetP
// GetParameters retrieves the specified parameters from the fake parameter
// store.
func (c *FakeSSMClient) GetParameters(ctx context.Context, input *ssm.GetParametersInput) ([]*ssm.GetParametersOutput, error) {
checkTestingEnvironment()

names := input.Names
if len(names) == 0 {
return nil, nil
Expand Down
2 changes: 1 addition & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var (

// ClientVersion is the commandline version string used to control updating
// the CLI. The format is the calendar date (YYYY-MM-DD).
ClientVersion = "2025-01-09a"
ClientVersion = "2025-01-09b"

// Agent version to control agent rollover. The format is the calendar date
// (YYYY-MM-DD).
Expand Down
2 changes: 1 addition & 1 deletion model/github_app_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func githubAppCheckAndRunParameterStoreOp(ctx context.Context, appAuth *githubap
if err != nil {
return errors.Wrapf(err, "checking project ref '%s' to verify if GitHub app should use Parameter Store", appAuth.Id)
}
isPSEnabled, err := isParameterStoreEnabledForProject(ctx, ref)
isPSEnabled, err := isParameterStoreEnabledForProject(ctx, ref, true)
if err != nil {
return errors.Wrapf(err, "checking if Parameter Store is enabled for project '%s'", appAuth.Id)
}
Expand Down
11 changes: 8 additions & 3 deletions model/project_vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -610,10 +610,11 @@ func getUpdatedParamMappings(original ParameterMappings, upserted, deleted map[s
}

// isParameterStoreEnabledForProject checks if Parameter Store is enabled for a
// project.
// project. If ignoreProjectFeatureFlag is enabled, the project will use
// Parameter Store regardless of the project-level feature flag.
// TODO (DEVPROD-11882): remove feature flag checks once all project vars are
// using Parameter Store and the rollout is stable.
func isParameterStoreEnabledForProject(ctx context.Context, ref *ProjectRef) (bool, error) {
func isParameterStoreEnabledForProject(ctx context.Context, ref *ProjectRef, ignoreProjectFeatureFlag bool) (bool, error) {
flags, err := evergreen.GetServiceFlags(ctx)
if err != nil {
return false, errors.Wrap(err, "getting service flags")
Expand All @@ -622,6 +623,10 @@ func isParameterStoreEnabledForProject(ctx context.Context, ref *ProjectRef) (bo
return false, nil
}

if ignoreProjectFeatureFlag {
return true, nil
}

if ref == nil {
return false, errors.Errorf("ref is nil")
}
Expand Down Expand Up @@ -901,7 +906,7 @@ func (projectVars *ProjectVars) checkAndRunParameterStoreOp(ctx context.Context,
"project_id": projectVars.Id,
"epic": "DEVPROD-5552",
}))
isPSEnabled, err := isParameterStoreEnabledForProject(ctx, ref)
isPSEnabled, err := isParameterStoreEnabledForProject(ctx, ref, false)
grip.Error(message.WrapError(err, message.Fields{
"message": "could not check if Parameter Store is enabled for project; assuming it's disabled and will not use Parameter Store",
"op": opName,
Expand Down
8 changes: 7 additions & 1 deletion operations/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const (
syncTasksFlagName = "sync_tasks"
syncTimeoutFlagName = "sync_timeout"
tasksFlagName = "tasks"
testingEnvFlagName = "testing-env"
traceEndpointFlagName = "trace_endpoint"
uncommittedChangesFlag = "uncommitted"
variantsFlagName = "variants"
Expand Down Expand Up @@ -89,7 +90,12 @@ func serviceConfigFlags(flags ...cli.Flag) []cli.Flag {
cli.BoolFlag{
Name: overwriteConfFlagName,
Usage: "overwrite the configuration in the DB with the file",
})
},
cli.BoolFlag{
Name: testingEnvFlagName,
Usage: "if true, run Evergreen service as a testing environment",
},
)
}

func addProjectFlag(flags ...cli.Flag) []cli.Flag {
Expand Down
2 changes: 1 addition & 1 deletion operations/service_deploy_smoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func startLocalEvergreen() cli.Command {
return errors.Wrap(err, "getting working directory")
}
binary := filepath.Join(wd, "clients", runtime.GOOS+"_"+runtime.GOARCH, "evergreen")
if err := smokeRunBinary(exit, "web.service", wd, binary, "service", "web", "--db", "evergreen_local"); err != nil {
if err := smokeRunBinary(exit, "web.service", wd, binary, "service", "web", "--db", "evergreen_local", "--testing-env"); err != nil {
return errors.Wrap(err, "running web service")
}
<-exit
Expand Down
23 changes: 23 additions & 0 deletions operations/service_web.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (

"github.com/evergreen-ci/evergreen"
"github.com/evergreen-ci/evergreen/auth"
"github.com/evergreen-ci/evergreen/cloud/parameterstore"
"github.com/evergreen-ci/evergreen/cloud/parameterstore/fakeparameter"
"github.com/evergreen-ci/evergreen/service"
"github.com/evergreen-ci/gimlet"
"github.com/evergreen-ci/utility"
Expand Down Expand Up @@ -74,6 +76,27 @@ func startWebService() cli.Command {
db := parseDB(c)
env, err := evergreen.NewEnvironment(ctx, confPath, versionID, clientS3Bucket, db, tp)
grip.EmergencyFatal(errors.Wrap(err, "configuring application environment"))

if c.Bool(testingEnvFlagName) {
// If running in a testing environment (e.g. local Evergreen),
// use a fake implementation of Parameter Store since testing
// environments won't have access to a real Parameter Store
// instance.
fakeparameter.ExecutionEnvironmentType = "test"

opts := parameterstore.ParameterManagerOptions{
PathPrefix: env.Settings().ParameterStore.Prefix,
CachingEnabled: true,
SSMClient: fakeparameter.NewFakeSSMClient(),
DB: env.DB(),
}
pm, err := parameterstore.NewParameterManager(ctx, opts)
if err != nil {
return errors.Wrap(err, "creating parameter manager")
}
env.SetParameterManager(pm)
}

evergreen.SetEnvironment(env)
if c.Bool(overwriteConfFlagName) {
grip.EmergencyFatal(errors.Wrap(env.SaveConfig(ctx), "saving config"))
Expand Down

0 comments on commit 5e0e6e2

Please sign in to comment.