Skip to content

Commit

Permalink
Implement minder auth invite CLI commands
Browse files Browse the repository at this point in the history
Signed-off-by: Radoslav Dimitrov <[email protected]>
  • Loading branch information
rdimitrov committed Jun 6, 2024
1 parent a21f1dd commit bb8d6ae
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 0 deletions.
38 changes: 38 additions & 0 deletions cmd/cli/app/auth/invite/invite.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// Copyright 2024 Stacklok, Inc.
//
// 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 invite provides the auth invite command for the minder CLI.
package invite

import (
"github.com/spf13/cobra"

"github.com/stacklok/minder/cmd/cli/app/auth"
)

// inviteCmd represents the offline-token set of sub-commands
var inviteCmd = &cobra.Command{
Use: "invite",
Short: "Manage user invitations",
Long: `The minder auth invite command lets you manage user invitations
for the minder control plane.`,
RunE: func(cmd *cobra.Command, _ []string) error {
return cmd.Usage()
},
}

func init() {
auth.AuthCmd.AddCommand(inviteCmd)
}
59 changes: 59 additions & 0 deletions cmd/cli/app/auth/invite/invite_accept.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// Copyright 2023 Stacklok, Inc.
//
// 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 invite provides the auth invite command for the minder CLI.
package invite

import (
"context"

"github.com/spf13/cobra"
"google.golang.org/grpc"

"github.com/stacklok/minder/internal/util/cli"
minderv1 "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1"
)

// inviteAcceptCmd represents the accept command
var inviteAcceptCmd = &cobra.Command{
Use: "accept",
Short: "Accept a pending invitation",
Long: `Accept a pending invitation for the current minder user`,
RunE: cli.GRPCClientWrapRunE(inviteAcceptCommand),
Args: cobra.ExactArgs(1),
}

// inviteAcceptCommand is the whoami subcommand
func inviteAcceptCommand(ctx context.Context, cmd *cobra.Command, args []string, conn *grpc.ClientConn) error {
client := minderv1.NewUserServiceClient(conn)
code := args[0]
// No longer print usage on returned error, since we've parsed our inputs
// See https://github.com/spf13/cobra/issues/340#issuecomment-374617413
cmd.SilenceUsage = true

res, err := client.ResolveInvitation(ctx, &minderv1.ResolveInvitationRequest{
Accept: true,
Code: code,
})
if err != nil {
return cli.MessageAndError("Error resolving invitation", err)
}
cmd.Printf("Invitation %s for %s to become %s of project %s was accepted!\n", code, res.Email, res.Role, res.Project)
return nil
}

func init() {
inviteCmd.AddCommand(inviteAcceptCmd)
}
59 changes: 59 additions & 0 deletions cmd/cli/app/auth/invite/invite_decline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// Copyright 2023 Stacklok, Inc.
//
// 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 invite provides the auth invite command for the minder CLI.
package invite

import (
"context"

"github.com/spf13/cobra"
"google.golang.org/grpc"

"github.com/stacklok/minder/internal/util/cli"
minderv1 "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1"
)

// inviteDeclineCmd represents the decline command
var inviteDeclineCmd = &cobra.Command{
Use: "decline",
Short: "Declines a pending invitation",
Long: `Declines a pending invitation for the current minder user`,
RunE: cli.GRPCClientWrapRunE(inviteDeclineCommand),
Args: cobra.ExactArgs(1),
}

// inviteAcceptCommand is the whoami subcommand
func inviteDeclineCommand(ctx context.Context, cmd *cobra.Command, args []string, conn *grpc.ClientConn) error {
client := minderv1.NewUserServiceClient(conn)
code := args[0]
// No longer print usage on returned error, since we've parsed our inputs
// See https://github.com/spf13/cobra/issues/340#issuecomment-374617413
cmd.SilenceUsage = true

res, err := client.ResolveInvitation(ctx, &minderv1.ResolveInvitationRequest{
Accept: false,
Code: code,
})
if err != nil {
return cli.MessageAndError("Error resolving invitation", err)
}
cmd.Printf("Invitation %s for %s to become %s of project %s was declined!\n", code, res.Email, res.Role, res.Project)
return nil
}

func init() {
inviteCmd.AddCommand(inviteDeclineCmd)
}
89 changes: 89 additions & 0 deletions cmd/cli/app/auth/invite/invite_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//
// Copyright 2023 Stacklok, Inc.
//
// 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 invite provides the auth invite command for the minder CLI.
package invite

import (
"context"
"fmt"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/viper"
"google.golang.org/grpc"

"github.com/stacklok/minder/cmd/cli/app"
"github.com/stacklok/minder/internal/util"
"github.com/stacklok/minder/internal/util/cli"
"github.com/stacklok/minder/internal/util/cli/table"
"github.com/stacklok/minder/internal/util/cli/table/layouts"
minderv1 "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1"
)

// inviteListCmd represents the list command
var inviteListCmd = &cobra.Command{
Use: "list",
Short: "List pending invitations",
Long: `List shows all pending invitations for the current minder user`,
RunE: cli.GRPCClientWrapRunE(inviteListCommand),
}

// inviteListCommand is the whoami subcommand
func inviteListCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn *grpc.ClientConn) error {
client := minderv1.NewUserServiceClient(conn)

// No longer print usage on returned error, since we've parsed our inputs
// See https://github.com/spf13/cobra/issues/340#issuecomment-374617413
cmd.SilenceUsage = true

format := viper.GetString("output")

res, err := client.ListInvitations(ctx, &minderv1.ListInvitationsRequest{})
if err != nil {
return cli.MessageAndError("Error listing invitations", err)
}

switch format {
case app.JSON:
out, err := util.GetJsonFromProto(res)
if err != nil {
return cli.MessageAndError("Error getting json from proto", err)
}
cmd.Println(out)
case app.YAML:
out, err := util.GetYamlFromProto(res)
if err != nil {
return cli.MessageAndError("Error getting yaml from proto", err)
}
cmd.Println(out)
case app.Table:
t := table.New(table.Simple, layouts.Default, []string{"Sponsor", "Project", "Role", "Code"})
for _, v := range res.Invitations {
t.AddRow(v.SponsorDisplay, v.Project, v.Role, v.Code)
}
t.Render()
default:
return fmt.Errorf("unsupported output format: %s", format)
}
return nil
}

func init() {
inviteCmd.AddCommand(inviteListCmd)

inviteListCmd.Flags().StringP("output", "o", app.Table,
fmt.Sprintf("Output format (one of %s)", strings.Join(app.SupportedOutputFormats(), ",")))
}
1 change: 1 addition & 0 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/stacklok/minder/cmd/cli/app"
_ "github.com/stacklok/minder/cmd/cli/app/artifact"
_ "github.com/stacklok/minder/cmd/cli/app/auth"
_ "github.com/stacklok/minder/cmd/cli/app/auth/invite"
_ "github.com/stacklok/minder/cmd/cli/app/auth/offline_token"
_ "github.com/stacklok/minder/cmd/cli/app/docs"
_ "github.com/stacklok/minder/cmd/cli/app/profile"
Expand Down

0 comments on commit bb8d6ae

Please sign in to comment.