Skip to content

Commit

Permalink
squashing all commits into one (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
ashleyvjoy authored Feb 28, 2023
1 parent 2bc199c commit 4bbef3b
Show file tree
Hide file tree
Showing 27 changed files with 1,487 additions and 296 deletions.
11 changes: 11 additions & 0 deletions cmd/karavictl/cmd/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/reflect/protoreflect"
)

// NewTenantCmd creates a new tenant command
Expand All @@ -54,6 +56,7 @@ func NewTenantCmd() *cobra.Command {
tenantCmd.AddCommand(NewTenantGetCmd())
tenantCmd.AddCommand(NewTenantListCmd())
tenantCmd.AddCommand(NewTenantRevokeCmd())
tenantCmd.AddCommand(NewTenantUpdateCmd())
return tenantCmd
}

Expand Down Expand Up @@ -121,3 +124,11 @@ func jsonOutput(w io.Writer, v interface{}) error {
}
return nil
}

// jsonOutput() omits boolean flag on false value while encoding
func jsonOutputEmitEmpty(w io.Writer, m protoreflect.ProtoMessage) error {
enc := protojson.MarshalOptions{Multiline: true, EmitUnpopulated: true, Indent: ""}
data := enc.Format(m)
fmt.Fprintln(w, data)
return nil
}
11 changes: 9 additions & 2 deletions cmd/karavictl/cmd/tenant_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,24 @@ func NewTenantCreateCmd() *cobra.Command {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), errors.New("empty name not allowed"))
}

approveSdc, err := cmd.Flags().GetBool("approvesdc")
if err != nil {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), err)
}

_, err = tenantClient.CreateTenant(context.Background(), &pb.CreateTenantRequest{
Tenant: &pb.Tenant{
Name: name,
Name: name,
Approvesdc: approveSdc,
},
})
if err != nil {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), err)
reportErrorAndExit(jsonOutput, cmd.ErrOrStderr(), err)
}
},
}

tenantCreateCmd.Flags().StringP("name", "n", "", "Tenant name")
tenantCreateCmd.Flags().Bool("approvesdc", true, "To allow/deny SDC approval requests")
return tenantCreateCmd
}
21 changes: 21 additions & 0 deletions cmd/karavictl/cmd/tenant_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,25 @@ func TestTenantCreate(t *testing.T) {
t.Errorf("got err %q, want %q", gotErr.ErrorMsg, wantErrMsg)
}
})
t.Run("it requests creation of a tenant with setting approvesdc flag explicitly", func(t *testing.T) {
defer afterFn()
CreateTenantServiceClient = func(_ string, _ bool) (pb.TenantServiceClient, io.Closer, error) {
return &fakeTenantServiceClient{}, ioutil.NopCloser(nil), nil
}
JSONOutput = func(w io.Writer, _ interface{}) error {
return nil
}
osExit = func(code int) {
}
var gotOutput bytes.Buffer

cmd := NewRootCmd()
cmd.SetOutput(&gotOutput)
cmd.SetArgs([]string{"tenant", "create", "-n", "testname", "--approvesdc", "true"})
cmd.Execute()

if len(gotOutput.Bytes()) != 0 {
t.Errorf("expected zero output but got %q", string(gotOutput.Bytes()))
}
})
}
6 changes: 3 additions & 3 deletions cmd/karavictl/cmd/tenant_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ func NewTenantGetCmd() *cobra.Command {
Name: name,
})
if err != nil {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), err)
reportErrorAndExit(jsonOutput, cmd.ErrOrStderr(), err)
}

err = JSONOutput(cmd.OutOrStdout(), &t)
err = jsonOutputEmitEmpty(cmd.ErrOrStderr(), t)
if err != nil {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), err)
reportErrorAndExit(jsonOutput, cmd.ErrOrStderr(), err)
}
},
}
Expand Down
10 changes: 10 additions & 0 deletions cmd/karavictl/cmd/tenant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
type fakeTenantServiceClient struct {
pb.TenantServiceClient
CreateTenantFn func(context.Context, *pb.CreateTenantRequest, ...grpc.CallOption) (*pb.Tenant, error)
UpdateTenantFn func(context.Context, *pb.UpdateTenantRequest, ...grpc.CallOption) (*pb.Tenant, error)
GetTenantFn func(context.Context, *pb.GetTenantRequest, ...grpc.CallOption) (*pb.Tenant, error)
DeleteTenantFn func(context.Context, *pb.DeleteTenantRequest, ...grpc.CallOption) (*pb.DeleteTenantResponse, error)
ListTenantFn func(context.Context, *pb.ListTenantRequest, ...grpc.CallOption) (*pb.ListTenantResponse, error)
Expand All @@ -40,6 +41,15 @@ func (f *fakeTenantServiceClient) CreateTenant(ctx context.Context, in *pb.Creat
}, nil
}

