Skip to content

Commit

Permalink
Merge branch 'main' into 3835-update-minder-install-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mesembria authored Jul 15, 2024
2 parents 859dc7e + 3be7c67 commit d22427b
Show file tree
Hide file tree
Showing 35 changed files with 3,727 additions and 2,970 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
go-version-file: ./go.mod
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3
uses: github/codeql-action/init@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -60,7 +60,7 @@ jobs:
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality

uses: github/codeql-action/autobuild@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3
uses: github/codeql-action/autobuild@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

Expand All @@ -71,6 +71,6 @@ jobs:
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3
uses: github/codeql-action/analyze@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3
with:
category: "/language:${{matrix.language}}"
50 changes: 26 additions & 24 deletions cmd/cli/app/auth/offline_token/offline_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
package offline_token

import (
"context"
"fmt"
"os"

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

"github.com/stacklok/minder/cmd/cli/app/auth"
"github.com/stacklok/minder/internal/config"
Expand All @@ -40,37 +42,37 @@ Offline tokens are used to authenticate to the minder control plane without
requiring the user's presence. This is useful for long-running processes
that need to authenticate to the control plane.`,

RunE: func(cmd *cobra.Command, _ []string) error {
ctx, cancel := cli.GetAppContext(cmd.Context(), viper.GetViper())
defer cancel()
RunE: cli.GRPCClientWrapRunE(offlineGetCommand),
}

clientConfig, err := config.ReadConfigFromViper[clientconfig.Config](viper.GetViper())
if err != nil {
return fmt.Errorf("error reading config: %w", err)
}
// offlineGetCommand is the offline-token get subcommand
func offlineGetCommand(ctx context.Context, cmd *cobra.Command, _ []string, _ *grpc.ClientConn) error {
clientConfig, err := config.ReadConfigFromViper[clientconfig.Config](viper.GetViper())
if err != nil {
return fmt.Errorf("error reading config: %w", err)
}

f := viper.GetString("file")
skipBrowser := viper.GetBool("offline.get.skip-browser")
f := viper.GetString("file")
skipBrowser := viper.GetBool("offline.get.skip-browser")

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

// wait for the token to be received
token, err := auth.Login(ctx, cmd, clientConfig, []string{"offline_access"}, skipBrowser)
if err != nil {
return err
}
// wait for the token to be received
token, err := auth.Login(ctx, cmd, clientConfig, []string{"offline_access"}, skipBrowser)
if err != nil {
return err
}

// write the token to the file
if err := os.WriteFile(f, []byte(token.RefreshToken), 0600); err != nil {
return fmt.Errorf("error writing offline token to file: %w", err)
}
// write the token to the file
if err := os.WriteFile(f, []byte(token.RefreshToken), 0600); err != nil {
return fmt.Errorf("error writing offline token to file: %w", err)
}

cmd.Printf("Offline token written to %s\n", f)
cmd.Printf("Offline token written to %s\n", f)

return nil
},
return nil
}

func init() {
Expand Down
59 changes: 32 additions & 27 deletions cmd/cli/app/auth/offline_token/offline_revoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@
package offline_token

import (
"context"
"fmt"
"os"
"path/filepath"

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

"github.com/stacklok/minder/internal/config"
clientconfig "github.com/stacklok/minder/internal/config/client"
"github.com/stacklok/minder/internal/util"
"github.com/stacklok/minder/internal/util/cli"
)

// offlineTokenRevokeCmd represents the offline-token use command
Expand All @@ -40,48 +43,50 @@ Offline tokens are used to authenticate to the minder control plane without
requiring the user's presence. This is useful for long-running processes
that need to authenticate to the control plane.`,

RunE: func(cmd *cobra.Command, _ []string) error {
clientConfig, err := config.ReadConfigFromViper[clientconfig.Config](viper.GetViper())
if err != nil {
return fmt.Errorf("error reading config: %w", err)
}
RunE: cli.GRPCClientWrapRunE(offlineRevokeCommand),
}

f := viper.GetString("file")
tok := viper.GetString("token")
if tok == "" {
fpath := filepath.Clean(f)
tokbytes, err := os.ReadFile(fpath)
if err != nil {
return fmt.Errorf("error reading file: %w", err)
}
// offlineRevokeCommand is the offline-token revoke subcommand
func offlineRevokeCommand(_ context.Context, cmd *cobra.Command, _ []string, _ *grpc.ClientConn) error {
clientConfig, err := config.ReadConfigFromViper[clientconfig.Config](viper.GetViper())
if err != nil {
return fmt.Errorf("error reading config: %w", err)
}

tok = string(tokbytes)
f := viper.GetString("file")
tok := viper.GetString("token")
if tok == "" {
fpath := filepath.Clean(f)
tokbytes, err := os.ReadFile(fpath)
if err != nil {
return fmt.Errorf("error reading file: %w", err)
}

// 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
tok = string(tokbytes)
}

issuerUrlStr := clientConfig.Identity.CLI.IssuerUrl
clientID := clientConfig.Identity.CLI.ClientId
// 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

if err := util.RevokeOfflineToken(tok, issuerUrlStr, clientID); err != nil {
return fmt.Errorf("couldn't revoke token: %v", err)
}
issuerUrlStr := clientConfig.Identity.CLI.IssuerUrl
clientID := clientConfig.Identity.CLI.ClientId

if err := util.RevokeOfflineToken(tok, issuerUrlStr, clientID); err != nil {
return fmt.Errorf("couldn't revoke token: %v", err)
}

cmd.Printf("Token revoked\n")
cmd.Printf("Token revoked\n")

return nil
},
return nil
}

func init() {
offlineTokenCmd.AddCommand(offlineTokenRevokeCmd)

offlineTokenRevokeCmd.Flags().StringP("file", "f", "offline.token", "The file that contains the offline token")
offlineTokenRevokeCmd.Flags().StringP("token", "t", "",
"The environment variable to use for the offline token. "+
"Also settable through the MINDER_OFFLINE_TOKEN environment variable.")
"The offline token to revoke. Also settable through the MINDER_OFFLINE_TOKEN environment variable.")

offlineTokenRevokeCmd.MarkFlagsMutuallyExclusive("file", "token")

Expand Down
78 changes: 41 additions & 37 deletions cmd/cli/app/auth/offline_token/offline_use.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@
package offline_token

import (
"context"
"fmt"
"os"
"path/filepath"

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

"github.com/stacklok/minder/internal/config"
clientconfig "github.com/stacklok/minder/internal/config/client"
"github.com/stacklok/minder/internal/util"
"github.com/stacklok/minder/internal/util/cli"
)

// offlineTokenUseCmd represents the offline-token use command
Expand All @@ -39,60 +42,61 @@ for the minder control plane.
Offline tokens are used to authenticate to the minder control plane without
requiring the user's presence. This is useful for long-running processes
that need to authenticate to the control plane.`,
RunE: cli.GRPCClientWrapRunE(offlineUseCommand),
}

// offlineUseCommand is the offline-token use subcommand
func offlineUseCommand(_ context.Context, cmd *cobra.Command, _ []string, _ *grpc.ClientConn) error {
clientConfig, err := config.ReadConfigFromViper[clientconfig.Config](viper.GetViper())
if err != nil {
return fmt.Errorf("error reading config: %w", err)
}

RunE: func(cmd *cobra.Command, _ []string) error {
clientConfig, err := config.ReadConfigFromViper[clientconfig.Config](viper.GetViper())
f := viper.GetString("file")
tok := viper.GetString("token")
if tok == "" {
fpath := filepath.Clean(f)
tokbytes, err := os.ReadFile(fpath)
if err != nil {
return fmt.Errorf("error reading config: %w", err)
return fmt.Errorf("error reading file: %w", err)
}

f := viper.GetString("file")
tok := viper.GetString("token")
if tok == "" {
fpath := filepath.Clean(f)
tokbytes, err := os.ReadFile(fpath)
if err != nil {
return fmt.Errorf("error reading file: %w", err)
}

tok = string(tokbytes)
}
tok = string(tokbytes)
}

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

issuerUrlStr := clientConfig.Identity.CLI.IssuerUrl
clientID := clientConfig.Identity.CLI.ClientId
issuerUrlStr := clientConfig.Identity.CLI.IssuerUrl
clientID := clientConfig.Identity.CLI.ClientId

creds, err := util.RefreshCredentials(tok, issuerUrlStr, clientID)
if err != nil {
return fmt.Errorf("couldn't fetch credentials: %v", err)
}
creds, err := util.RefreshCredentials(tok, issuerUrlStr, clientID)
if err != nil {
return fmt.Errorf("couldn't fetch credentials: %v", err)
}

// save credentials
filePath, err := util.SaveCredentials(util.OpenIdCredentials{
AccessToken: creds.AccessToken,
RefreshToken: creds.RefreshToken,
AccessTokenExpiresAt: creds.AccessTokenExpiresAt,
})
if err != nil {
cmd.PrintErrf("couldn't save credentials: %s\n", err)
}
// save credentials
filePath, err := util.SaveCredentials(util.OpenIdCredentials{
AccessToken: creds.AccessToken,
RefreshToken: creds.RefreshToken,
AccessTokenExpiresAt: creds.AccessTokenExpiresAt,
})
if err != nil {
cmd.PrintErrf("couldn't save credentials: %s\n", err)
}

cmd.Printf("Your access credentials have been saved to %s\n", filePath)
cmd.Printf("Your access credentials have been saved to %s\n", filePath)

return nil
},
return nil
}

func init() {
offlineTokenCmd.AddCommand(offlineTokenUseCmd)

offlineTokenUseCmd.Flags().StringP("file", "f", "offline.token", "The file that contains the offline token")
offlineTokenUseCmd.Flags().StringP("token", "t", "",
"The environment variable to use for the offline token. "+
"Also settable through the MINDER_OFFLINE_TOKEN environment variable.")
"The offline token to use. Also settable through the MINDER_OFFLINE_TOKEN environment variable.")

offlineTokenUseCmd.MarkFlagsMutuallyExclusive("file", "token")

Expand Down
49 changes: 49 additions & 0 deletions cmd/cli/app/provider/provider_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package provider
import (
"context"
"fmt"
"reflect"
"strings"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -97,6 +98,10 @@ func GetProviderCommand(ctx context.Context, cmd *cobra.Command, _ []string, con
t.AddRow("Version", p.GetVersion())
t.AddRow("Implements", strings.Join(impls, ", "))
t.AddRow("Auth Flows", strings.Join(afs, ", "))
config := configAsKeyValues(p)
if config != "" {
t.AddRow("Config", config)
}

t.Render()
return nil
Expand All @@ -106,3 +111,47 @@ func GetProviderCommand(ctx context.Context, cmd *cobra.Command, _ []string, con

return nil
}

// mapToKvPairs converts a map to a list of key-value pairs
// TODO(jakub): This works OK now that we have a low-number of config options
// if we have more elaborate configs, we might want to just dump the config as YAML, but for the usual
// case now (1 option..) that would not be very readable
func mapToKvPairs(m map[string]any, parentKey string, result *[]string, nesting int) {
// just in case
if nesting > 10 {
return
}

for key, value := range m {
fullKey := key
if parentKey != "" {
fullKey = parentKey + "." + key
}

v := reflect.ValueOf(value)
switch v.Kind() { // nolint:exhaustive
case reflect.Map:
nestedMap := value.(map[string]any)
mapToKvPairs(nestedMap, fullKey, result, nesting+1)
default:
// this should work for most types, if not, we'll likely just switch to printing YAML
*result = append(*result, fmt.Sprintf("%s=%v", fullKey, value))
}
}
}

func configAsKeyValues(p *minderv1.Provider) string {
if p == nil {
return ""
}

conf := p.GetConfig().AsMap()
if conf == nil {
return ""
}

var result []string
mapToKvPairs(conf, "", &result, 0)

return strings.Join(result, "\n")
}
Loading

0 comments on commit d22427b

Please sign in to comment.