Skip to content

Commit

Permalink
Merge branch 'main' into eval-metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
dmjb authored Jun 21, 2024
2 parents 834f355 + 2c0c6b2 commit 1209d30
Show file tree
Hide file tree
Showing 36 changed files with 3,088 additions and 1,096 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/image-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
- name: Test build on x86
id: docker_build
uses: docker/build-push-action@94f8f8c2eec4bc3f1d78c1755580779804cb87b2 # v6.0.1
uses: docker/build-push-action@f6010ea70151369b06f0194be1051fbbdff851b2 # v6.0.2
with:
context: .
file: ./docker/minder/Dockerfile
Expand Down
2 changes: 1 addition & 1 deletion cmd/cli/app/auth/invite/invite_accept.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var inviteAcceptCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
}

// inviteAcceptCommand is the whoami subcommand
// inviteAcceptCommand is the "invite accept" subcommand
func inviteAcceptCommand(ctx context.Context, cmd *cobra.Command, args []string, conn *grpc.ClientConn) error {
client := minderv1.NewUserServiceClient(conn)
code := args[0]
Expand Down
2 changes: 1 addition & 1 deletion cmd/cli/app/auth/invite/invite_decline.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var inviteDeclineCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
}

// inviteAcceptCommand is the whoami subcommand
// inviteDeclineCommand is the "invite decline" subcommand
func inviteDeclineCommand(ctx context.Context, cmd *cobra.Command, args []string, conn *grpc.ClientConn) error {
client := minderv1.NewUserServiceClient(conn)
code := args[0]
Expand Down
90 changes: 90 additions & 0 deletions cmd/cli/app/auth/invite/invite_get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//
// 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"
"time"

"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"
)

// inviteGetCmd represents the list command
var inviteGetCmd = &cobra.Command{
Hidden: true, // TODO: This hides the command, remove it once it's implemented
Use: "get",
Short: "Get info about pending invitations",
Long: `Get shows additional information about a pending invitation`,
RunE: cli.GRPCClientWrapRunE(inviteGetCommand),
Args: cobra.ExactArgs(1),
}

