Skip to content

Commit 2cba9e0

Browse files
authored
feat(controlplane): soft-delete CAS backends (#242)
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
1 parent d6e7b66 commit 2cba9e0

25 files changed

Lines changed: 1034 additions & 111 deletions

app/cli/cmd/casbackend.go

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
package cmd
1717

1818
import (
19+
"fmt"
20+
21+
"github.com/chainloop-dev/chainloop/app/cli/internal/action"
1922
"github.com/spf13/cobra"
2023
)
2124

@@ -25,7 +28,7 @@ func newCASBackendCmd() *cobra.Command {
2528
Short: "Operations on Artifact CAS backends",
2629
}
2730

28-
cmd.AddCommand(newCASBackendListCmd(), newCASBackendAddCmd(), newCASBackendUpdateCmd())
31+
cmd.AddCommand(newCASBackendListCmd(), newCASBackendAddCmd(), newCASBackendUpdateCmd(), newCASBackendDeleteCmd())
2932
return cmd
3033
}
3134

@@ -54,3 +57,61 @@ func newCASBackendUpdateCmd() *cobra.Command {
5457
cmd.AddCommand(newCASBackendUpdateOCICmd())
5558
return cmd
5659
}
60+
61+
// confirmDefaultCASBackendOverride asks the user to confirm the override of the default CAS backend
62+
// in the event that there is one already set and its not the same as the one we are setting
63+
func confirmDefaultCASBackendOverride(actionOpts *action.ActionsOpts, id string) (bool, error) {
64+
// get existing backends
65+
backends, err := action.NewCASBackendList(actionOpts).Run()
66+
if err != nil {
67+
return false, fmt.Errorf("failed to list existing CAS backends: %w", err)
68+
}
69+
70+
// Find the default
71+
var defaultB *action.CASBackendItem
72+
for _, b := range backends {
73+
if b.Default {
74+
defaultB = b
75+
break
76+
}
77+
}
78+
79+
// If there is none or there is but it's the same as the one we are setting, we are ok
80+
if defaultB == nil || (id != "" && id == defaultB.ID) {
81+
return true, nil
82+
}
83+
84+
// Ask the user to confirm the override
85+
return confirmationPrompt("You are changing the default CAS backend in your organization"), nil
86+
}
87+
88+
// If we are removing the default we confirm too
89+
func confirmDefaultCASBackendRemoval(actionOpts *action.ActionsOpts, id string) (bool, error) {
90+
return confirmDefaultCASBackendUnset(id, "You are deleting the default CAS backend.", actionOpts)
91+
}
92+
93+
func confirmDefaultCASBackendUnset(id, msg string, actionOpts *action.ActionsOpts) (bool, error) {
94+
// get existing backends
95+
backends, err := action.NewCASBackendList(actionOpts).Run()
96+
if err != nil {
97+
return false, fmt.Errorf("failed to list existing CAS backends: %w", err)
98+
}
99+
100+
for _, b := range backends {
101+
// We are removing ourselves as the default, ask the user to confirm
102+
if b.Default && b.ID == id {
103+
return confirmationPrompt(msg), nil
104+
}
105+
}
106+
107+
return true, nil
108+
}
109+
110+
// y/n confirmation prompt
111+
func confirmationPrompt(msg string) bool {
112+
fmt.Printf("%s\nPlease confirm to continue y/N\n", msg)
113+
var gotChallenge string
114+
fmt.Scanln(&gotChallenge)
115+
116+
return gotChallenge == "y" || gotChallenge == "Y"
117+
}

app/cli/cmd/casbackend_add_oci.go

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
package cmd
1717

