Skip to content

Commit fc04f06

Browse files
authored
feat(controlplane): leave organization (#452)
Signed-off-by: Miguel Martinez Trivino <[email protected]>
1 parent ab80861 commit fc04f06

File tree

18 files changed

+948
-178
lines changed

18 files changed

+948
-178
lines changed

app/cli/cmd/organization.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func newOrganizationCmd() *cobra.Command {
3131
newOrganizationCreateCmd(),
3232
newOrganizationUpdateCmd(),
3333
newOrganizationSet(),
34+
newOrganizationLeaveCmd(),
3435
newOrganizationDescribeCmd(),
3536
newOrganizationInvitationCmd(),
3637
)

app/cli/cmd/organization_leave.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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+
"context"
20+
"fmt"
21+
22+
"github.com/chainloop-dev/chainloop/app/cli/internal/action"
23+
"github.com/spf13/cobra"
24+
)
25+
26+
// Get the membership entry associated to the current user for the given organization
27+
func membershipFromOrg(orgID string) (*action.MembershipItem, error) {
28+
memberships, err := action.NewMembershipList(actionOpts).Run()
29+
if err != nil {
30+
return nil, fmt.Errorf("listing memberships: %w", err)
31+
}
32+
33+
for _, m := range memberships {
34+
if m.Org.ID == orgID {
35+
return m, nil
36+
}
37+
}
38+
39+
return nil, fmt.Errorf("organization %s not found", orgID)
40+
}
41+
42+
func newOrganizationLeaveCmd() *cobra.Command {
43+
var orgID string
44+
cmd := &cobra.Command{
45+
Use: "leave",
46+
Short: "leave an organization",
47+
RunE: func(cmd *cobra.Command, args []string) error {
48+
// To find the membership ID, we need to iterate and filter by org
49+
membership, err := membershipFromOrg(orgID)
50+
if err != nil {
51+
return fmt.Errorf("getting membership: %w", err)
52+
} else if membership == nil {
53+
return fmt.Errorf("organization %s not found", orgID)
54+
}
55+
56+
fmt.Printf("You are about to leave the organization %q\n", membership.Org.Name)
57+
58+
// Ask for confirmation
59+
if err := confirmDeletion(); err != nil {
60+
return err
61+
}
62+
63+
// Membership deletion
64+
if err := action.NewMembershipDelete(actionOpts).Run(context.Background(), membership.ID); err != nil {
65+
return fmt.Errorf("deleting membership: %w", err)
66+
}
67+
68+
logger.Info().Msg("Membership deleted")
69+
return nil
70+
},
71+
}
72+
73+
cmd.Flags().StringVar(&orgID, "id", "", "organization ID to leave")
74+
cobra.CheckErr(cmd.MarkFlagRequired("id"))
75+
return cmd
76+
}

app/cli/cmd/organization_set.go

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,15 @@ func newOrganizationSet() *cobra.Command {
2929
Use: "set",
3030
Short: "Set the current organization associated with this user",
3131
RunE: func(cmd *cobra.Command, args []string) error {
32-
// To change the current organization, we need to find the membership ID
33-
memberships, err := action.NewMembershipList(actionOpts).Run()
32+
// To find the membership ID, we need to iterate and filter by org
33+
membership, err := membershipFromOrg(orgID)
3434
if err != nil {
35-
return err
36-
}
37-
38-
var membershipID string
39-
for _, m := range memberships {
40-
if m.Org.ID == orgID {
41-
membershipID = m.ID
42-
break
43-
}
44-
}
45-
46-
if membershipID == "" {
35+
return fmt.Errorf("getting membership: %w", err)
36+
} else if membership == nil {
4737
return fmt.Errorf("organization %s not found", orgID)
4838
}
4939

50-
m, err := action.NewMembershipSet(actionOpts).Run(membershipID)
40+
m, err := action.NewMembershipSet(actionOpts).Run(membership.ID)
5141
if err != nil {
5242
return err
5343
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
"fmt"
21+
22+
pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1"
23+
)
24+
25+
type MembershipDelete struct {
26+
cfg *ActionsOpts
27+
}
28+
29+
func NewMembershipDelete(cfg *ActionsOpts) *MembershipDelete {
30+
return &MembershipDelete{cfg}
31+
}
32+
33+
func (action *MembershipDelete) Run(ctx context.Context, membershipID string) error {
34+
client := pb.NewOrganizationServiceClient(action.cfg.CPConnection)
35+
if _, err := client.DeleteMembership(ctx, &pb.DeleteMembershipRequest{MembershipId: membershipID}); err != nil {
36+
return fmt.Errorf("deleting membership: %w", err)
37+
}
38+
39+
return nil
40+
}

0 commit comments

Comments
 (0)