Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b715467
Add types for CMP announcement
zachaller Apr 25, 2022
d71e8a3
Reorg
zachaller Apr 25, 2022
58acff9
Merge branch 'parameterized-cmps-michael' of github.com:crenshaw-dev/…
zachaller Apr 25, 2022
3a29a5b
finish type
zachaller Apr 25, 2022
edd2207
First pass at working GetParametersAnnouncement
zachaller Apr 25, 2022
088ce0d
Typos
zachaller Apr 25, 2022
87bc81c
Make all fields optional
zachaller Apr 25, 2022
33388f7
Make sure response makes it to repo server
zachaller Apr 25, 2022
63a9f75
Refactor for testing
zachaller Apr 25, 2022
1ae56f6
values types for parameters
crenshaw-dev Apr 26, 2022
a92b81b
Merge pull request #7 from crenshaw-dev/parameterized-cmps-step1
crenshaw-dev Apr 26, 2022
be27448
Merge remote-tracking branch 'crenshaw-dev/parameterized-cmps-shared'…
crenshaw-dev Apr 26, 2022
c421f37
Merge pull request #8 from crenshaw-dev/parameterized-cmps-values
crenshaw-dev Apr 26, 2022
b782233
lint
crenshaw-dev Apr 26, 2022
89b67cb
send build env to param announcement gen
crenshaw-dev Apr 26, 2022
232c7a1
test parameter announcement
crenshaw-dev Apr 26, 2022
1830aa2
tests
crenshaw-dev Apr 26, 2022
1916148
environ tests
crenshaw-dev Apr 26, 2022
c2899de
Rename workdir to app dir
zachaller Apr 26, 2022
475d00c
Merge pull request #10 from crenshaw-dev/parameterized-cmps-rename
crenshaw-dev Apr 26, 2022
55a0de7
handle empty command, start ui work
crenshaw-dev Apr 26, 2022
18ea4ed
merge shared
crenshaw-dev Apr 26, 2022
8f9c9b8
fix order
crenshaw-dev Apr 27, 2022
da13d6f
fix map merging, make params read-only
crenshaw-dev Apr 27, 2022
a2d486a
merge shared
crenshaw-dev Apr 27, 2022
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
27 changes: 16 additions & 11 deletions cmpserver/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,9 @@ func (s *Service) GetParametersAnnouncement(stream apiclient.ConfigManagementPlu
}

