Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEVPROD-11883: ignore Parameter Store feature flag for GitHub app keys #8594

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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-02"
ClientVersion = "2025-01-06"

// 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 @@ -72,6 +74,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
Loading