func (f *fakeTenantServiceClient) UpdateTenant(ctx context.Context, in *pb.UpdateTenantRequest, opts ...grpc.CallOption) (*pb.Tenant, error) {
if f.UpdateTenantFn != nil {
return f.UpdateTenantFn(ctx, in, opts...)
}
return &pb.Tenant{
Name: "testname",
}, nil
}

func (f *fakeTenantServiceClient) GetTenant(ctx context.Context, in *pb.GetTenantRequest, opts ...grpc.CallOption) (*pb.Tenant, error) {
if f.GetTenantFn != nil {
return f.GetTenantFn(ctx, in, opts...)
Expand Down
76 changes: 76 additions & 0 deletions cmd/karavictl/cmd/tenant_update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright © 2023 Dell Inc., or its subsidiaries. All Rights Reserved.
//
// 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"
"errors"
"karavi-authorization/pb"
"strings"

"github.com/spf13/cobra"
)

// NewTenantUpdateCmd creates a new update command for tenant
func NewTenantUpdateCmd() *cobra.Command {
tenantUpdateCmd := &cobra.Command{
Use: "update",
TraverseChildren: true,
Short: "Update a tenant resource within CSM Authorization",
Long: `Updates a tenant resource within CSM Authorization`,
Run: func(cmd *cobra.Command, args []string) {
addr, err := cmd.Flags().GetString("addr")
if err != nil {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), err)
}

insecure, err := cmd.Flags().GetBool("insecure")
if err != nil {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), err)
}

tenantClient, conn, err := CreateTenantServiceClient(addr, insecure)
if err != nil {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), err)
}
defer conn.Close()

name, err := cmd.Flags().GetString("name")
if err != nil {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), err)
}
if strings.TrimSpace(name) == "" {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), errors.New("empty name not allowed"))
}

approveSdc, err := cmd.Flags().GetBool("approvesdc")
if err != nil {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), err)
}

_, err = tenantClient.UpdateTenant(context.Background(), &pb.UpdateTenantRequest{
TenantName: name,
Approvesdc: approveSdc,
})
if err != nil {
reportErrorAndExit(JSONOutput, cmd.ErrOrStderr(), err)
}
},
}

tenantUpdateCmd.Flags().StringP("name", "n", "", "Tenant name")
tenantUpdateCmd.Flags().Bool("approvesdc", true, "To allow/deny SDC approval requests")
return tenantUpdateCmd
}
165 changes: 165 additions & 0 deletions cmd/karavictl/cmd/tenant_update_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Copyright © 2023 Dell Inc., or its subsidiaries. All Rights Reserved.
//
// 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 (
"bytes"
"context"
"encoding/json"
"errors"
"io"
"io/ioutil"
"karavi-authorization/pb"
"os"
"testing"

"google.golang.org/grpc"
)

