diff --git a/cmd/agola/cmd/projectgroupsecretlist.go b/cmd/agola/cmd/projectgroupsecretlist.go new file mode 100644 index 0000000..4198a05 --- /dev/null +++ b/cmd/agola/cmd/projectgroupsecretlist.go @@ -0,0 +1,41 @@ +// Copyright 2019 Sorint.lab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "github.com/spf13/cobra" +) + +var cmdProjectGroupSecretList = &cobra.Command{ + Use: "list", + Short: "list project group secrets", + Run: func(cmd *cobra.Command, args []string) { + if err := secretList(cmd, "projectgroup", args); err != nil { + log.Fatalf("err: %v", err) + } + }, +} + +func init() { + flags := cmdProjectGroupSecretList.Flags() + + flags.StringVar(&secretListOpts.parentRef, "projectgroup", "", "project group id or full path") + + if err := cmdProjectGroupSecretList.MarkFlagRequired("projectgroup"); err != nil { + log.Fatal(err) + } + + cmdProjectGroupSecret.AddCommand(cmdProjectGroupSecretList) +} diff --git a/cmd/agola/cmd/projectgroupvariablelist.go b/cmd/agola/cmd/projectgroupvariablelist.go new file mode 100644 index 0000000..cad80a3 --- /dev/null +++ b/cmd/agola/cmd/projectgroupvariablelist.go @@ -0,0 +1,41 @@ +// Copyright 2019 Sorint.lab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "github.com/spf13/cobra" +) + +var cmdProjectGroupVariableList = &cobra.Command{ + Use: "list", + Short: "list project group variables", + Run: func(cmd *cobra.Command, args []string) { + if err := variableList(cmd, "projectgroup", args); err != nil { + log.Fatalf("err: %v", err) + } + }, +} + +func init() { + flags := cmdProjectGroupVariableList.Flags() + + flags.StringVar(&variableListOpts.parentRef, "projectgroup", "", "project group id or full path") + + if err := cmdProjectGroupVariableList.MarkFlagRequired("projectgroup"); err != nil { + log.Fatal(err) + } + + cmdProjectGroupVariable.AddCommand(cmdProjectGroupVariableList) +} diff --git a/cmd/agola/cmd/projectsecretlist.go b/cmd/agola/cmd/projectsecretlist.go new file mode 100644 index 0000000..8e107bd --- /dev/null +++ b/cmd/agola/cmd/projectsecretlist.go @@ -0,0 +1,89 @@ +// Copyright 2019 Sorint.lab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "context" + "encoding/json" + "fmt" + + gwapitypes "agola.io/agola/services/gateway/api/types" + gwclient "agola.io/agola/services/gateway/client" + + "github.com/spf13/cobra" + errors "golang.org/x/xerrors" +) + +var cmdProjectSecretList = &cobra.Command{ + Use: "list", + Short: "list project secrets", + Run: func(cmd *cobra.Command, args []string) { + if err := secretList(cmd, "project", args); err != nil { + log.Fatalf("err: %v", err) + } + }, +} + +type secretListOptions struct { + parentRef string +} + +var secretListOpts secretListOptions + +func init() { + flags := cmdProjectSecretList.Flags() + + flags.StringVar(&secretListOpts.parentRef, "project", "", "project id or full path") + + if err := cmdProjectSecretList.MarkFlagRequired("project"); err != nil { + log.Fatal(err) + } + + cmdProjectSecret.AddCommand(cmdProjectSecretList) +} + +func secretList(cmd *cobra.Command, ownertype string, args []string) error { + if err := printSecrets(ownertype, fmt.Sprintf("%s secrets", ownertype), false, false); err != nil { + return err + } + if err := printSecrets(ownertype, "All secrets (local and inherited)", true, true); err != nil { + return err + } + return nil +} + +func printSecrets(ownertype, description string, tree, removeoverridden bool) error { + + var err error + var secrets []*gwapitypes.SecretResponse + + gwclient := gwclient.NewClient(gatewayURL, token) + + switch ownertype { + case "project": + secrets, _, err = gwclient.GetProjectSecrets(context.TODO(), secretListOpts.parentRef, tree, removeoverridden) + case "projectgroup": + secrets, _, err = gwclient.GetProjectGroupSecrets(context.TODO(), secretListOpts.parentRef, tree, removeoverridden) + } + if err != nil { + return errors.Errorf("failed to list %s secrets: %w", ownertype, err) + } + prettyJSON, err := json.MarshalIndent(secrets, "", "\t") + if err != nil { + return errors.Errorf("failed to convert %s secrets to json: %w", ownertype, err) + } + fmt.Printf("%s:\n%s\n", description, string(prettyJSON)) + return nil +} diff --git a/cmd/agola/cmd/projectvariablelist.go b/cmd/agola/cmd/projectvariablelist.go new file mode 100644 index 0000000..e2450be --- /dev/null +++ b/cmd/agola/cmd/projectvariablelist.go @@ -0,0 +1,89 @@ +// Copyright 2019 Sorint.lab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "context" + "encoding/json" + "fmt" + + gwapitypes "agola.io/agola/services/gateway/api/types" + gwclient "agola.io/agola/services/gateway/client" + + "github.com/spf13/cobra" + errors "golang.org/x/xerrors" +) + +var cmdProjectVariableList = &cobra.Command{ + Use: "list", + Short: "list project variables", + Run: func(cmd *cobra.Command, args []string) { + if err := variableList(cmd, "project", args); err != nil { + log.Fatalf("err: %v", err) + } + }, +} + +type variableListOptions struct { + parentRef string +} + +var variableListOpts variableListOptions + +func init() { + flags := cmdProjectVariableList.Flags() + + flags.StringVar(&variableListOpts.parentRef, "project", "", "project id or full path") + + if err := cmdProjectVariableList.MarkFlagRequired("project"); err != nil { + log.Fatal(err) + } + + cmdProjectVariable.AddCommand(cmdProjectVariableList) +} + +func variableList(cmd *cobra.Command, ownertype string, args []string) error { + if err := printVariables(ownertype, fmt.Sprintf("%s variables", ownertype), false, false); err != nil { + return err + } + if err := printVariables(ownertype, "All variables (local and inherited)", true, true); err != nil { + return err + } + return nil +} + +func printVariables(ownertype, description string, tree, removeoverridden bool) error { + + var err error + var variables []*gwapitypes.VariableResponse + + gwclient := gwclient.NewClient(gatewayURL, token) + + switch ownertype { + case "project": + variables, _, err = gwclient.GetProjectVariables(context.TODO(), variableListOpts.parentRef, tree, removeoverridden) + case "projectgroup": + variables, _, err = gwclient.GetProjectGroupVariables(context.TODO(), variableListOpts.parentRef, tree, removeoverridden) + } + if err != nil { + return errors.Errorf("failed to list %s variables: %w", ownertype, err) + } + prettyJSON, err := json.MarshalIndent(variables, "", "\t") + if err != nil { + return errors.Errorf("failed to convert %s variables to json: %w", ownertype, err) + } + fmt.Printf("%s:\n%s\n", description, string(prettyJSON)) + return nil +} diff --git a/services/gateway/client/client.go b/services/gateway/client/client.go index 7ddff57..666d7d9 100644 --- a/services/gateway/client/client.go +++ b/services/gateway/client/client.go @@ -186,6 +186,19 @@ func (c *Client) DeleteProjectGroupSecret(ctx context.Context, projectGroupRef, return c.getResponse(ctx, "DELETE", path.Join("/projectgroups", url.PathEscape(projectGroupRef), "secrets", secretName), nil, jsonContent, nil) } +func (c *Client) GetProjectGroupSecrets(ctx context.Context, projectRef string, tree, removeoverridden bool) ([]*gwapitypes.SecretResponse, *http.Response, error) { + secrets := []*gwapitypes.SecretResponse{} + q := url.Values{} + if tree { + q.Add("tree", "") + } + if removeoverridden { + q.Add("removeoverridden", "") + } + resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projectgroups/%s/secrets", url.PathEscape(projectRef)), q, jsonContent, nil, &secrets) + return secrets, resp, err +} + func (c *Client) CreateProjectSecret(ctx context.Context, projectRef string, req *gwapitypes.CreateSecretRequest) (*gwapitypes.SecretResponse, *http.Response, error) { reqj, err := json.Marshal(req) if err != nil { @@ -212,6 +225,19 @@ func (c *Client) DeleteProjectSecret(ctx context.Context, projectRef, secretName return c.getResponse(ctx, "DELETE", path.Join("/projects", url.PathEscape(projectRef), "secrets", secretName), nil, jsonContent, nil) } +func (c *Client) GetProjectSecrets(ctx context.Context, projectRef string, tree, removeoverridden bool) ([]*gwapitypes.SecretResponse, *http.Response, error) { + secrets := []*gwapitypes.SecretResponse{} + q := url.Values{} + if tree { + q.Add("tree", "") + } + if removeoverridden { + q.Add("removeoverridden", "") + } + resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projects/%s/secrets", url.PathEscape(projectRef)), q, jsonContent, nil, &secrets) + return secrets, resp, err +} + func (c *Client) CreateProjectGroupVariable(ctx context.Context, projectGroupRef string, req *gwapitypes.CreateVariableRequest) (*gwapitypes.VariableResponse, *http.Response, error) { reqj, err := json.Marshal(req) if err != nil { @@ -238,6 +264,19 @@ func (c *Client) DeleteProjectGroupVariable(ctx context.Context, projectGroupRef return c.getResponse(ctx, "DELETE", path.Join("/projectgroups", url.PathEscape(projectGroupRef), "variables", variableName), nil, jsonContent, nil) } +func (c *Client) GetProjectGroupVariables(ctx context.Context, projectRef string, tree, removeoverridden bool) ([]*gwapitypes.VariableResponse, *http.Response, error) { + variables := []*gwapitypes.VariableResponse{} + q := url.Values{} + if tree { + q.Add("tree", "") + } + if removeoverridden { + q.Add("removeoverridden", "") + } + resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projectgroups/%s/variables", url.PathEscape(projectRef)), q, jsonContent, nil, &variables) + return variables, resp, err +} + func (c *Client) CreateProjectVariable(ctx context.Context, projectRef string, req *gwapitypes.CreateVariableRequest) (*gwapitypes.VariableResponse, *http.Response, error) { reqj, err := json.Marshal(req) if err != nil { @@ -264,6 +303,19 @@ func (c *Client) DeleteProjectVariable(ctx context.Context, projectRef, variable return c.getResponse(ctx, "DELETE", path.Join("/projects", url.PathEscape(projectRef), "variables", variableName), nil, jsonContent, nil) } +func (c *Client) GetProjectVariables(ctx context.Context, projectRef string, tree, removeoverridden bool) ([]*gwapitypes.VariableResponse, *http.Response, error) { + variables := []*gwapitypes.VariableResponse{} + q := url.Values{} + if tree { + q.Add("tree", "") + } + if removeoverridden { + q.Add("removeoverridden", "") + } + resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projects/%s/variables", url.PathEscape(projectRef)), q, jsonContent, nil, &variables) + return variables, resp, err +} + func (c *Client) DeleteProject(ctx context.Context, projectRef string) (*http.Response, error) { return c.getResponse(ctx, "DELETE", fmt.Sprintf("/projects/%s", url.PathEscape(projectRef)), nil, jsonContent, nil) }