func getParametersAnnouncement(ctx context.Context, appDir string, staticAnnouncements []Static, command Command) (*apiclient.ParametersAnnouncementResponse, error) {
var staticParamAnnouncements []*apiclient.ParameterAnnouncement
var announcements []*apiclient.ParameterAnnouncement
for _, static := range staticAnnouncements {
staticParamAnnouncements = append(staticParamAnnouncements, &apiclient.ParameterAnnouncement{
announcements = append(announcements, &apiclient.ParameterAnnouncement{
Name: static.Name,
Title: static.Title,
Tooltip: static.Tooltip,
Expand All @@ -347,19 +347,24 @@ func getParametersAnnouncement(ctx context.Context, appDir string, staticAnnounc
})
}

stdout, err := runCommand(ctx, command, appDir, os.Environ())
if err != nil {
return nil, fmt.Errorf("error executing dynamic parameter output command: %s", err)
}
if len(command.Command) > 0 {
stdout, err := runCommand(ctx, command, appDir, os.Environ())
if err != nil {
return nil, fmt.Errorf("error executing dynamic parameter output command: %s", err)
}

var dynamicParamAnnouncements []*apiclient.ParameterAnnouncement
err = json.Unmarshal([]byte(stdout), &dynamicParamAnnouncements)
if err != nil {
return nil, fmt.Errorf("error unmarshaling dynamic parameter output into ParametersAnnouncementResponse: %s", err)
var dynamicParamAnnouncements []*apiclient.ParameterAnnouncement
err = json.Unmarshal([]byte(stdout), &dynamicParamAnnouncements)
if err != nil {
return nil, fmt.Errorf("error unmarshaling dynamic parameter output into ParametersAnnouncementResponse: %s", err)
}

// dynamic goes first, because static should take precedence by being later.
announcements = append(dynamicParamAnnouncements, announcements...)
}

repoResponse := &apiclient.ParametersAnnouncementResponse{
ParameterAnnouncements: append(staticParamAnnouncements, dynamicParamAnnouncements...),
ParameterAnnouncements: announcements,
}
return repoResponse, nil
}
28 changes: 26 additions & 2 deletions cmpserver/plugin/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,20 @@ func Test_getParametersAnnouncement_empty_command(t *testing.T) {
assert.Equal(t, []*apiclient.ParameterAnnouncement{{Name: "static-a"}, {Name: "static-b"}}, res.ParameterAnnouncements)
}

func Test_getParametersAnnouncement_no_command(t *testing.T) {
staticYAML := `
- name: static-a
- name: static-b
`
static := &[]Static{}
err := yaml.Unmarshal([]byte(staticYAML), static)
require.NoError(t, err)
command := Command{}
res, err := getParametersAnnouncement(context.Background(), "", *static, command)
require.NoError(t, err)
assert.Equal(t, []*apiclient.ParameterAnnouncement{{Name: "static-a"}, {Name: "static-b"}}, res.ParameterAnnouncements)
}

func Test_getParametersAnnouncement_static_and_dynamic(t *testing.T) {
staticYAML := `
- name: static-a
Expand All @@ -261,10 +275,10 @@ func Test_getParametersAnnouncement_static_and_dynamic(t *testing.T) {
res, err := getParametersAnnouncement(context.Background(), "", *static, command)
require.NoError(t, err)
expected := []*apiclient.ParameterAnnouncement{
{Name: "static-a"},
{Name: "static-b"},
{Name: "dynamic-a"},
{Name: "dynamic-b"},
{Name: "static-a"},
{Name: "static-b"},
}
assert.Equal(t, expected, res.ParameterAnnouncements)
}
Expand All @@ -278,3 +292,13 @@ func Test_getParametersAnnouncement_invalid_json(t *testing.T) {
assert.Error(t, err)
assert.Contains(t, err.Error(), "unexpected end of JSON input")
}

func Test_getParametersAnnouncement_bad_command(t *testing.T) {
command := Command{
Command: []string{"exit"},
Args: []string{"1"},
}
_, err := getParametersAnnouncement(context.Background(), "", []Static{}, command)
assert.Error(t, err)
assert.Contains(t, err.Error(), "error executing dynamic parameter output command")
}
14 changes: 14 additions & 0 deletions test/cmp/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,17 @@ spec:
glob: "**/kustomization.yaml"
allowConcurrency: true
lockRepo: false
parameters:
static:
- name: string-param
string: value
- name: array-param
collectionType: array
array:
- value1
- value2
- name: map-param
collectionType: map
map:
key: value
key2: value2
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,36 @@ export const ApplicationParameters = (props: {
view: app.spec.source.plugin && (app.spec.source.plugin.env || []).map(i => `${i.name}='${i.value}'`).join(' '),
edit: (formApi: FormApi) => <FormField field='spec.source.plugin.env' formApi={formApi} component={ArrayInputField} />
});
if (props.details.plugin.parametersAnnouncement) {
for (const announcement of props.details.plugin.parametersAnnouncement) {
const liveParam = app.spec.source.plugin.parameters?.find(param => param.name === announcement.name);
if (announcement.collectionType === undefined || announcement.collectionType === '' || announcement.collectionType === 'string') {
attributes.push({
title: announcement.title ?? announcement.name,
view: liveParam?.string || announcement.string,
edit: () => liveParam?.string || announcement.string
});
} else if (announcement.collectionType === 'array') {
attributes.push({
title: announcement.title ?? announcement.name,
view: (liveParam?.array || announcement.array || []).join(' '),
edit: () => (liveParam?.array || announcement.array || []).join(' ')
});
} else if (announcement.collectionType === 'map') {
const entries = concatMaps(announcement.map, liveParam?.map).entries();
attributes.push({
title: announcement.title ?? announcement.name,
view: Array.from(entries)
.map(([key, value]) => `${key}='${value}'`)
.join(' '),
edit: () =>
Array.from(entries)
.map(([key, value]) => `${key}='${value}'`)
.join(' ')
});
}
}
}
} else if (props.details.type === 'Directory') {
const directory = app.spec.source.directory || ({} as ApplicationSourceDirectory);
attributes.push({
Expand Down Expand Up @@ -344,3 +374,16 @@ export const ApplicationParameters = (props: {
/>
);
};

// concatMaps merges two maps. Later args take precedence where there's a key conflict.
function concatMaps(...maps: (Map<string, string> | null)[]): Map<string, string> {
const newMap = new Map<string, string>();
for (const map of maps) {
if (map) {
for (const entry of Object.entries(map)) {
newMap.set(entry[0], entry[1]);
}
}
}
return newMap;
}
21 changes: 21 additions & 0 deletions ui/src/app/shared/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@ export interface EnvEntry {
export interface ApplicationSourcePlugin {
name: string;
env: EnvEntry[];
parameters?: Parameter[];
}

export interface Parameter {
name: string;
string?: string;
array?: string[];
map?: Map<string, string>;
}

export interface JsonnetVar {
Expand Down Expand Up @@ -579,6 +587,19 @@ export interface KustomizeAppSpec {
export interface PluginAppSpec {
name: string;
env: EnvEntry[];
parametersAnnouncement?: ParameterAnnouncement[];
}

export interface ParameterAnnouncement {
name?: string;
title?: string;
tooltip?: string;
required?: boolean;
itemType?: string;
collectionType?: string;
string?: string;
array?: string[];
map?: Map<string, string>;
}

export interface ObjectReference {
Expand Down