func TestTenantUpdate(t *testing.T) {
afterFn := func() {
CreateTenantServiceClient = createTenantServiceClient
JSONOutput = jsonOutput
osExit = os.Exit
}

t.Run("it requests updation of a tenant", func(t *testing.T) {
defer afterFn()
CreateTenantServiceClient = func(_ string, _ bool) (pb.TenantServiceClient, io.Closer, error) {
return &fakeTenantServiceClient{}, ioutil.NopCloser(nil), nil
}
JSONOutput = func(w io.Writer, _ interface{}) error {
return nil
}
osExit = func(code int) {
}
var gotOutput bytes.Buffer

cmd := NewRootCmd()
cmd.SetOutput(&gotOutput)
cmd.SetArgs([]string{"tenant", "update", "-n", "testname", "--approvesdc", "true"})
cmd.Execute()

if len(gotOutput.Bytes()) != 0 {
t.Errorf("expected zero output but got %q", string(gotOutput.Bytes()))
}
})
t.Run("it requires a valid tenant server connection", func(t *testing.T) {
defer afterFn()
CreateTenantServiceClient = func(_ string, _ bool) (pb.TenantServiceClient, io.Closer, error) {
return nil, ioutil.NopCloser(nil), errors.New("test error")
}
var gotCode int
done := make(chan struct{})
osExit = func(code int) {
gotCode = code
done <- struct{}{}
done <- struct{}{} // we can't let this function return
}
var gotOutput bytes.Buffer

cmd := NewRootCmd()
cmd.SetErr(&gotOutput)
cmd.SetArgs([]string{"tenant", "update", "-n", "testname", "--approvesdc", "true"})
go cmd.Execute()
<-done

wantCode := 1
if gotCode != wantCode {
t.Errorf("got exit code %d, want %d", gotCode, wantCode)
}
var gotErr CommandError
if err := json.NewDecoder(&gotOutput).Decode(&gotErr); err != nil {
t.Fatal(err)
}
wantErrMsg := "test error"
if gotErr.ErrorMsg != wantErrMsg {
t.Errorf("got err %q, want %q", gotErr.ErrorMsg, wantErrMsg)
}
})
t.Run("it requires a valid name argument", func(t *testing.T) {
defer afterFn()
CreateTenantServiceClient = func(_ string, _ bool) (pb.TenantServiceClient, io.Closer, error) {
return &fakeTenantServiceClient{}, ioutil.NopCloser(nil), nil
}
var gotCode int
done := make(chan struct{})
osExit = func(code int) {
gotCode = code
done <- struct{}{}
done <- struct{}{} // we can't let this function return
}

var gotOutput bytes.Buffer

rootCmd := NewRootCmd()
rootCmd.SetErr(&gotOutput)
rootCmd.SetArgs([]string{"tenant", "update"})

go rootCmd.Execute()
<-done

wantCode := 1
if gotCode != wantCode {
t.Errorf("got exit code %d, want %d", gotCode, wantCode)
}
var gotErr CommandError
if err := json.NewDecoder(&gotOutput).Decode(&gotErr); err != nil {
t.Fatal(err)
}
wantErrMsg := "empty name not allowed"
if gotErr.ErrorMsg != wantErrMsg {
t.Errorf("got err %q, want %q", gotErr.ErrorMsg, wantErrMsg)
}
})
t.Run("it handles server errors", func(t *testing.T) {
defer afterFn()
CreateTenantServiceClient = func(_ string, _ bool) (pb.TenantServiceClient, io.Closer, error) {
return &fakeTenantServiceClient{
UpdateTenantFn: func(_ context.Context, _ *pb.UpdateTenantRequest, _ ...grpc.CallOption) (*pb.Tenant, error) {
return nil, errors.New("test error")
},
}, ioutil.NopCloser(nil), nil
}
var gotCode int
done := make(chan struct{})
osExit = func(code int) {
gotCode = code
done <- struct{}{}
done <- struct{}{} // we can't let this function return
}
var gotOutput bytes.Buffer

rootCmd := NewRootCmd()
rootCmd.SetErr(&gotOutput)
rootCmd.SetArgs([]string{"tenant", "update", "-n", "test", "--approvesdc", "true"})

go rootCmd.Execute()
<-done

wantCode := 1
if gotCode != wantCode {
t.Errorf("got exit code %d, want %d", gotCode, wantCode)
}
var gotErr CommandError
if err := json.NewDecoder(&gotOutput).Decode(&gotErr); err != nil {
t.Fatal(err)
}
wantErrMsg := "test error"
if gotErr.ErrorMsg != wantErrMsg {
t.Errorf("got err %q, want %q", gotErr.ErrorMsg, wantErrMsg)
}
})
}
4 changes: 3 additions & 1 deletion cmd/proxy-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"karavi-authorization/internal/quota"
"karavi-authorization/internal/role-service"
"karavi-authorization/internal/role-service/roles"
"karavi-authorization/internal/sdc"
"karavi-authorization/internal/storage-service"
"karavi-authorization/internal/token"
"karavi-authorization/internal/token/jwx"
Expand Down Expand Up @@ -253,6 +254,7 @@ func run(log *logrus.Entry) error {
}
}()
enf := quota.NewRedisEnforcement(context.Background(), quota.WithRedis(rdb))
sdcapr := sdc.NewSdcApprover(context.Background(), sdc.WithRedis(rdb))

// Start tracing support

Expand Down Expand Up @@ -312,7 +314,7 @@ func run(log *logrus.Entry) error {
sysViper.WatchConfig()

// Create handlers for the supported storage arrays.
powerFlexHandler := proxy.NewPowerFlexHandler(log, enf, cfg.OpenPolicyAgent.Host)
powerFlexHandler := proxy.NewPowerFlexHandler(log, enf, sdcapr, cfg.OpenPolicyAgent.Host)
powerMaxHandler := proxy.NewPowerMaxHandler(log, enf, cfg.OpenPolicyAgent.Host)
powerScaleHandler := proxy.NewPowerScaleHandler(log, enf, cfg.OpenPolicyAgent.Host)

Expand Down
2 changes: 1 addition & 1 deletion cmd/proxy-server/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func TestUpdateStorageSystems(t *testing.T) {
logger := logrus.NewEntry(logrus.New())

powerScaleHandler := proxy.NewPowerScaleHandler(logger, nil, "")
powerFlexHandler := proxy.NewPowerFlexHandler(logger, nil, "")
powerFlexHandler := proxy.NewPowerFlexHandler(logger, nil, nil, "")
powerMaxHandler := proxy.NewPowerMaxHandler(logger, nil, "")

// When
Expand Down
Loading

0 comments on commit 4bbef3b

Please sign in to comment.