// inviteGetCommand is the invite get subcommand
func inviteGetCommand(ctx context.Context, cmd *cobra.Command, args []string, conn *grpc.ClientConn) error {
client := minderv1.NewInviteServiceClient(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.GetInviteDetails(ctx, &minderv1.GetInviteDetailsRequest{
Code: args[0],
})
if err != nil {
return cli.MessageAndError("Error getting info for invitation", 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", "Expires"})
t.AddRow(res.SponsorDisplay, res.ProjectDisplay, res.ExpiresAt.AsTime().Format(time.RFC3339))
t.Render()
default:
return fmt.Errorf("unsupported output format: %s", format)
}
return nil
}

func init() {
inviteCmd.AddCommand(inviteGetCmd)
inviteGetCmd.Flags().StringP("output", "o", app.Table,
fmt.Sprintf("Output format (one of %s)", strings.Join(app.SupportedOutputFormats(), ",")))
}
6 changes: 4 additions & 2 deletions cmd/cli/app/auth/invite/invite_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ func inviteListCommand(ctx context.Context, cmd *cobra.Command, _ []string, 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{})
Expand All @@ -72,6 +71,10 @@ func inviteListCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn
}
cmd.Println(out)
case app.Table:
if len(res.Invitations) == 0 {
cmd.Println("No pending invitations")
return nil
}
t := table.New(table.Simple, layouts.Default, []string{"Sponsor", "Project", "Role", "Expires", "Code"})
for _, v := range res.Invitations {
t.AddRow(v.SponsorDisplay, v.Project, v.Role, v.ExpiresAt.AsTime().Format(time.RFC3339), v.Code)
Expand All @@ -85,7 +88,6 @@ func inviteListCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn

func init() {
inviteCmd.AddCommand(inviteListCmd)

inviteListCmd.Flags().StringP("output", "o", app.Table,
fmt.Sprintf("Output format (one of %s)", strings.Join(app.SupportedOutputFormats(), ",")))
}
35 changes: 24 additions & 11 deletions cmd/cli/app/project/role/role_deny.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,37 +42,50 @@ func DenyCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn *grpc
sub := viper.GetString("sub")
r := viper.GetString("role")
project := viper.GetString("project")
email := viper.GetString("email")

// 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

roleAssignment := &minderv1.RoleAssignment{
Role: r,
Subject: sub,
}
failMsg := "Error denying role"
successMsg := "Denied role successfully."
// Only send an email if one is provided
if email != "" {
roleAssignment = &minderv1.RoleAssignment{
Role: r,
Email: email,
}
failMsg = "Error deleting an invite"
successMsg = "Invite deleted successfully."
}

_, err := client.RemoveRole(ctx, &minderv1.RemoveRoleRequest{
Context: &minderv1.Context{
Project: &project,
},
RoleAssignment: &minderv1.RoleAssignment{
Role: r,
Subject: sub,
},
RoleAssignment: roleAssignment,
})
if err != nil {
return cli.MessageAndError("Error denying role", err)
return cli.MessageAndError(failMsg, err)
}

cmd.Println("Denied role successfully.")
cmd.Println(successMsg)
return nil
}

func init() {
RoleCmd.AddCommand(denyCmd)

denyCmd.Flags().StringP("sub", "s", "", "subject to grant access to")
denyCmd.Flags().StringP("role", "r", "", "the role to grant")
if err := denyCmd.MarkFlagRequired("sub"); err != nil {
denyCmd.Print("Error marking `sub` flag as required.")
os.Exit(1)
}
denyCmd.Flags().StringP("sub", "s", "", "subject to grant access to")
denyCmd.Flags().StringP("email", "e", "", "email to send invitation to")
denyCmd.MarkFlagsOneRequired("sub", "email")
denyCmd.MarkFlagsMutuallyExclusive("sub", "email")
if err := denyCmd.MarkFlagRequired("role"); err != nil {
denyCmd.Print("Error marking `role` flag as required.")
os.Exit(1)
Expand Down
39 changes: 28 additions & 11 deletions cmd/cli/app/project/role/role_grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,43 @@ func GrantCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn *grp
sub := viper.GetString("sub")
r := viper.GetString("role")
project := viper.GetString("project")
email := viper.GetString("email")

// 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

_, err := client.AssignRole(ctx, &minderv1.AssignRoleRequest{
roleAssignment := &minderv1.RoleAssignment{
Role: r,
Subject: sub,
}
failMsg := "Error granting role"
successMsg := "Granted role successfully."
// Only send an email if one is provided
if email != "" {
roleAssignment = &minderv1.RoleAssignment{
Role: r,
Email: email,
}
failMsg = "Error creating/updating an invite"
successMsg = "Invite created/updated successfully."
}

ret, err := client.AssignRole(ctx, &minderv1.AssignRoleRequest{
Context: &minderv1.Context{
Project: &project,
},
RoleAssignment: &minderv1.RoleAssignment{
Role: r,
Subject: sub,
},
RoleAssignment: roleAssignment,
})
if err != nil {
return cli.MessageAndError("Error granting role", err)
return cli.MessageAndError(failMsg, err)
}

cmd.Println("Granted role successfully.")
cmd.Println(successMsg)

if ret.Invitation != nil && ret.Invitation.Code != "" {
cmd.Printf("\nThe invitee can accept it by running: \n\nminder auth invite accept %s\n", ret.Invitation.Code)
}
return nil
}

Expand All @@ -69,10 +87,9 @@ func init() {

grantCmd.Flags().StringP("sub", "s", "", "subject to grant access to")
grantCmd.Flags().StringP("role", "r", "", "the role to grant")
if err := grantCmd.MarkFlagRequired("sub"); err != nil {
grantCmd.Print("Error marking `sub` flag as required.")
os.Exit(1)
}
grantCmd.Flags().StringP("email", "e", "", "email to send invitation to")
grantCmd.MarkFlagsOneRequired("sub", "email")
grantCmd.MarkFlagsMutuallyExclusive("sub", "email")
if err := grantCmd.MarkFlagRequired("role"); err != nil {
grantCmd.Print("Error marking `role` flag as required.")
os.Exit(1)
Expand Down
77 changes: 77 additions & 0 deletions cmd/cli/app/project/role/role_update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// 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 role

import (
"context"

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

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

var updateCmd = &cobra.Command{
Use: "update",
Short: "update a role to a subject on a project",
Long: `The minder project role update command allows one to update a role
to a user (subject) on a particular project.`,
RunE: cli.GRPCClientWrapRunE(UpdateCommand),
}

// UpdateCommand is the command for granting roles
func UpdateCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn *grpc.ClientConn) error {
client := minderv1.NewPermissionsServiceClient(conn)

sub := viper.GetString("sub")
r := viper.GetString("role")
project := viper.GetString("project")

// 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

ret, err := client.UpdateRole(ctx, &minderv1.UpdateRoleRequest{
Context: &minderv1.Context{
Project: &project,
},
Role: []string{r},
Subject: sub,
})
if err != nil {
return cli.MessageAndError("Error updating role", err)
}

cmd.Println("Update role successfully.")
cmd.Printf(
"Subject \"%s\" is now assigned to role \"%s\" on project \"%s\"\n",
ret.RoleAssignments[0].Subject,
ret.RoleAssignments[0].Role,
*ret.RoleAssignments[0].Project,
)

return nil
}

func init() {
RoleCmd.AddCommand(updateCmd)

updateCmd.Flags().StringP("sub", "s", "", "subject to update role access for")
updateCmd.Flags().StringP("role", "r", "", "the role to update it to")
updateCmd.MarkFlagsRequiredTogether("sub", "role")
}
Loading

0 comments on commit 1209d30

Please sign in to comment.