1818
import (
19-
"fmt"
20-
2119
"github.com/chainloop-dev/chainloop/app/cli/internal/action"
2220
"github.com/go-kratos/kratos/v2/log"
2321
"github.com/spf13/cobra"
@@ -80,35 +78,3 @@ func newCASBackendAddOCICmd() *cobra.Command {
8078
cobra.CheckErr(err)
8179
return cmd
8280
}
83-
84-
// confirmDefaultCASBackendOverride asks the user to confirm the override of the default CAS backend
85-
// in the event that there is one already set and its not the same as the one we are setting
86-
func confirmDefaultCASBackendOverride(actionOpts *action.ActionsOpts, id string) (bool, error) {
87-
// get existing backends
88-
backends, err := action.NewCASBackendList(actionOpts).Run()
89-
if err != nil {
90-
return false, fmt.Errorf("failed to list existing CAS backends: %w", err)
91-
}
92-
93-
// Find the default
94-
var defaultB *action.CASBackendItem
95-
for _, b := range backends {
96-
if b.Default {
97-
defaultB = b
98-
break
99-
}
100-
}
101-
102-
// If there is none or there is but it's the same as the one we are setting, we are ok
103-
if defaultB == nil || (id != "" && id == defaultB.ID) {
104-
return true, nil
105-
}
106-
107-
// Ask the user to confirm the override
108-
fmt.Println("There is already a default CAS backend in your organization.\nPlease confirm to override y/N: ")
109-
var gotChallenge string
110-
fmt.Scanln(&gotChallenge)
111-
112-
// If the user does not confirm, we are done
113-
return gotChallenge == "y" || gotChallenge == "Y", nil
114-
}

app/cli/cmd/casbackend_delete.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//
2+
// Copyright 2023 The Chainloop Authors.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
package cmd
17+
18+
import (
19+
"github.com/chainloop-dev/chainloop/app/cli/internal/action"
20+
"github.com/go-kratos/kratos/v2/log"
21+
"github.com/spf13/cobra"
22+
)
23+
24+
func newCASBackendDeleteCmd() *cobra.Command {
25+
var backendID string
26+
27+
cmd := &cobra.Command{
28+
Use: "delete",
29+
Aliases: []string{"rm"},
30+
Short: "Delete a CAS Backend from your organization",
31+
RunE: func(cmd *cobra.Command, args []string) error {
32+
if confirmed, err := confirmDefaultCASBackendRemoval(actionOpts, backendID); err != nil {
33+
return err
34+
} else if !confirmed {
35+
log.Info("Aborting...")
36+
return nil
37+
}
38+
39+
if err := action.NewCASBackendDelete(actionOpts).Run(backendID); err != nil {
40+
return err
41+
}
42+
43+
logger.Info().Msg("Backend deleted")
44+
45+
return nil
46+
},
47+
}
48+
49+
cmd.Flags().StringVar(&backendID, "id", "", "CAS Backend ID")
50+
cobra.CheckErr(cmd.MarkFlagRequired("id"))
51+
return cmd
52+
}

app/cli/cmd/casbackend_update_oci.go

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
package cmd
1717

1818
import (
19-
"fmt"
20-
2119
"github.com/chainloop-dev/chainloop/app/cli/internal/action"
2220
"github.com/go-kratos/kratos/v2/log"
2321
"github.com/spf13/cobra"
@@ -45,8 +43,9 @@ func newCASBackendUpdateOCICmd() *cobra.Command {
4543
log.Info("Aborting...")
4644
return nil
4745
}
48-
} else { // If we are removing the default we ask for confirmation too
49-
if confirmed, err := confirmDefaultCASBackendRemoval(actionOpts, backendID); err != nil {
46+
} else {
47+
// If we are removing the default we ask for confirmation too
48+
if confirmed, err := confirmDefaultCASBackendUnset(backendID, "You are setting the default CAS backend to false", actionOpts); err != nil {
5049
return err
5150
} else if !confirmed {
5251
log.Info("Aborting...")
@@ -88,29 +87,3 @@ func newCASBackendUpdateOCICmd() *cobra.Command {
8887
cmd.Flags().StringVarP(&password, "password", "p", "", "registry password")
8988
return cmd
9089
}
91-
92-
// If we are removing the default we confirm too
93-
func confirmDefaultCASBackendRemoval(actionOpts *action.ActionsOpts, id string) (bool, error) {
94-
// get existing backends
95-
backends, err := action.NewCASBackendList(actionOpts).Run()
96-
if err != nil {
97-
return false, fmt.Errorf("failed to list existing CAS backends: %w", err)
98-
}
99-
100-
for _, b := range backends {
101-
// We are removing ourselves as the default, ask the user to confirm
102-
if b.Default && b.ID == id {
103-
// Ask the user to confirm the override
104-
fmt.Println("This is the default CAS backend and your are setting default=false.\nPlease confirm to continue y/N: ")
105-
var gotChallenge string
106-
fmt.Scanln(&gotChallenge)
107-
108-
// If the user does not confirm, we are done
109-
if gotChallenge != "y" && gotChallenge != "Y" {
110-
return false, nil
111-
}
112-
}
113-
}
114-
115-
return true, nil
116-
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// Copyright 2023 The Chainloop Authors.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
package action
17+
18+
import (
19+
"context"
20+
21+
pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1"
22+
)
23+
24+
type CASBackendDelete struct {
25+
cfg *ActionsOpts
26+
}
27+
28+
func NewCASBackendDelete(cfg *ActionsOpts) *CASBackendDelete {
29+
return &CASBackendDelete{cfg}
30+
}
31+
32+
func (action *CASBackendDelete) Run(id string) error {
33+
client := pb.NewCASBackendServiceClient(action.cfg.CPConnection)
34+
_, err := client.Delete(context.Background(), &pb.CASBackendServiceDeleteRequest{
35+
Id: id,
36+
})
37+
38+
return err
39+
}

0 commit comments

Comments
 (0)