-
Notifications
You must be signed in to change notification settings - Fork 11
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
cli: add support for environment tags #345
Changes from 8 commits
fb4c819
b0d2dc0
c9b1176
0adc94b
f8e942f
043cd27
9fa4f3e
3be1962
ede7b8a
27a6392
b3bc337
ff36b34
74b1079
663f752
1138532
2e20f2a
1f19a6f
70ea48f
d6b14b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -258,8 +258,9 @@ type testEnvironmentRevision struct { | |
} | ||
|
||
type testEnvironment struct { | ||
revisions []*testEnvironmentRevision | ||
tags map[string]int | ||
revisions []*testEnvironmentRevision | ||
revisionTags map[string]int | ||
tags map[string]string | ||
} | ||
|
||
func (env *testEnvironment) latest() *testEnvironmentRevision { | ||
|
@@ -365,7 +366,7 @@ func (c *testPulumiClient) getEnvironment(orgName, envName, version string) (*te | |
} | ||
revision = int(rev) | ||
} else { | ||
rev, ok := env.tags[version] | ||
rev, ok := env.revisionTags[version] | ||
if !ok { | ||
return nil, nil, errors.New("not found") | ||
} | ||
|
@@ -496,8 +497,9 @@ func (c *testPulumiClient) CreateEnvironment(ctx context.Context, orgName, envNa | |
return errors.New("already exists") | ||
} | ||
c.environments[name] = &testEnvironment{ | ||
revisions: []*testEnvironmentRevision{{}}, | ||
tags: map[string]int{"latest": 0}, | ||
revisions: []*testEnvironmentRevision{{}}, | ||
revisionTags: map[string]int{"latest": 0}, | ||
tags: map[string]string{}, | ||
} | ||
return nil | ||
} | ||
|
@@ -568,10 +570,10 @@ func (c *testPulumiClient) UpdateEnvironmentWithRevision( | |
yaml: yaml, | ||
tag: base64.StdEncoding.EncodeToString(h.Sum(nil)), | ||
}) | ||
env.tags["latest"] = revisionNumber | ||
env.revisionTags["latest"] = revisionNumber | ||
} | ||
|
||
return diags, env.tags["latest"], err | ||
return diags, env.revisionTags["latest"], err | ||
} | ||
|
||
func (c *testPulumiClient) DeleteEnvironment(ctx context.Context, orgName, envName string) error { | ||
|
@@ -627,6 +629,86 @@ func (c *testPulumiClient) GetOpenProperty(ctx context.Context, orgName, envName | |
return nil, errors.New("NYI") | ||
} | ||
|
||
func (c *testPulumiClient) GetEnvironmentTag( | ||
ctx context.Context, | ||
orgName, envName, key string, | ||
) (*client.EnvironmentTag, error) { | ||
ts := time.Now() | ||
return &client.EnvironmentTag{ | ||
ID: "1234", | ||
Name: "team", | ||
Value: "pulumi", | ||
Created: ts, | ||
Modified: ts, | ||
EditorLogin: "pulumipus", | ||
EditorName: "pulumipus", | ||
}, nil | ||
} | ||
|
||
func (c *testPulumiClient) ListEnvironmentTags( | ||
ctx context.Context, | ||
orgName string, | ||
envName string, | ||
options client.ListEnvironmentTagsOptions, | ||
) ([]*client.EnvironmentTag, string, error) { | ||
ts := time.Now() | ||
return []*client.EnvironmentTag{ | ||
{ | ||
ID: "1234", | ||
Name: "team", | ||
Value: "pulumi", | ||
Created: ts, | ||
Modified: ts, | ||
EditorLogin: "pulumipus", | ||
EditorName: "pulumipus", | ||
}, | ||
}, "0", nil | ||
} | ||
|
||
func (c *testPulumiClient) CreateEnvironmentTag( | ||
ctx context.Context, | ||
orgName, envName, key, value string, | ||
) (*client.EnvironmentTag, error) { | ||
ts := time.Now() | ||
return &client.EnvironmentTag{ | ||
ID: "1234", | ||
Name: key, | ||
Value: value, | ||
Created: ts, | ||
Modified: ts, | ||
EditorLogin: "pulumipus", | ||
EditorName: "pulumipus", | ||
}, nil | ||
} | ||
|
||
func (c *testPulumiClient) UpdateEnvironmentTag( | ||
ctx context.Context, | ||
orgName, envName, currentKey, currentValue, newKey, newValue string, | ||
) (*client.EnvironmentTag, error) { | ||
name := newKey | ||
if name == "" { | ||
name = currentKey | ||
} | ||
value := newValue | ||
if value == "" { | ||
value = currentValue | ||
} | ||
ts := time.Now() | ||
return &client.EnvironmentTag{ | ||
ID: "1234", | ||
Name: name, | ||
Value: value, | ||
Created: ts, | ||
Modified: ts, | ||
EditorLogin: "pulumipus", | ||
EditorName: "pulumipus", | ||
}, nil | ||
} | ||
|
||
func (c *testPulumiClient) DeleteEnvironmentTag(ctx context.Context, orgName, envName, tagName string) error { | ||
return nil | ||
} | ||
|
||
func (c *testPulumiClient) GetEnvironmentRevision( | ||
ctx context.Context, | ||
orgName string, | ||
|
@@ -733,11 +815,11 @@ func (c *testPulumiClient) CreateEnvironmentRevisionTag( | |
return errors.New("not found") | ||
} | ||
|
||
if _, ok := env.tags[tagName]; ok { | ||
if _, ok := env.revisionTags[tagName]; ok { | ||
return errors.New("already exists") | ||
} | ||
|
||
env.tags[tagName] = rev | ||
env.revisionTags[tagName] = rev | ||
return nil | ||
} | ||
|
||
|
@@ -753,7 +835,7 @@ func (c *testPulumiClient) GetEnvironmentRevisionTag( | |
return nil, err | ||
} | ||
|
||
rev, ok := env.tags[tagName] | ||
rev, ok := env.revisionTags[tagName] | ||
if !ok { | ||
return nil, &apitype.ErrorResponse{Code: http.StatusNotFound} | ||
} | ||
|
@@ -781,11 +863,11 @@ func (c *testPulumiClient) UpdateEnvironmentRevisionTag( | |
return errors.New("not found") | ||
} | ||
|
||
if _, ok := env.tags[tagName]; !ok { | ||
if _, ok := env.revisionTags[tagName]; !ok { | ||
return &apitype.ErrorResponse{Code: http.StatusNotFound} | ||
} | ||
|
||
env.tags[tagName] = rev | ||
env.revisionTags[tagName] = rev | ||
return nil | ||
} | ||
|
||
|
@@ -801,11 +883,11 @@ func (c *testPulumiClient) DeleteEnvironmentRevisionTag( | |
return err | ||
} | ||
|
||
if _, ok := env.tags[tagName]; !ok { | ||
if _, ok := env.revisionTags[tagName]; !ok { | ||
return errors.New("not found") | ||
} | ||
|
||
delete(env.tags, tagName) | ||
delete(env.revisionTags, tagName) | ||
return nil | ||
} | ||
|
||
|
@@ -821,10 +903,10 @@ func (c *testPulumiClient) ListEnvironmentRevisionTags( | |
return nil, err | ||
} | ||
|
||
names := maps.Keys(env.tags) | ||
names := maps.Keys(env.revisionTags) | ||
slices.Sort(names) | ||
return fx.ToSlice(fx.FMap(fx.IterSlice(names), func(name string) (client.EnvironmentRevisionTag, bool) { | ||
return client.EnvironmentRevisionTag{Name: name, Revision: env.tags[name]}, name > options.After | ||
return client.EnvironmentRevisionTag{Name: name, Revision: env.revisionTags[name]}, name > options.After | ||
})), nil | ||
} | ||
|
||
|
@@ -910,8 +992,22 @@ func (c *testExec) runScript(script string, cmd *exec.Cmd) error { | |
esc.SetIn(hc.Stdin) | ||
esc.SetOut(hc.Stdout) | ||
esc.SetErr(hc.Stderr) | ||
if err := esc.Execute(); err != nil { | ||
|
||
ctx, cancel := context.WithTimeout(ctx, 5*time.Second) | ||
esc.SetContext(ctx) | ||
defer cancel() | ||
|
||
ch := make(chan error, 1) | ||
go func() { | ||
ch <- esc.Execute() | ||
}() | ||
select { | ||
case <-ctx.Done(): | ||
return interp.NewExitStatus(1) | ||
dschaller marked this conversation as resolved.
Show resolved
Hide resolved
|
||
case result := <-ch: | ||
if result != nil { | ||
return interp.NewExitStatus(1) | ||
} | ||
} | ||
return nil | ||
} | ||
|
@@ -974,6 +1070,10 @@ type cliTestcaseRevisions struct { | |
Revisions []cliTestcaseRevision `yaml:"revisions,omitempty"` | ||
} | ||
|
||
type cliTestcaseEnvironmentTags struct { | ||
Tags map[string]string `yaml:"tags,omitempty"` | ||
} | ||
|
||
type cliTestcaseYAML struct { | ||
Parent string `yaml:"parent,omitempty"` | ||
|
||
|
@@ -1030,8 +1130,14 @@ func loadTestcase(path string) (*cliTestcaseYAML, *cliTestcase, error) { | |
revisions = cliTestcaseRevisions{Revisions: []cliTestcaseRevision{{YAML: env}}} | ||
} | ||
|
||
var tags cliTestcaseEnvironmentTags | ||
envTags := map[string]string{} | ||
if err := env.Decode(&tags); err == nil { | ||
envTags = tags.Tags | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that this is what we want. I think that we should add a new field to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry do you mean moving the existing tags to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah--it looks like as written an environment can either contain a set of tags or a set of revisions (unless I'm reading it wrong?). Feels like instead we want There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah yeah I follow you - will update There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually thinking more about this I feel like it makes sense to keep these at the top level on the env since revision tags must be unique across all revisions. I did adjust the interface of revision tags though to allow for passing a list instead of a single value since that mirrors what the API supports |
||
|
||
envRevisions := []*testEnvironmentRevision{{number: 1}} | ||
tags := map[string]int{} | ||
revisionTags := map[string]int{} | ||
for _, rev := range revisions.Revisions { | ||
bytes, err := yaml.Marshal(rev.YAML) | ||
if err != nil { | ||
|
@@ -1054,18 +1160,19 @@ func loadTestcase(path string) (*cliTestcaseYAML, *cliTestcase, error) { | |
}) | ||
|
||
if rev.Tag != "" { | ||
if _, ok := tags[rev.Tag]; ok || rev.Tag == "latest" { | ||
if _, ok := revisionTags[rev.Tag]; ok || rev.Tag == "latest" { | ||
return nil, nil, fmt.Errorf("duplicate tag %q", rev.Tag) | ||
} | ||
tags[rev.Tag] = revisionNumber | ||
revisionTags[rev.Tag] = revisionNumber | ||
envRevisions[revisionNumber-1].tag = rev.Tag | ||
} | ||
} | ||
tags["latest"] = len(envRevisions) | ||
revisionTags["latest"] = len(envRevisions) | ||
|
||
environments[k] = &testEnvironment{ | ||
revisions: envRevisions, | ||
tags: tags, | ||
revisions: envRevisions, | ||
revisionTags: revisionTags, | ||
tags: envTags, | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add some tests?
If you add a new file in
cli/testdata
, it will be automatically picked up by the test harness:run
section contains the command(s) to runenvironments
section contains the environments to define for testingOnce you've filled in those two sections, you can generate the
stdout
/stderr
sections by runningPULUMI_ACCEPT=1 go test ./cmd/esc/cli
from the repository root.You'll likely need to revert changes to
cmd/esc/cli/testdata/env-login-gh100.yaml
andcmd/esc/cli/testdata/env-set.yaml
as the regeneration process makes undesirable formatting changes to those files.