From 17e25d09f7e04a18bd4492b727f37b605b949e5d Mon Sep 17 00:00:00 2001 From: Alexander Birkner Date: Wed, 6 Aug 2025 13:20:41 +0200 Subject: [PATCH 01/11] chore(git): Added dist/ dir to gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ec48c1a..671995b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ *_gen.go /gpc /id_ed25519* -/tools/ \ No newline at end of file +/tools/ +/dist/ \ No newline at end of file From d6efc7ed31ebab8447ae75e24e9a82fefaec2246 Mon Sep 17 00:00:00 2001 From: Alexander Birkner Date: Wed, 6 Aug 2025 13:22:44 +0200 Subject: [PATCH 02/11] fix(admin): Add all admin commands to the build result --- cmd/agent/root.go | 5 +---- cmd/project/_network_create.go | 4 +--- pkg/generator/definition.go | 2 +- pkg/generator/sub_command.go | 8 +------- 4 files changed, 4 insertions(+), 15 deletions(-) diff --git a/cmd/agent/root.go b/cmd/agent/root.go index 91a0d22..2271697 100644 --- a/cmd/agent/root.go +++ b/cmd/agent/root.go @@ -56,10 +56,7 @@ func New() *cobra.Command { // Special client commands cmd.SelfupdateCommand(&rootCmd) cmd.SetLogLevelCommand(&rootCmd) - - if config.HasAdminConfig() { - cmd.LiveLogCommand(&rootCmd) - } + cmd.LiveLogCommand(&rootCmd) //InteractiveCLICommand(&rootCmd) // Autogenerated commands diff --git a/cmd/project/_network_create.go b/cmd/project/_network_create.go index c942fbc..85247e9 100644 --- a/cmd/project/_network_create.go +++ b/cmd/project/_network_create.go @@ -78,7 +78,5 @@ func init() { networkCreateCmd.MarkFlagRequired("type") networkCreateCmd.MarkFlagRequired("subnets") - if config.HasAdminConfig() { - RootProjectCommand.AddCommand(networkCreateCmd) - } + RootProjectCommand.AddCommand(networkCreateCmd) } diff --git a/pkg/generator/definition.go b/pkg/generator/definition.go index fb92a8e..13506bb 100644 --- a/pkg/generator/definition.go +++ b/pkg/generator/definition.go @@ -23,7 +23,7 @@ type Action struct { func (action *Action) CanCall() bool { adminCall := strings.HasPrefix(action.APICall.Client, "admin") - return !adminCall || adminCall && config.HasAdminConfig() + return !adminCall || config.HasAdminConfig() } type Param struct { diff --git a/pkg/generator/sub_command.go b/pkg/generator/sub_command.go index d25a88e..90683bc 100644 --- a/pkg/generator/sub_command.go +++ b/pkg/generator/sub_command.go @@ -620,13 +620,7 @@ func initFunc(name string, metadata SubcommandMetadata) []Code { Dot("AddCommand"). Call(Id(name + "Cmd")) - if metadata.Action.APICall.Client == "admin" { - c = append(c, If( - Qual("github.com/G-PORTAL/gpcore-cli/pkg/config", "HasAdminConfig").Call().Block( - addCommand))) - } else { - c = append(c, addCommand) - } + c = append(c, addCommand) return c } From fb48561ac56f87181c1be8af3fd51698f4b0fc38 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Tue, 16 Sep 2025 11:34:15 +0200 Subject: [PATCH 03/11] feat(auth): impersonate users Admin users can impersonate other users and perform actions on behalf of other users. This is needed to do bulk actions on `cloud` endpoints for a list of users. Warning: This depends on https://github.com/G-PORTAL/gpcore-go/pull/24 Ticket: TV-873 Signed-off-by: Aaron Fischer --- README.md | 9 +++ cmd/agent/start.go | 101 +++------------------------- cmd/project/list_post.go | 2 +- cmd/project/use.go | 62 ++++++++++++----- cmd/user/details.go | 9 ++- cmd/user/impersonate.go | 98 +++++++++++++++++++++++++++ cmd/user/logout.go | 57 ++++++++++++++++ pkg/api/connection.go | 127 ++++++++++++++++++++++++++++++++++- pkg/client/user.go | 22 +++++- pkg/config/config.go | 26 ++++--- pkg/config/session_config.go | 18 +++-- pkg/config/sources.go | 24 ++++++- 12 files changed, 428 insertions(+), 127 deletions(-) create mode 100644 cmd/user/impersonate.go create mode 100644 cmd/user/logout.go diff --git a/README.md b/README.md index e711a15..dead16b 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,15 @@ between client and server is secured, and no other ssh client can connect to it. If you messed up your config, the sensitive data in the keyring or the public/private key, you can reset everything with the ```gpcore agent setup``` command. +As the client ID and client secret, you can use a service account, created in +the GPCORE panel under https://panel.gpcore.io/user/settings/clients. + +A special case is the ```user impersonate``` command, which allows you to impersonate +another user. This command needs admin permissions, and you need to use the +```gpcore-cli``` client ID for that (see Keycloak for the client secret). This +client is preconfigured to have the impersonate role. To stop impersonating +a user, use the `user logout` command. + ### Admin permissions The GPCORE API has a concept of admin permissions. Several actions can only diff --git a/cmd/agent/start.go b/cmd/agent/start.go index 9c4f938..e59f551 100644 --- a/cmd/agent/start.go +++ b/cmd/agent/start.go @@ -4,98 +4,25 @@ import ( "context" "errors" "fmt" + "net/http" + "os" + "os/signal" + "syscall" + "github.com/G-PORTAL/gpcore-cli/pkg/api" "github.com/G-PORTAL/gpcore-cli/pkg/config" "github.com/G-PORTAL/gpcore-cli/pkg/consts" - "github.com/G-PORTAL/gpcore-go/pkg/gpcore/client" - "github.com/G-PORTAL/gpcore-go/pkg/gpcore/client/auth" "github.com/charmbracelet/log" "github.com/charmbracelet/ssh" "github.com/charmbracelet/wish" "github.com/spf13/cobra" - "google.golang.org/grpc" - "math" - "net/http" - "os" - "os/signal" - "syscall" ) var rootCmd *cobra.Command -type Session struct { - config *config.SessionConfig - conn *grpc.ClientConn - ssh *ssh.Session -} - -var session Session - var DoneChan = make(chan os.Signal, 1) var IsRunning = false -func (s *Session) ContextWithSession(ctx context.Context) context.Context { - ctx = context.WithValue(ctx, "config", s.config) - ctx = context.WithValue(ctx, "ssh", s.ssh) - ctx = context.WithValue(ctx, "conn", s.conn) - return ctx -} - -// ConnectToAPI connects to the API with the given credentials, depending -// on what credentials we have. -func ConnectToAPI(session *Session) (*grpc.ClientConn, error) { - // Endpoint - endpoint := config.Endpoint - if os.Getenv("GPCORE_ENDPOINT") != "" { - endpoint = os.Getenv("GPCORE_ENDPOINT") - } - - var credentials client.AuthProviderOption - - // We have two different connection methods available, depending on the - // type of credentials we get. For "normal" usage, we need the ClientID - // and the ClientSecret, which can be used by every user. - // Some endpoints need admin privileges, tho. For that, we need the - // username and password of the user. We can not use the same connection - // for that, so we need to reconnect with admin credentials. - - // First, we check if we have user/pass for admin login. If we have the - // credentials, we use it for login. - if config.HasAdminConfig() { - log.Info("Using admin credentials") - credentials = &auth.ProviderKeycloakUserPassword{ - ClientID: session.config.ClientID, - ClientSecret: session.config.ClientSecret, - Username: *session.config.Username, - Password: *session.config.Password, - } - - return api.NewGRPCConnection( - credentials, - grpc.WithDefaultCallOptions( - grpc.MaxCallRecvMsgSize(math.MaxInt32), - grpc.MaxCallSendMsgSize(math.MaxInt32), - ), - client.EndpointOverrideOption(endpoint), - ) - } - - // Otherwise, we just use the client credentials. With this login, the - // admin endpoints will not work and result in an error. - credentials = &auth.ProviderKeycloakClientAuth{ - ClientID: session.config.ClientID, - ClientSecret: session.config.ClientSecret, - } - return api.NewGRPCConnection( - credentials, - grpc.WithDefaultCallOptions( - grpc.MaxCallRecvMsgSize(math.MaxInt32), - grpc.MaxCallSendMsgSize(math.MaxInt32), - ), - client.EndpointOverrideOption(endpoint), - ) -} - var startCmd = &cobra.Command{ Use: "start", Short: "Start the agent", @@ -107,18 +34,7 @@ var startCmd = &cobra.Command{ if err != nil { panic(err) } - - session = Session{ - config: sessionConfig, - } - - // Open new connection - session.conn, err = ConnectToAPI(&session) - if err != nil { - log.Errorf("Can not connect to GPCORE API: %v", err) - log.Fatal("Check your config file and/or reset it with \"gpcore agent setup\"") - panic(err) - } + api.RenewAPISession() server, err := wish.NewServer( wish.WithAddress(fmt.Sprintf("%s:%d", consts.AgentHost, consts.AgentPort)), @@ -139,8 +55,9 @@ var startCmd = &cobra.Command{ rootCmd.SetErr(s.Stderr()) rootCmd.CompletionOptions.DisableDefaultCmd = true - session.ssh = &s - ctx := session.ContextWithSession(context.Background()) + api.ActiveSession.SSH = &s + ctx := api.ActiveSession.ContextWithSession(context.Background()) + if err := rootCmd.ExecuteContext(ctx); err != nil { log.Errorf("Error executing command on agent: %v", err) rootCmd.Printf("Error executing command on agent: %v\n", err) diff --git a/cmd/project/list_post.go b/cmd/project/list_post.go index c66f5cc..5a8dba4 100644 --- a/cmd/project/list_post.go +++ b/cmd/project/list_post.go @@ -12,7 +12,7 @@ func ListHookPost(resp *cloudv1.ListProjectsResponse, cobraCmd *cobra.Command) ( ctx := client.ExtractContext(cobraCmd) cfg := ctx.Value("config").(*config.SessionConfig) - user := client.GetUser(ctx) + user := client.GetUserFromContext(ctx) for i := range resp.Projects { name := resp.Projects[i].Name diff --git a/cmd/project/use.go b/cmd/project/use.go index 55982fe..2ffdcef 100644 --- a/cmd/project/use.go +++ b/cmd/project/use.go @@ -1,9 +1,12 @@ package project import ( + "fmt" + + "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/admin/v1/adminv1grpc" "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/cloud/v1/cloudv1grpc" + adminv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/admin/v1" cloudv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/cloud/v1" - "fmt" "github.com/G-PORTAL/gpcore-cli/pkg/client" "github.com/G-PORTAL/gpcore-cli/pkg/config" "github.com/charmbracelet/log" @@ -22,24 +25,53 @@ var useCmd = &cobra.Command{ grpcConn := ctx.Value("conn").(*grpc.ClientConn) client := cloudv1grpc.NewCloudServiceClient(grpcConn) cfg := ctx.Value("config").(*config.SessionConfig) - resp, err := client.ListProjects(cobraCmd.Context(), &cloudv1.ListProjectsRequest{}) - if err != nil { - return err - } - log.Info("Selecting project: " + args[0]) - for _, project := range resp.Projects { - if (project.Name == args[0]) || (project.Id == args[0]) { - cfg.CurrentProject = &project.Id - if err := cfg.Write(); err != nil { - return err + var newProject *cloudv1.Project + + // If the user is an admin user, all projects can be selected. Otherwise, + // only projects the user is a member of can be selected. But in all + // cases, we check if the project exists. + if config.HasAdminConfig() { + adminClient := adminv1grpc.NewAdminServiceClient(grpcConn) + resp, err := adminClient.GetProject(ctx, &adminv1.GetProjectRequest{ + Id: args[0], + }) + if err != nil { + return fmt.Errorf("project not found") + } + + newProject = resp.Project + } else { + resp, err := client.ListProjects(cobraCmd.Context(), &cloudv1.ListProjectsRequest{}) + if err != nil { + return err + } + + for _, project := range resp.Projects { + if (project.Name == args[0]) || (project.Id == args[0]) { + newProject = project + break } - log.Info("Active project is now: " + project.Name) - cobraCmd.Println("Active project is now: " + project.Name) - return nil } } - return fmt.Errorf("project not found") + + // If there is no project found (in the list of projects for the user or + // in the list of all projects for admin users), return an error. + if newProject == nil { + return fmt.Errorf("project not found") + } + + // Set the new project as the current project in the config and save + // the config. This will be used for all subsequent commands. + log.Info("Selecting project: " + args[0]) + cfg.CurrentProject = &newProject.Id + if err := cfg.Write(); err != nil { + return err + } + log.Info("Active project is now: " + newProject.Name) + cobraCmd.Println("Active project is now: " + newProject.Name) + + return nil }, } diff --git a/cmd/user/details.go b/cmd/user/details.go index 9191763..5103662 100644 --- a/cmd/user/details.go +++ b/cmd/user/details.go @@ -17,7 +17,7 @@ var detailsCmd = &cobra.Command{ Args: cobra.NoArgs, RunE: func(cobraCmd *cobra.Command, args []string) error { ctx := client.ExtractContext(cobraCmd) - user := client.GetUser(ctx) + user := client.GetUserFromContext(ctx) sshSession := ctx.Value("ssh").(*ssh.Session) tbl := table.NewWriter() @@ -35,6 +35,13 @@ var detailsCmd = &cobra.Command{ tbl.AppendRow([]interface{}{"Is locked?", user.GetLocked()}) if !config.JSONOutput { + // If the user is impersonated, we add a warning to the output, so + // the admin knows that this is just the impersonated user, not the + // own user. + if client.IsImpersonated() { + cobraCmd.Println("Impersonated user") + } + tbl.Render() } diff --git a/cmd/user/impersonate.go b/cmd/user/impersonate.go new file mode 100644 index 0000000..4889a1c --- /dev/null +++ b/cmd/user/impersonate.go @@ -0,0 +1,98 @@ +package user + +import ( + "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/admin/v1/adminv1grpc" + adminv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/admin/v1" + "github.com/G-PORTAL/gpcore-cli/pkg/api" + "github.com/G-PORTAL/gpcore-cli/pkg/client" + "github.com/G-PORTAL/gpcore-cli/pkg/config" + "github.com/G-PORTAL/gpcore-cli/pkg/protobuf" + "github.com/charmbracelet/log" + "github.com/charmbracelet/ssh" + "github.com/jedib0t/go-pretty/v6/table" + "github.com/spf13/cobra" + "google.golang.org/grpc" +) + +var userID string + +var impersonateCmd = &cobra.Command{ + Use: "impersonate", + Short: "Impersonate a user", + Long: "Impersonate a user, to access the resources from that user", + ValidArgs: []string{"id"}, + Args: cobra.OnlyValidArgs, + RunE: func(cobraCmd *cobra.Command, args []string) error { + ctx := client.ExtractContext(cobraCmd) + grpcConn := ctx.Value("conn").(*grpc.ClientConn) + grpcClient := adminv1grpc.NewAdminServiceClient(grpcConn) + + resp, err := grpcClient.ImpersonateUser(cobraCmd.Context(), &adminv1.ImpersonateUserRequest{ + UserId: userID, + }) + if err != nil { + return err + } + + // Store new access token in config + sessionConfig, err := config.GetSessionConfig() + if err != nil { + return err + } + + accessToken := resp.GetToken().GetAccessToken() + sessionConfig.ImpersonateAccessToken = &accessToken + + expiresIn := int(resp.GetToken().GetExpiresAt().GetSeconds()) + sessionConfig.ImpersonateExpiresIn = &expiresIn + + err = sessionConfig.Write() + if err != nil { + return err + } + + err = config.RefreshSessionConfig() + if err != nil { + return err + } + + newConnection := api.RenewAPISession() + + user := client.GetUser(newConnection) + log.Infof("Impersonating (id: %s) %s", user.GetId(), user.GetUsername()) + + if config.JSONOutput { + jsonData, err := protobuf.MarshalIndent(resp) + if err != nil { + return err + } + cobraCmd.Println(string(jsonData)) + } else { + tbl := table.NewWriter() + tbl.SetStyle(table.StyleRounded) + sshSession := ctx.Value("ssh").(*ssh.Session) + tbl.SetOutputMirror(*sshSession) + tbl.AppendRow([]interface{}{"ID", user.GetId()}) + tbl.AppendRow([]interface{}{"Email: ", user.GetEmail()}) + + cobraCmd.Printf("Impersonating user %v\n", user.GetUsername()) + cobraCmd.Println("All actions are now performed on behalf of the following user.") + cobraCmd.Println("Use 'user logout' to stop impersonating the user.") + tbl.Render() + } + + return nil + }, +} + +func init() { + impersonateCmd.Flags().StringVar(&userID, "id", "", "User ID to impersonate (required)") + err := impersonateCmd.MarkFlagRequired("id") + if err != nil { + return + } + + if config.HasAdminConfig() { + RootUserCommand.AddCommand(impersonateCmd) + } +} diff --git a/cmd/user/logout.go b/cmd/user/logout.go new file mode 100644 index 0000000..0f52de0 --- /dev/null +++ b/cmd/user/logout.go @@ -0,0 +1,57 @@ +package user + +import ( + "github.com/G-PORTAL/gpcore-cli/pkg/api" + "github.com/G-PORTAL/gpcore-cli/pkg/client" + "github.com/G-PORTAL/gpcore-cli/pkg/config" + "github.com/charmbracelet/log" + "github.com/spf13/cobra" +) + +var logoutCmd = &cobra.Command{ + Use: "logout", + Short: "Logout a previously impersonated user", + Long: "Logout a previously impersonated user", + RunE: func(cobraCmd *cobra.Command, args []string) error { + ctx := client.ExtractContext(cobraCmd) + user := client.GetUserFromContext(ctx) + sessionConfig, err := config.GetSessionConfig() + if err != nil { + return err + } + + // If the impersonate access token is already nil, we no longer + // impersonating anybody. + if !client.IsImpersonated() { + cobraCmd.Println("No need to logout, you do not impersonate anybody.") + return nil + } + + sessionConfig.ImpersonateAccessToken = nil + sessionConfig.ImpersonateExpiresIn = nil + sessionConfig.CurrentProject = nil + + err = sessionConfig.Write() + if err != nil { + return err + } + + err = config.RefreshSessionConfig() + if err != nil { + return err + } + + api.RenewAPISession() + + log.Infof("No longer impersonating (id: %s) %s", user.GetId(), user.GetUsername()) + cobraCmd.Printf("No longer impersonating user %s\n", user.GetUsername()) + + return nil + }, +} + +func init() { + if config.HasAdminConfig() { + RootUserCommand.AddCommand(logoutCmd) + } +} diff --git a/pkg/api/connection.go b/pkg/api/connection.go index d42e5dd..8552b08 100644 --- a/pkg/api/connection.go +++ b/pkg/api/connection.go @@ -1,14 +1,42 @@ package api import ( + "context" "crypto/tls" "fmt" + "math" + "os" + + "github.com/G-PORTAL/gpcore-cli/pkg/config" "github.com/G-PORTAL/gpcore-go/pkg/gpcore/client" + "github.com/G-PORTAL/gpcore-go/pkg/gpcore/client/auth" + "github.com/Nerzal/gocloak/v13" + "github.com/charmbracelet/log" + "github.com/charmbracelet/ssh" "google.golang.org/grpc" "google.golang.org/grpc/credentials" - "log" ) +type Session struct { + config *config.SessionConfig + conn *grpc.ClientConn + SSH *ssh.Session +} + +func (s *Session) ContextWithSession(ctx context.Context) context.Context { + ctx = context.WithValue(ctx, "config", s.config) + ctx = context.WithValue(ctx, "ssh", s.SSH) + ctx = context.WithValue(ctx, "conn", s.conn) + return ctx +} + +// ActiveSession hold the currently active session. This can change when the user +// impersonate a other user. In this case, the connection will be replaced and the +// access token will also be changed to perform action on behalf of the +// impersonated user. The command `user logout` will also replace the active +// session back to the original user. +var ActiveSession Session + // NewGRPCConnection creates a new gRPC connection. We can not use the NewClient // function from the client package, because we need the grpc.ClientConn object // in order to open a new AdminClient. If we decide to expose the AdminClient @@ -51,3 +79,100 @@ func NewGRPCConnection(extraOptions ...interface{}) (*grpc.ClientConn, error) { return clientConn, nil } + +// ConnectToAPI connects to the API with the given credentials, depending +// on what credentials we have. +func ConnectToAPI() (*grpc.ClientConn, error) { + // Endpoint + endpoint := config.Endpoint + if os.Getenv("GPCORE_ENDPOINT") != "" { + endpoint = os.Getenv("GPCORE_ENDPOINT") + } + + var credOptions client.AuthProviderOption + + // We have two different connection methods available, depending on the + // type of credentials we get. For "normal" usage, we need the ClientID + // and the ClientSecret, which can be used by every user. + // Some endpoints need admin privileges, tho. For that, we need the + // username and password of the user. We can not use the same connection + // for that, so we need to reconnect with admin credentials. + + // First, we check if we have user/pass for admin login. If we have the + // credentials, we use it for login. + if config.HasAdminConfig() { + log.Info("Using admin credentials") + credOptions = &auth.ProviderKeycloakUserPassword{ + ClientID: ActiveSession.config.ClientID, + ClientSecret: ActiveSession.config.ClientSecret, + Username: *ActiveSession.config.Username, + Password: *ActiveSession.config.Password, + } + + // If we currently impersonate a user, we need to add the access token + // to the credentials, so we can access the resources of that user. + if ActiveSession.config.ImpersonateAccessToken != nil { + credOptions.Impersonate(&gocloak.JWT{ + AccessToken: *ActiveSession.config.ImpersonateAccessToken, + ExpiresIn: *ActiveSession.config.ImpersonateExpiresIn, + }) + } + + return NewGRPCConnection( + credOptions, + grpc.WithDefaultCallOptions( + grpc.MaxCallRecvMsgSize(math.MaxInt32), + grpc.MaxCallSendMsgSize(math.MaxInt32), + ), + client.EndpointOverrideOption(endpoint), + ) + } + + // Otherwise, we just use the client credentials. With this login, the + // admin endpoints will not work and result in an error. + credOptions = &auth.ProviderKeycloakClientAuth{ + ClientID: ActiveSession.config.ClientID, + ClientSecret: ActiveSession.config.ClientSecret, + } + return NewGRPCConnection( + credOptions, + grpc.WithDefaultCallOptions( + grpc.MaxCallRecvMsgSize(math.MaxInt32), + grpc.MaxCallSendMsgSize(math.MaxInt32), + ), + client.EndpointOverrideOption(endpoint), + ) +} + +// RenewAPISession restarts the API session with the currently set config from +// the config file and the keystore. Call this function if you change the session +// config. +func RenewAPISession() *grpc.ClientConn { + // Initialize a new session + err := config.RefreshSessionConfig() + if err != nil { + log.Fatal(err) + panic(err) + } + sessionConfig, err := config.GetSessionConfig() + if err != nil { + panic(err) + } + + ActiveSession = Session{ + config: sessionConfig, + } + + // Open new connection + newConnection, err := ConnectToAPI() + if err != nil { + log.Errorf("Can not connect to GPCORE API: %v", err) + log.Fatal("Check your config file and/or reset it with \"gpcore agent setup\"") + panic(err) + } + + ActiveSession.conn = newConnection + log.Debugf("Renewed GPCORE API session") + + return newConnection +} diff --git a/pkg/client/user.go b/pkg/client/user.go index 8066552..8a1d606 100644 --- a/pkg/client/user.go +++ b/pkg/client/user.go @@ -1,17 +1,25 @@ package client import ( + "context" + "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/auth/v1/authv1grpc" authv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/auth/v1" cloudv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/cloud/v1" - "context" + "github.com/G-PORTAL/gpcore-cli/pkg/config" "github.com/charmbracelet/log" "google.golang.org/grpc" ) -func GetUser(ctx context.Context) *cloudv1.User { +// GetUserFromContext return the gRPC user, which will be extracted from the +// context. +func GetUserFromContext(ctx context.Context) *cloudv1.User { conn := ctx.Value("conn").(*grpc.ClientConn) + return GetUser(conn) +} +// GetUser return the gRPC user from a connection. +func GetUser(conn *grpc.ClientConn) *cloudv1.User { authClient := authv1grpc.NewAuthServiceClient(conn) resp, err := authClient.GetUser(context.Background(), &authv1.GetUserRequest{}) if err != nil { @@ -21,3 +29,13 @@ func GetUser(ctx context.Context) *cloudv1.User { return resp.GetUser() } + +// IsImpersonated return true if the current acting user is an impersonated +// user and not the real user. +func IsImpersonated() bool { + cfg, err := config.GetSessionConfig() + if err != nil { + return false + } + return cfg.ImpersonateAccessToken != nil +} diff --git a/pkg/config/config.go b/pkg/config/config.go index 5605c5a..a9b3b0c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -2,12 +2,13 @@ package config import ( "errors" + "os" + "github.com/G-PORTAL/gpcore-go/pkg/gpcore/client" "github.com/charmbracelet/log" - "os" ) -// ConfigFilePath is the path to the config file used to store the session config. The +// FilePath is the path to the config file used to store the session config. The // default value is ~/.config/gpcore/config.yaml. This can be overwritten by setting the // environment variable GPCORE_CONFIG or by passing the --config flag to the // gpc command. @@ -96,24 +97,33 @@ func AskForAdminCredentials() (string, string) { return username, password } -func GetSessionConfig() (*SessionConfig, error) { - if sessionConfig != nil { - return sessionConfig, nil - } - +func RefreshSessionConfig() error { sessionConfig = &SessionConfig{} // No config file found? if !HasConfig() { log.Errorf("No config file found at %s", FilePath) log.Errorf("Create a new config file with \"gpcore agent setup\"") - return nil, errors.New("no config file found") + return errors.New("no config file found") } // Read in config file err := sessionConfig.Read() if err != nil { log.Errorf("Error reading config: %s", err) + return err + } + + return nil +} + +func GetSessionConfig() (*SessionConfig, error) { + if sessionConfig != nil { + return sessionConfig, nil + } + err := RefreshSessionConfig() + if err != nil { + log.Errorf("Error refreshing session config: %s", err) return nil, err } diff --git a/pkg/config/session_config.go b/pkg/config/session_config.go index 6c8c91c..62ebfef 100644 --- a/pkg/config/session_config.go +++ b/pkg/config/session_config.go @@ -1,9 +1,10 @@ package config import ( + "os" + "github.com/charmbracelet/log" "gopkg.in/yaml.v3" - "os" ) // SessionConfig holds session related credentials and other information @@ -24,6 +25,10 @@ type SessionConfig struct { Username *string `yaml:"username,omitempty"` Password *string `yaml:"password,omitempty"` + // Impersonate another user (admin only) + ImpersonateAccessToken *string `yaml:"impersonate_access_token,omitempty"` + ImpersonateExpiresIn *int `yaml:"impersonate_expires_in,omitempty"` + // Session related stuff CurrentProject *string `yaml:"current_project"` @@ -57,13 +62,16 @@ func (c *SessionConfig) Write() error { return err } + cleanedSessionConfig := c + // Remove sensitive data from struct - c.PrivateKeyPassword = nil - c.Password = nil - c.ClientSecret = "" + cleanedSessionConfig.PrivateKeyPassword = nil + cleanedSessionConfig.Password = nil + cleanedSessionConfig.ClientSecret = "" + cleanedSessionConfig.ImpersonateAccessToken = nil // Convert to yaml - data, err := yaml.Marshal(c) + data, err := yaml.Marshal(cleanedSessionConfig) if err != nil { return err } diff --git a/pkg/config/sources.go b/pkg/config/sources.go index dbc73be..19d395c 100644 --- a/pkg/config/sources.go +++ b/pkg/config/sources.go @@ -3,11 +3,12 @@ package config import ( "bufio" "errors" - "github.com/G-PORTAL/gpcore-cli/pkg/consts" - "github.com/G-PORTAL/gpcore-cli/pkg/secret" "os" "path" "strings" + + "github.com/G-PORTAL/gpcore-cli/pkg/consts" + "github.com/G-PORTAL/gpcore-cli/pkg/secret" ) func init() { @@ -40,6 +41,12 @@ func GetSecretsFromKeyring(config *SessionConfig) error { config.Password = &password } + // Impersonate access token + impersonateAccessToken, err := ring.Get("impersonate_access_token") + if err == nil { + config.ImpersonateAccessToken = &impersonateAccessToken + } + return nil } @@ -69,6 +76,19 @@ func StoreSecretsInKeyring(config *SessionConfig) error { } } + // Impersonate access token + if config.ImpersonateAccessToken != nil { + err := ring.Set("impersonate_access_token", *config.ImpersonateAccessToken) + if err != nil { + return err + } + } else { + err := ring.Remove("impersonate_access_token") + if err != nil { + return err + } + } + return nil } From d03c5714f25c529f82cd822b6a557631f97a7292 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Fri, 19 Sep 2025 10:40:27 +0200 Subject: [PATCH 04/11] feat(impersonate): proper handling of the session Proper handling of the current user session, even if the server crashes or the user uses the `use` command to set up a project, logout or stop the server. Ticket: TV-873 Signed-off-by: Aaron Fischer --- README.md | 7 ++++--- cmd/agent/start.go | 11 ++++++++++ cmd/project/use.go | 48 +++++++++++++++---------------------------- cmd/user/details.go | 7 ++++++- cmd/user/logout.go | 12 +++++------ pkg/client/user.go | 6 +++--- pkg/config/setup.go | 5 +++-- pkg/config/sources.go | 10 ++++++--- 8 files changed, 57 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index dead16b..82cc5b5 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,10 @@ the GPCORE panel under https://panel.gpcore.io/user/settings/clients. A special case is the ```user impersonate``` command, which allows you to impersonate another user. This command needs admin permissions, and you need to use the -```gpcore-cli``` client ID for that (see Keycloak for the client secret). This -client is preconfigured to have the impersonate role. To stop impersonating -a user, use the `user logout` command. +```gpcore-cli``` client ID for that (see Bitwarden or Keycloak for the client +secret). This client is preconfigured to have the impersonate role. Further, your +admin user need the "impersonate-user" permission set in Keycloak. To stop +impersonating a user, use the `user logout` command. ### Admin permissions diff --git a/cmd/agent/start.go b/cmd/agent/start.go index e59f551..ab98a2b 100644 --- a/cmd/agent/start.go +++ b/cmd/agent/start.go @@ -34,6 +34,17 @@ var startCmd = &cobra.Command{ if err != nil { panic(err) } + + // If we have impersonated a user before the agent was stopped, we remove + // the access token and the expiry time, so the user start with his own + // user. + sessionConfig.ImpersonateAccessToken = nil + sessionConfig.ImpersonateExpiresIn = nil + err = sessionConfig.Write() + if err != nil { + panic(err) + } + api.RenewAPISession() server, err := wish.NewServer( diff --git a/cmd/project/use.go b/cmd/project/use.go index 2ffdcef..f05d409 100644 --- a/cmd/project/use.go +++ b/cmd/project/use.go @@ -1,11 +1,7 @@ package project import ( - "fmt" - - "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/admin/v1/adminv1grpc" "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/cloud/v1/cloudv1grpc" - adminv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/admin/v1" cloudv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/cloud/v1" "github.com/G-PORTAL/gpcore-cli/pkg/client" "github.com/G-PORTAL/gpcore-cli/pkg/config" @@ -23,42 +19,29 @@ var useCmd = &cobra.Command{ RunE: func(cobraCmd *cobra.Command, args []string) error { ctx := client.ExtractContext(cobraCmd) grpcConn := ctx.Value("conn").(*grpc.ClientConn) - client := cloudv1grpc.NewCloudServiceClient(grpcConn) + grpcClient := cloudv1grpc.NewCloudServiceClient(grpcConn) cfg := ctx.Value("config").(*config.SessionConfig) var newProject *cloudv1.Project - // If the user is an admin user, all projects can be selected. Otherwise, - // only projects the user is a member of can be selected. But in all - // cases, we check if the project exists. - if config.HasAdminConfig() { - adminClient := adminv1grpc.NewAdminServiceClient(grpcConn) - resp, err := adminClient.GetProject(ctx, &adminv1.GetProjectRequest{ - Id: args[0], - }) - if err != nil { - return fmt.Errorf("project not found") - } - - newProject = resp.Project - } else { - resp, err := client.ListProjects(cobraCmd.Context(), &cloudv1.ListProjectsRequest{}) - if err != nil { - return err - } + resp, err := grpcClient.ListProjects(cobraCmd.Context(), &cloudv1.ListProjectsRequest{}) + if err != nil { + return err + } - for _, project := range resp.Projects { - if (project.Name == args[0]) || (project.Id == args[0]) { - newProject = project - break - } + for _, project := range resp.Projects { + if (project.Name == args[0]) || (project.Id == args[0]) { + newProject = project + break } } - // If there is no project found (in the list of projects for the user or - // in the list of all projects for admin users), return an error. + // If there is no project found in the list of the current user (or the + // user currently impersonating), we need to raise an error. if newProject == nil { - return fmt.Errorf("project not found") + cobraCmd.Println("Project not found or not accessible.") + cobraCmd.Println("If you are an admin user, try impersonate first.") + return nil } // Set the new project as the current project in the config and save @@ -68,6 +51,9 @@ var useCmd = &cobra.Command{ if err := cfg.Write(); err != nil { return err } + if err := config.RefreshSessionConfig(); err != nil { + return err + } log.Info("Active project is now: " + newProject.Name) cobraCmd.Println("Active project is now: " + newProject.Name) diff --git a/cmd/user/details.go b/cmd/user/details.go index 5103662..1626c7f 100644 --- a/cmd/user/details.go +++ b/cmd/user/details.go @@ -38,7 +38,12 @@ var detailsCmd = &cobra.Command{ // If the user is impersonated, we add a warning to the output, so // the admin knows that this is just the impersonated user, not the // own user. - if client.IsImpersonated() { + isImpersonated, err := client.IsImpersonated() + if err != nil { + return err + } + + if isImpersonated { cobraCmd.Println("Impersonated user") } diff --git a/cmd/user/logout.go b/cmd/user/logout.go index 0f52de0..9c65188 100644 --- a/cmd/user/logout.go +++ b/cmd/user/logout.go @@ -22,7 +22,12 @@ var logoutCmd = &cobra.Command{ // If the impersonate access token is already nil, we no longer // impersonating anybody. - if !client.IsImpersonated() { + isImpersonated, err := client.IsImpersonated() + if err != nil { + return err + } + + if !isImpersonated { cobraCmd.Println("No need to logout, you do not impersonate anybody.") return nil } @@ -36,11 +41,6 @@ var logoutCmd = &cobra.Command{ return err } - err = config.RefreshSessionConfig() - if err != nil { - return err - } - api.RenewAPISession() log.Infof("No longer impersonating (id: %s) %s", user.GetId(), user.GetUsername()) diff --git a/pkg/client/user.go b/pkg/client/user.go index 8a1d606..3e66aea 100644 --- a/pkg/client/user.go +++ b/pkg/client/user.go @@ -32,10 +32,10 @@ func GetUser(conn *grpc.ClientConn) *cloudv1.User { // IsImpersonated return true if the current acting user is an impersonated // user and not the real user. -func IsImpersonated() bool { +func IsImpersonated() (bool, error) { cfg, err := config.GetSessionConfig() if err != nil { - return false + return false, err } - return cfg.ImpersonateAccessToken != nil + return cfg.ImpersonateAccessToken != nil, nil } diff --git a/pkg/config/setup.go b/pkg/config/setup.go index 0418455..3c43ff2 100644 --- a/pkg/config/setup.go +++ b/pkg/config/setup.go @@ -2,11 +2,12 @@ package config import ( "errors" + "os" + "path" + "github.com/G-PORTAL/gpcore-cli/pkg/secret" "github.com/charmbracelet/log" "gopkg.in/op/go-logging.v1" - "os" - "path" ) func SetupConfig() error { diff --git a/pkg/config/sources.go b/pkg/config/sources.go index 19d395c..50c553a 100644 --- a/pkg/config/sources.go +++ b/pkg/config/sources.go @@ -83,9 +83,13 @@ func StoreSecretsInKeyring(config *SessionConfig) error { return err } } else { - err := ring.Remove("impersonate_access_token") - if err != nil { - return err + // If we do not have set the access token, we also need to remove it + // from the keyring if still set there. + if _, err := ring.Get("impersonate_access_token"); err == nil { + err := ring.Remove("impersonate_access_token") + if err != nil { + return err + } } } From b16e0c5eadc6079e3cef94d2264fe741dfc4dce6 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Wed, 24 Sep 2025 10:19:58 +0200 Subject: [PATCH 05/11] fix(command): add node id to change-billing-period Ticket: TV-873 Signed-off-by: Aaron Fischer --- README.md | 2 +- pkg/generator/definition/node.yaml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 82cc5b5..63f3f0f 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ You can always add custom subcommands without generating it. Just add a new file to ```cmd/```. The file name will be the name of the subcommand. With hooks, you can inject code at some points in auto generated code. For -example, if you want to remove some colums, format certain colums or validate +example, if you want to remove some columns, format certain columns or validate input, you can do this with hooks. Create a file in the same package with the same name of the action (auto generated file), but with the prefix ```_pre.go``` to execute code before the action and ```_post.go``` to execute code after the diff --git a/pkg/generator/definition/node.yaml b/pkg/generator/definition/node.yaml index 59a1d6e..3bcd20b 100644 --- a/pkg/generator/definition/node.yaml +++ b/pkg/generator/definition/node.yaml @@ -170,10 +170,17 @@ actions: description: Node ID required: true + # DEPRECATED: This endpoint is no longer needed (just for migration), because + # We removed HOURLY billing and only support MONTHLY billing from now on. change-billing-period: api-call: cloud.ChangeNodeBillingPeriod description: Change the billing period of a node + identifier: nil params: + - name: id + type: string + description: Node ID + required: true - name: project_id type: string required: true @@ -181,6 +188,17 @@ actions: type: cloudv1.BillingPeriod default: cloudv1.BILLING_PERIOD_MONTHLY required: true + # TODO: This has currently no effect. We need a way to manipulate the JSON + # output for non nist endpoints when fields are specified. The output of this + # particular endpoint is mostly useless and is would be nice if we can limit + # the output to a limited set of fields of manipulate the output completely + # without rewriting the whole endpoint itself. + fields: + - ID + - FQDN + - PaidUntilAt + - BillingPeriod + - TargetBillingPeriod # change-rescue-mode is implemented in code, because rescue_mode is an object, # which is not supported by the generator. From 235794d2ccb0e941b8aeaecd515a239d92d37fb8 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Wed, 24 Sep 2025 10:25:08 +0200 Subject: [PATCH 06/11] chore(dependencies): update all dependencies Signed-off-by: Aaron Fischer --- go.mod | 56 ++++++++++++------------ go.sum | 136 +++++++++++++++++++++++++++------------------------------ 2 files changed, 94 insertions(+), 98 deletions(-) diff --git a/go.mod b/go.mod index f7ae179..79fbae2 100644 --- a/go.mod +++ b/go.mod @@ -1,46 +1,49 @@ module github.com/G-PORTAL/gpcore-cli -go 1.24.0 +go 1.24.6 + +// For development +//replace github.com/G-PORTAL/gpcore-go => ../gpcore-go require ( buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2 - buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.6-20250804091548-289250b42883.1 - github.com/G-PORTAL/gpcore-go v0.0.0-20240703125604-2cc907e0b5ef + buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.9-20250804091548-289250b42883.1 + github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f + github.com/Nerzal/gocloak/v13 v13.9.0 github.com/charmbracelet/log v0.4.2 - github.com/charmbracelet/ssh v0.0.0-20250429213052-383d50896132 + github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309 github.com/charmbracelet/wish v1.4.7 - github.com/creativeprojects/go-selfupdate v1.5.0 + github.com/creativeprojects/go-selfupdate v1.5.1 github.com/dave/jennifer v1.7.1 github.com/gertd/go-pluralize v0.2.1 github.com/jedib0t/go-pretty/v6 v6.6.8 github.com/melbahja/goph v1.4.0 - github.com/spf13/cobra v1.9.1 + github.com/spf13/cobra v1.10.1 github.com/stoewer/go-strcase v1.3.1 github.com/zalando/go-keyring v0.2.6 - golang.org/x/crypto v0.40.0 - google.golang.org/grpc v1.74.2 - google.golang.org/protobuf v1.36.6 + golang.org/x/crypto v0.42.0 + google.golang.org/grpc v1.75.1 + google.golang.org/protobuf v1.36.9 gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 gopkg.in/yaml.v3 v3.0.1 ) require ( al.essio.dev/pkg/shellescape v1.6.0 // indirect - buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1 // indirect - code.gitea.io/sdk/gitea v0.21.0 // indirect + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1 // indirect + code.gitea.io/sdk/gitea v0.22.0 // indirect github.com/42wim/httpsig v1.2.3 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect - github.com/Nerzal/gocloak/v13 v13.9.0 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/charmbracelet/bubbletea v1.3.6 // indirect - github.com/charmbracelet/colorprofile v0.3.1 // indirect + github.com/charmbracelet/bubbletea v1.3.10 // indirect + github.com/charmbracelet/colorprofile v0.3.2 // indirect github.com/charmbracelet/keygen v0.5.3 // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect github.com/charmbracelet/x/ansi v0.10.1 // indirect github.com/charmbracelet/x/cellbuf v0.0.13 // indirect - github.com/charmbracelet/x/conpty v0.1.0 // indirect - github.com/charmbracelet/x/errors v0.0.0-20250805141217-38fb69db254f // indirect + github.com/charmbracelet/x/conpty v0.1.1 // indirect + github.com/charmbracelet/x/errors v0.0.0-20250922100529-c9afca5d6f21 // indirect github.com/charmbracelet/x/term v0.2.1 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect github.com/creack/pty v1.1.24 // indirect @@ -59,7 +62,7 @@ require ( github.com/hashicorp/go-version v1.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kr/fs v0.1.0 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect @@ -71,16 +74,15 @@ require ( github.com/pkg/sftp v1.13.9 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/segmentio/ksuid v1.0.4 // indirect - github.com/spf13/pflag v1.0.7 // indirect - github.com/ulikunitz/xz v0.5.12 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/ulikunitz/xz v0.5.15 // indirect github.com/xanzy/go-gitlab v0.115.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect - golang.org/x/net v0.42.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.34.0 // indirect - golang.org/x/text v0.27.0 // indirect - golang.org/x/time v0.12.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect + golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/oauth2 v0.31.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 // indirect ) diff --git a/go.sum b/go.sum index 270fc50..35f00c4 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,17 @@ al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA= al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1 h1:Lg6klmCi3v7VvpqeeLEER9/m5S8y9e9DjhqQnSCNy4k= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1/go.mod h1:avRlCjnFzl98VPaeCtJ24RrV/wwHFzB8sWXhj26+n/U= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1 h1:DQLS/rRxLHuugVzjJU5AvOwD57pdFl9he/0O7e5P294= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1/go.mod h1:aY3zbkNan5F+cGm9lITDP6oxJIwu0dn9KjJuJjWaHkg= buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2 h1:6gjQy8rvNdpfbuzEPoimtQ2BD5hebvV9TMxiuNWQGCQ= buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2/go.mod h1:/rxp37k3p7xxCe1X1jfSNMtYowCkcEvhiDbL3tBpyWA= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.6-20250804091548-289250b42883.1 h1:LRXO8sra76/AEWJu/qs1d1/s6jqs28P7TSnALSkvur4= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.6-20250804091548-289250b42883.1/go.mod h1:RQUThbRAkbdfZFNIL9vAm4JOjaBysbEaROm7tgfpwVU= -code.gitea.io/sdk/gitea v0.21.0 h1:69n6oz6kEVHRo1+APQQyizkhrZrLsTLXey9142pfkD4= -code.gitea.io/sdk/gitea v0.21.0/go.mod h1:tnBjVhuKJCn8ibdyyhvUyxrR1Ca2KHEoTWoukNhXQPA= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.9-20250804091548-289250b42883.1 h1:oUYlXzAMRIm/umpdF+7CxjDc5BrLJTAc+SDTXW3xSKE= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.9-20250804091548-289250b42883.1/go.mod h1:9cZ5Dad/JncDI9XPW3QDXovAAL/bj/Ro+/fPcBL0uIw= +code.gitea.io/sdk/gitea v0.22.0 h1:HCKq7bX/HQ85Nw7c/HAhWgRye+vBp5nQOE8Md1+9Ef0= +code.gitea.io/sdk/gitea v0.22.0/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs= github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM= -github.com/G-PORTAL/gpcore-go v0.0.0-20240703125604-2cc907e0b5ef h1:/6YwHctb2wMe8o72u/WlwzIRsAJ8fiOKnEimKlwsG+k= -github.com/G-PORTAL/gpcore-go v0.0.0-20240703125604-2cc907e0b5ef/go.mod h1:CoJMebbI1HNVoUR6iATl1QfoDSyfjC+BbeGH1kDZS7k= +github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f h1:gvIRcU/B46blquBfuf/oVEzmnlW3etX0R6a9Oa1Mbs0= +github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f/go.mod h1:CoJMebbI1HNVoUR6iATl1QfoDSyfjC+BbeGH1kDZS7k= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Nerzal/gocloak/v13 v13.9.0 h1:YWsJsdM5b0yhM2Ba3MLydiOlujkBry4TtdzfIzSVZhw= @@ -20,32 +20,28 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/charmbracelet/bubbletea v1.3.6 h1:VkHIxPJQeDt0aFJIsVxw8BQdh/F/L2KKZGsK6et5taU= -github.com/charmbracelet/bubbletea v1.3.6/go.mod h1:oQD9VCRQFF8KplacJLo28/jofOI2ToOfGYeFgBBxHOc= -github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40= -github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0= +github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= +github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= +github.com/charmbracelet/colorprofile v0.3.2 h1:9J27WdztfJQVAQKX2WOlSSRB+5gaKqqITmrvb1uTIiI= +github.com/charmbracelet/colorprofile v0.3.2/go.mod h1:mTD5XzNeWHj8oqHb+S1bssQb7vIHbepiebQ2kPKVKbI= github.com/charmbracelet/keygen v0.5.3 h1:2MSDC62OUbDy6VmjIE2jM24LuXUvKywLCmaJDmr/Z/4= github.com/charmbracelet/keygen v0.5.3/go.mod h1:TcpNoMAO5GSmhx3SgcEMqCrtn8BahKhB8AlwnLjRUpk= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw= -github.com/charmbracelet/ssh v0.0.0-20250429213052-383d50896132 h1:ILyX/vWS/SeHfyuMFAsaV95jEKrwivNUkA8tE7JEXs4= -github.com/charmbracelet/ssh v0.0.0-20250429213052-383d50896132/go.mod h1:R9cISUs5kAH4Cq/rguNbSwcR+slE5Dfm8FEs//uoIGE= +github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309 h1:dCVbCRRtg9+tsfiTXTp0WupDlHruAXyp+YoxGVofHHc= +github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309/go.mod h1:R9cISUs5kAH4Cq/rguNbSwcR+slE5Dfm8FEs//uoIGE= github.com/charmbracelet/wish v1.4.7 h1:O+jdLac3s6GaqkOHHSwezejNK04vl6VjO1A+hl8J8Yc= github.com/charmbracelet/wish v1.4.7/go.mod h1:OBZ8vC62JC5cvbxJLh+bIWtG7Ctmct+ewziuUWK+G14= -github.com/charmbracelet/x/ansi v0.9.3 h1:BXt5DHS/MKF+LjuK4huWrC6NCvHtexww7dMayh6GXd0= -github.com/charmbracelet/x/ansi v0.9.3/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k= github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= -github.com/charmbracelet/x/conpty v0.1.0 h1:4zc8KaIcbiL4mghEON8D72agYtSeIgq8FSThSPQIb+U= -github.com/charmbracelet/x/conpty v0.1.0/go.mod h1:rMFsDJoDwVmiYM10aD4bH2XiRgwI7NYJtQgl5yskjEQ= -github.com/charmbracelet/x/errors v0.0.0-20250725211024-d60e1b0112b2 h1:A1ebXSCQAvgQauzUL1JzHF9w2x7nvf3HLBWuRwDPoaE= -github.com/charmbracelet/x/errors v0.0.0-20250725211024-d60e1b0112b2/go.mod h1:nmnmDtAEAq9i8KHhoYE3SvXMjYPuS219MWbawvAumQ4= -github.com/charmbracelet/x/errors v0.0.0-20250805141217-38fb69db254f h1:SbcVs3s906tLdfiJG+ooJpZxDVZCt5ShdDOjl1LX8qY= -github.com/charmbracelet/x/errors v0.0.0-20250805141217-38fb69db254f/go.mod h1:nmnmDtAEAq9i8KHhoYE3SvXMjYPuS219MWbawvAumQ4= +github.com/charmbracelet/x/conpty v0.1.1 h1:s1bUxjoi7EpqiXysVtC+a8RrvPPNcNvAjfi4jxsAuEs= +github.com/charmbracelet/x/conpty v0.1.1/go.mod h1:OmtR77VODEFbiTzGE9G1XiRJAga6011PIm4u5fTNZpk= +github.com/charmbracelet/x/errors v0.0.0-20250922100529-c9afca5d6f21 h1:hEZp21B03sMDSyChx2152zUm43m5b2A3WykdyvOaZkI= +github.com/charmbracelet/x/errors v0.0.0-20250922100529-c9afca5d6f21/go.mod h1:O2BTD/aMVQDmrvqroIO3fB6zXUuU07ZpVt21QTmZjRg= github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= @@ -53,8 +49,8 @@ github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= -github.com/creativeprojects/go-selfupdate v1.5.0 h1:4zuFafc/qGpymx7umexxth2y2lJXoBR49c3uI0Hr+zU= -github.com/creativeprojects/go-selfupdate v1.5.0/go.mod h1:Pewm8hY7Xe1ne7P8irVBAFnXjTkRuxbbkMlBeTdumNQ= +github.com/creativeprojects/go-selfupdate v1.5.1 h1:fuyEGFFfqcC8SxDGolcEPYPLXGQ9Mcrc5uRyRG2Mqnk= +github.com/creativeprojects/go-selfupdate v1.5.1/go.mod h1:2uY75rP8z/D/PBuDn6mlBnzu+ysEmwOJfcgF8np0JIM= github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo= @@ -114,8 +110,8 @@ github.com/jedib0t/go-pretty/v6 v6.6.8 h1:JnnzQeRz2bACBobIaa/r+nqjvws4yEhcmaZ4n1 github.com/jedib0t/go-pretty/v6 v6.6.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= +github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -147,11 +143,11 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= -github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= +github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs= github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -164,10 +160,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= -github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= +github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/xanzy/go-gitlab v0.115.0 h1:6DmtItNcVe+At/liXSgfE/DZNZrGfalQmBRmOcJjOn8= github.com/xanzy/go-gitlab v0.115.0/go.mod h1:5XCDtM7AM6WMKmfDdOiEpyRWUqui2iS9ILfvCZ2gJ5M= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= @@ -177,16 +173,16 @@ github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8u github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= -go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= @@ -197,10 +193,10 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= -golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= -golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4= -golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -217,11 +213,11 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= -golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= +golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -229,8 +225,6 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -247,8 +241,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= -golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -258,8 +252,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= -golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -270,10 +264,10 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= -golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -282,15 +276,15 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58 golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 h1:MAKi5q709QWfnkkpNQ0M12hYJ1+e8qYVDyowc4U1XZM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b h1:zPKJod4w6F1+nRGDI9ubnXYhU9NSWoFAijkHkUXeTK8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 h1:V1jCN2HBa8sySkR5vLcCSqJSTMv093Rw9EJefhQGP7M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ= +google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= +google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 h1:wO6teAQa+/6NqTzys8iAd3kWzcWWzrIhLZOdTGfDYAo= From 3f97d22b29eb415d408a0790494eeb12c41187c4 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Fri, 14 Nov 2025 10:46:38 +0100 Subject: [PATCH 07/11] feat(auth): add option to change auth realm Useful to switch to staging environment. Signed-off-by: Aaron Fischer --- README.md | 16 ++++++++++++++++ cmd/agent/root.go | 10 ++++++---- pkg/api/connection.go | 7 +++++++ pkg/config/config.go | 5 +++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 63f3f0f..925a48c 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,22 @@ The client itself is a simple SSH client. It connects to the agent and sends commands to it. The result is printed to stdout. You can use the standard SSH command (ssh) to connect through it, but it is not that convenient. +### Using different environments + +It is possible to use the CLI with different GPCORE environments, like +staging or development. For that, you can set the API base URL and the +auth realm when the agent starts (`agent start` or first command). + +* `--endpoint` (or `GPCORE_ENDPOINT` environment variable): + Set the API base URL, efault is the production API. +* `--auth-realm` (or `GPCORE_AUTH_REALM` environment variable) + Set the auth realm, efault is set to the production realm (master). + +Remember, this will be set once the agent starts and will be used for all +subsequent commands. If you want to change the environment, you need to +stop the agent with `gpcore agent stop` and start it again with the new +parameters. + ## Usage The commandline tool is separated into subcommands. To get a list of all diff --git a/cmd/agent/root.go b/cmd/agent/root.go index 2271697..d0c9c2b 100644 --- a/cmd/agent/root.go +++ b/cmd/agent/root.go @@ -2,15 +2,16 @@ package agent import ( "fmt" + "net" + "strconv" + "time" + "github.com/G-PORTAL/gpcore-cli/cmd" "github.com/G-PORTAL/gpcore-cli/cmd/help" "github.com/G-PORTAL/gpcore-cli/pkg/config" "github.com/G-PORTAL/gpcore-cli/pkg/consts" "github.com/G-PORTAL/gpcore-go/pkg/gpcore/client" "github.com/spf13/cobra" - "net" - "strconv" - "time" ) var printVersion = false @@ -44,9 +45,10 @@ func New() *cobra.Command { // Application information rootCmd.Flags().BoolVarP(&printVersion, "version", "V", false, "print version information and quit") - // GPCORE API + // GPCORE API + Authentication/Authorization // TODO: Will set on first run (when agent starts),the following client calls will ignore these, so, move this to the agent only or reconnect the API on every change rootCmd.PersistentFlags().StringVarP(&config.Endpoint, "endpoint", "e", client.DefaultEndpoint, "set API endpoint") + rootCmd.PersistentFlags().StringVarP(&config.AuthRealm, "auth-realm", "r", "master", "set auth realm to use") // Output formats and verbosity rootCmd.PersistentFlags().BoolVarP(&config.Verbose, "verbose", "v", false, "verbose mode") diff --git a/pkg/api/connection.go b/pkg/api/connection.go index 8552b08..fffe153 100644 --- a/pkg/api/connection.go +++ b/pkg/api/connection.go @@ -89,6 +89,12 @@ func ConnectToAPI() (*grpc.ClientConn, error) { endpoint = os.Getenv("GPCORE_ENDPOINT") } + // Auth realm + authRealm := config.AuthRealm + if os.Getenv("GPCORE_AUTH_REALM") != "" { + authRealm = os.Getenv("GPCORE_AUTH_REALM") + } + var credOptions client.AuthProviderOption // We have two different connection methods available, depending on the @@ -107,6 +113,7 @@ func ConnectToAPI() (*grpc.ClientConn, error) { ClientSecret: ActiveSession.config.ClientSecret, Username: *ActiveSession.config.Username, Password: *ActiveSession.config.Password, + Realm: &authRealm, } // If we currently impersonate a user, we need to add the access token diff --git a/pkg/config/config.go b/pkg/config/config.go index a9b3b0c..3179d9e 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -32,6 +32,11 @@ var Verbose = false // not be changes for subsequent client calls (because the connection is open). var Endpoint = client.DefaultEndpoint +// AuthRealm is the authentication realm used by the client. This can be +// overwritten by setting the environment variable GPCORE_AUTH_REALM or by +// passing the --auth-realm flag to the gpc command. +var AuthRealm = "master" + var sessionConfig *SessionConfig func HasConfig() bool { From 6f90d4334aa67f21e679ceda8b9120a85d6f5540 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 17 Nov 2025 10:21:44 +0100 Subject: [PATCH 08/11] chore(deps): update all dependencies, including the actions and go itself --- .github/workflows/release.yml | 10 +++++----- .github/workflows/test.yml | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6590ed2..74a2e77 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,11 +18,11 @@ jobs: pull-requests: write # to be able to comment on released pull requests steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-tags: true - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: "lts/*" - name: Release @@ -30,9 +30,9 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: npx semantic-release - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: - go-version: '1.24.x' + go-version: '1.25.4' - name: Install quill CLI run: curl -sSfL https://raw.githubusercontent.com/anchore/quill/main/install.sh | sh -s -- -b /usr/local/bin - name: Check if snapshot build @@ -50,7 +50,7 @@ jobs: QUILL_NOTARY_KEY_ID: ${{ secrets.QUILL_NOTARY_KEY_ID }} QUILL_NOTARY_ISSUER: ${{ secrets.QUILL_NOTARY_ISSUER }} - name: Upload dist artifacts to GitHub when not on main - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: "!contains(github.ref, 'main')" with: name: gpcore diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a4134c8..26ff654 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,12 +6,12 @@ jobs: tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: - go-version: '1.22.x' + go-version: '1.25.4' - name: Install dependencies run: go mod download From bb90cf5e06bd81bb8c553c18fe7d4301120fcee8 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Tue, 18 Nov 2025 09:40:00 +0100 Subject: [PATCH 09/11] chore(deps): update all dependencies and go itself Signed-off-by: Aaron Fischer --- go.mod | 58 ++++++++++--------- go.sum | 178 +++++++++++++++++++++++---------------------------------- 2 files changed, 102 insertions(+), 134 deletions(-) diff --git a/go.mod b/go.mod index 79fbae2..ec56036 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/G-PORTAL/gpcore-cli -go 1.24.6 +go 1.25.4 // For development //replace github.com/G-PORTAL/gpcore-go => ../gpcore-go require ( - buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2 - buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.9-20250804091548-289250b42883.1 + buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2 + buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1 github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f github.com/Nerzal/gocloak/v13 v13.9.0 github.com/charmbracelet/log v0.4.2 @@ -16,44 +16,46 @@ require ( github.com/creativeprojects/go-selfupdate v1.5.1 github.com/dave/jennifer v1.7.1 github.com/gertd/go-pluralize v0.2.1 - github.com/jedib0t/go-pretty/v6 v6.6.8 + github.com/jedib0t/go-pretty/v6 v6.7.2 github.com/melbahja/goph v1.4.0 github.com/spf13/cobra v1.10.1 github.com/stoewer/go-strcase v1.3.1 github.com/zalando/go-keyring v0.2.6 - golang.org/x/crypto v0.42.0 - google.golang.org/grpc v1.75.1 - google.golang.org/protobuf v1.36.9 + golang.org/x/crypto v0.44.0 + google.golang.org/grpc v1.77.0 + google.golang.org/protobuf v1.36.10 gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 gopkg.in/yaml.v3 v3.0.1 ) require ( al.essio.dev/pkg/shellescape v1.6.0 // indirect - buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1 // indirect - code.gitea.io/sdk/gitea v0.22.0 // indirect + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1 // indirect + code.gitea.io/sdk/gitea v0.22.1 // indirect github.com/42wim/httpsig v1.2.3 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect - github.com/charmbracelet/colorprofile v0.3.2 // indirect - github.com/charmbracelet/keygen v0.5.3 // indirect + github.com/charmbracelet/colorprofile v0.3.3 // indirect + github.com/charmbracelet/keygen v0.5.4 // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect - github.com/charmbracelet/x/ansi v0.10.1 // indirect - github.com/charmbracelet/x/cellbuf v0.0.13 // indirect - github.com/charmbracelet/x/conpty v0.1.1 // indirect - github.com/charmbracelet/x/errors v0.0.0-20250922100529-c9afca5d6f21 // indirect - github.com/charmbracelet/x/term v0.2.1 // indirect + github.com/charmbracelet/x/ansi v0.11.1 // indirect + github.com/charmbracelet/x/cellbuf v0.0.14 // indirect + github.com/charmbracelet/x/conpty v0.2.0 // indirect + github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect + github.com/clipperhouse/displaywidth v0.6.0 // indirect + github.com/clipperhouse/stringish v0.1.1 // indirect + github.com/clipperhouse/uax29/v2 v2.3.0 // indirect github.com/creack/pty v1.1.24 // indirect - github.com/danieljoos/wincred v1.2.2 // indirect + github.com/danieljoos/wincred v1.2.3 // indirect github.com/davidmz/go-pageant v1.0.2 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-fed/httpsig v1.1.0 // indirect - github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-logfmt/logfmt v0.6.1 // indirect github.com/go-resty/resty/v2 v2.16.5 // indirect - github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/godbus/dbus/v5 v5.2.0 // indirect github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/google/go-github/v30 v30.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect @@ -65,24 +67,24 @@ require ( github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.19 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.16.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pkg/sftp v1.13.9 // indirect + github.com/pkg/sftp v1.13.10 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/segmentio/ksuid v1.0.4 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/ulikunitz/xz v0.5.15 // indirect github.com/xanzy/go-gitlab v0.115.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect - golang.org/x/net v0.44.0 // indirect - golang.org/x/oauth2 v0.31.0 // indirect - golang.org/x/sys v0.36.0 // indirect - golang.org/x/text v0.29.0 // indirect - golang.org/x/time v0.13.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 // indirect + golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/oauth2 v0.33.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect + golang.org/x/time v0.14.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect ) diff --git a/go.sum b/go.sum index 35f00c4..3d89282 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,13 @@ al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA= al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1 h1:DQLS/rRxLHuugVzjJU5AvOwD57pdFl9he/0O7e5P294= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1/go.mod h1:aY3zbkNan5F+cGm9lITDP6oxJIwu0dn9KjJuJjWaHkg= -buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2 h1:6gjQy8rvNdpfbuzEPoimtQ2BD5hebvV9TMxiuNWQGCQ= -buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2/go.mod h1:/rxp37k3p7xxCe1X1jfSNMtYowCkcEvhiDbL3tBpyWA= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.9-20250804091548-289250b42883.1 h1:oUYlXzAMRIm/umpdF+7CxjDc5BrLJTAc+SDTXW3xSKE= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.9-20250804091548-289250b42883.1/go.mod h1:9cZ5Dad/JncDI9XPW3QDXovAAL/bj/Ro+/fPcBL0uIw= -code.gitea.io/sdk/gitea v0.22.0 h1:HCKq7bX/HQ85Nw7c/HAhWgRye+vBp5nQOE8Md1+9Ef0= -code.gitea.io/sdk/gitea v0.22.0/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1 h1:31on4W/yPcV4nZHL4+UCiCvLPsMqe/vJcNg8Rci0scc= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1/go.mod h1:fUl8CEN/6ZAMk6bP8ahBJPUJw7rbp+j4x+wCcYi2IG4= +buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2 h1:2mTDOUSt3hHaeAjxY5KljY2DXyMqO2iC15eiL4HK8nk= +buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2/go.mod h1:dTA7kNFwWSjEiP42gb1QA7V+B+aMi0Heq03BKqeULiU= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1 h1:4eZgyGoegoDwt1ZT9cR3f2oE/8Ys/csbiKnMYmxQ9xg= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1/go.mod h1:L7GAI5uJLx5y5vl+4w/x9kNWt0YaOZ6LfUEbhyv9Udg= +code.gitea.io/sdk/gitea v0.22.1 h1:7K05KjRORyTcTYULQ/AwvlVS6pawLcWyXZcTr7gHFyA= +code.gitea.io/sdk/gitea v0.22.1/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs= github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM= github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f h1:gvIRcU/B46blquBfuf/oVEzmnlW3etX0R6a9Oa1Mbs0= @@ -22,10 +22,10 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= -github.com/charmbracelet/colorprofile v0.3.2 h1:9J27WdztfJQVAQKX2WOlSSRB+5gaKqqITmrvb1uTIiI= -github.com/charmbracelet/colorprofile v0.3.2/go.mod h1:mTD5XzNeWHj8oqHb+S1bssQb7vIHbepiebQ2kPKVKbI= -github.com/charmbracelet/keygen v0.5.3 h1:2MSDC62OUbDy6VmjIE2jM24LuXUvKywLCmaJDmr/Z/4= -github.com/charmbracelet/keygen v0.5.3/go.mod h1:TcpNoMAO5GSmhx3SgcEMqCrtn8BahKhB8AlwnLjRUpk= +github.com/charmbracelet/colorprofile v0.3.3 h1:DjJzJtLP6/NZ8p7Cgjno0CKGr7wwRJGxWUwh2IyhfAI= +github.com/charmbracelet/colorprofile v0.3.3/go.mod h1:nB1FugsAbzq284eJcjfah2nhdSLppN2NqvfotkfRYP4= +github.com/charmbracelet/keygen v0.5.4 h1:XQYgf6UEaTGgQSSmiPpIQ78WfseNQp4Pz8N/c1OsrdA= +github.com/charmbracelet/keygen v0.5.4/go.mod h1:t4oBRr41bvK7FaJsAaAQhhkUuHslzFXVjOBwA55CZNM= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= @@ -34,25 +34,29 @@ github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309 h1:dCVbCRRtg9+ts github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309/go.mod h1:R9cISUs5kAH4Cq/rguNbSwcR+slE5Dfm8FEs//uoIGE= github.com/charmbracelet/wish v1.4.7 h1:O+jdLac3s6GaqkOHHSwezejNK04vl6VjO1A+hl8J8Yc= github.com/charmbracelet/wish v1.4.7/go.mod h1:OBZ8vC62JC5cvbxJLh+bIWtG7Ctmct+ewziuUWK+G14= -github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= -github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= -github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k= -github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= -github.com/charmbracelet/x/conpty v0.1.1 h1:s1bUxjoi7EpqiXysVtC+a8RrvPPNcNvAjfi4jxsAuEs= -github.com/charmbracelet/x/conpty v0.1.1/go.mod h1:OmtR77VODEFbiTzGE9G1XiRJAga6011PIm4u5fTNZpk= -github.com/charmbracelet/x/errors v0.0.0-20250922100529-c9afca5d6f21 h1:hEZp21B03sMDSyChx2152zUm43m5b2A3WykdyvOaZkI= -github.com/charmbracelet/x/errors v0.0.0-20250922100529-c9afca5d6f21/go.mod h1:O2BTD/aMVQDmrvqroIO3fB6zXUuU07ZpVt21QTmZjRg= -github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= -github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/charmbracelet/x/ansi v0.11.1 h1:iXAC8SyMQDJgtcz9Jnw+HU8WMEctHzoTAETIeA3JXMk= +github.com/charmbracelet/x/ansi v0.11.1/go.mod h1:M49wjzpIujwPceJ+t5w3qh2i87+HRtHohgb5iTyepL0= +github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4= +github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA= +github.com/charmbracelet/x/conpty v0.2.0 h1:eKtA2hm34qNfgJCDp/M6Dc0gLy7e07YEK4qAdNGOvVY= +github.com/charmbracelet/x/conpty v0.2.0/go.mod h1:fexgUnVrZgw8scD49f6VSi0Ggj9GWYIrpedRthAwW/8= +github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= +github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= +github.com/clipperhouse/displaywidth v0.6.0 h1:k32vueaksef9WIKCNcoqRNyKbyvkvkysNYnAWz2fN4s= +github.com/clipperhouse/displaywidth v0.6.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= +github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/creativeprojects/go-selfupdate v1.5.1 h1:fuyEGFFfqcC8SxDGolcEPYPLXGQ9Mcrc5uRyRG2Mqnk= github.com/creativeprojects/go-selfupdate v1.5.1/go.mod h1:2uY75rP8z/D/PBuDn6mlBnzu+ysEmwOJfcgF8np0JIM= -github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= -github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= +github.com/danieljoos/wincred v1.2.3 h1:v7dZC2x32Ut3nEfRH+vhoZGvN72+dQ/snVXo/vMFLdQ= +github.com/danieljoos/wincred v1.2.3/go.mod h1:6qqX0WNrS4RzPZ1tnroDzq9kY3fu1KwE7MRLQK4X0bs= github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo= github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -68,23 +72,22 @@ github.com/gertd/go-pluralize v0.2.1 h1:M3uASbVjMnTsPb0PNqg+E/24Vwigyo/tvyMTtAlL github.com/gertd/go-pluralize v0.2.1/go.mod h1:rbYaKDbsXxmRfr8uygAEKhOWsjyrrqrkHVpZvoOp8zk= github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= -github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= -github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkvE= +github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8= +github.com/godbus/dbus/v5 v5.2.0/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG16L+Oo= @@ -106,8 +109,8 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jedib0t/go-pretty/v6 v6.6.8 h1:JnnzQeRz2bACBobIaa/r+nqjvws4yEhcmaZ4n1QzsEc= -github.com/jedib0t/go-pretty/v6 v6.6.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= +github.com/jedib0t/go-pretty/v6 v6.7.2 h1:EYWgQNIH/+JsyHki7ns9OHyBKuHPkzrBo02uYjran7w= +github.com/jedib0t/go-pretty/v6 v6.7.2/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= @@ -118,8 +121,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= +github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs= github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= @@ -133,11 +136,10 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= -github.com/pkg/sftp v1.13.9 h1:4NGkvGudBL7GteO3m6qnaQ4pC0Kvf0onSVc9gR3EWBw= -github.com/pkg/sftp v1.13.9/go.mod h1:OBN7bVXdstkFFN/gdnHPUb5TE8eb8G1Rp9wCItqjkkA= +github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU= +github.com/pkg/sftp v1.13.10/go.mod h1:bJ1a7uDhrX/4OII+agvy28lzRvQrmIQuaHrcI1HbeGA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -171,37 +173,29 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJu github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= -golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= -golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 h1:zfMcR1Cs4KNuomFFgGefv5N0czO2XZpUbxGUy8i8ug0= +golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -209,22 +203,13 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= -golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= -golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -236,55 +221,36 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= -golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= -golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= -golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 h1:V1jCN2HBa8sySkR5vLcCSqJSTMv093Rw9EJefhQGP7M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= -google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= +google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 h1:wO6teAQa+/6NqTzys8iAd3kWzcWWzrIhLZOdTGfDYAo= From fd67fdf3a00c7b3aeb48497662e550a661ff9e0e Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Tue, 18 Nov 2025 09:40:29 +0100 Subject: [PATCH 10/11] fix(build): disable darwin builds for now Signed-off-by: Aaron Fischer --- .goreleaser.yaml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 1b51922..00ae61b 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -15,19 +15,20 @@ builds: ldflags: - "-s -w -X '{{ .ModulePath }}/cmd.version={{.Tag}}' -X '{{ .ModulePath }}/cmd.commit={{.Commit}}' -X '{{ .ModulePath }}/cmd.date={{.Date}}'" - - id: gpcore-macos - goos: - - darwin - ldflags: - - "-s -w -X '{{ .ModulePath }}/cmd.version={{.Tag}}' -X '{{ .ModulePath }}/cmd.commit={{.Commit}}' -X '{{ .ModulePath }}/cmd.date={{.Date}}'" - goarch: - - amd64 - - arm64 - hooks: - post: - - cmd: quill sign-and-notarize "{{ .Path }}" --dry-run={{ .IsSnapshot }} --ad-hoc={{ .IsSnapshot }} -vv - env: - - QUILL_LOG_FILE=/tmp/quill-{{ .Target }}.log +# TODO: Disabled for now due to a missing agreement from apple developer account. +# - id: gpcore-macos +# goos: +# - darwin +# ldflags: +# - "-s -w -X '{{ .ModulePath }}/cmd.version={{.Tag}}' -X '{{ .ModulePath }}/cmd.commit={{.Commit}}' -X '{{ .ModulePath }}/cmd.date={{.Date}}'" +# goarch: +# - amd64 +# - arm64 +# hooks: +# post: +# - cmd: quill sign-and-notarize "{{ .Path }}" --dry-run={{ .IsSnapshot }} --ad-hoc={{ .IsSnapshot }} -vv +# env: +# - QUILL_LOG_FILE=/tmp/quill-{{ .Target }}.log archives: - formats: From 0b7d1242d6e3a54d25cdd3f6622a0b0716660ceb Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Fri, 19 Dec 2025 10:40:35 +0100 Subject: [PATCH 11/11] chore(dependencies): update all dependencies, go version, action versions Ticket: TV-1092 Signed-off-by: Aaron Fischer --- .github/workflows/danger.yml | 2 +- .github/workflows/release.yml | 6 +-- .github/workflows/test.yml | 4 +- go.mod | 38 ++++++++--------- go.sum | 77 ++++++++++++++++++----------------- 5 files changed, 64 insertions(+), 63 deletions(-) diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index 83f365d..b159ab6 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest if: github.event_name == 'pull_request' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: ruby/setup-ruby@v1 with: ruby-version: '3.3' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 74a2e77..5ec40ec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: pull-requests: write # to be able to comment on released pull requests steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: fetch-tags: true - name: Setup Node.js @@ -32,7 +32,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v6 with: - go-version: '1.25.4' + go-version: '1.25.5' - name: Install quill CLI run: curl -sSfL https://raw.githubusercontent.com/anchore/quill/main/install.sh | sh -s -- -b /usr/local/bin - name: Check if snapshot build @@ -50,7 +50,7 @@ jobs: QUILL_NOTARY_KEY_ID: ${{ secrets.QUILL_NOTARY_KEY_ID }} QUILL_NOTARY_ISSUER: ${{ secrets.QUILL_NOTARY_ISSUER }} - name: Upload dist artifacts to GitHub when not on main - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 if: "!contains(github.ref, 'main')" with: name: gpcore diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 26ff654..140d577 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,12 +6,12 @@ jobs: tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Setup Go uses: actions/setup-go@v6 with: - go-version: '1.25.4' + go-version: '1.25.5' - name: Install dependencies run: go mod download diff --git a/go.mod b/go.mod index ec56036..c741058 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/G-PORTAL/gpcore-cli -go 1.25.4 +go 1.25.5 // For development //replace github.com/G-PORTAL/gpcore-go => ../gpcore-go require ( - buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2 - buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1 + buf.build/gen/go/gportal/gpcore/grpc/go v1.6.0-20251103085422-b156624a826d.1 + buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20251103085422-b156624a826d.1 github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f github.com/Nerzal/gocloak/v13 v13.9.0 github.com/charmbracelet/log v0.4.2 @@ -16,36 +16,36 @@ require ( github.com/creativeprojects/go-selfupdate v1.5.1 github.com/dave/jennifer v1.7.1 github.com/gertd/go-pluralize v0.2.1 - github.com/jedib0t/go-pretty/v6 v6.7.2 + github.com/jedib0t/go-pretty/v6 v6.7.7 github.com/melbahja/goph v1.4.0 - github.com/spf13/cobra v1.10.1 + github.com/spf13/cobra v1.10.2 github.com/stoewer/go-strcase v1.3.1 github.com/zalando/go-keyring v0.2.6 - golang.org/x/crypto v0.44.0 + golang.org/x/crypto v0.46.0 google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/protobuf v1.36.11 gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 gopkg.in/yaml.v3 v3.0.1 ) require ( al.essio.dev/pkg/shellescape v1.6.0 // indirect - buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1 // indirect + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 // indirect code.gitea.io/sdk/gitea v0.22.1 // indirect github.com/42wim/httpsig v1.2.3 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect - github.com/charmbracelet/colorprofile v0.3.3 // indirect + github.com/charmbracelet/colorprofile v0.4.1 // indirect github.com/charmbracelet/keygen v0.5.4 // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect - github.com/charmbracelet/x/ansi v0.11.1 // indirect + github.com/charmbracelet/x/ansi v0.11.3 // indirect github.com/charmbracelet/x/cellbuf v0.0.14 // indirect github.com/charmbracelet/x/conpty v0.2.0 // indirect github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect - github.com/clipperhouse/displaywidth v0.6.0 // indirect + github.com/clipperhouse/displaywidth v0.6.2 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect github.com/clipperhouse/uax29/v2 v2.3.0 // indirect github.com/creack/pty v1.1.24 // indirect @@ -54,14 +54,14 @@ require ( github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-logfmt/logfmt v0.6.1 // indirect - github.com/go-resty/resty/v2 v2.16.5 // indirect + github.com/go-resty/resty/v2 v2.17.1 // indirect github.com/godbus/dbus/v5 v5.2.0 // indirect github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/google/go-github/v30 v30.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kr/fs v0.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect @@ -80,11 +80,11 @@ require ( github.com/ulikunitz/xz v0.5.15 // indirect github.com/xanzy/go-gitlab v0.115.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect ) diff --git a/go.sum b/go.sum index 3d89282..1c10ab0 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA= al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1 h1:31on4W/yPcV4nZHL4+UCiCvLPsMqe/vJcNg8Rci0scc= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1/go.mod h1:fUl8CEN/6ZAMk6bP8ahBJPUJw7rbp+j4x+wCcYi2IG4= -buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2 h1:2mTDOUSt3hHaeAjxY5KljY2DXyMqO2iC15eiL4HK8nk= -buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2/go.mod h1:dTA7kNFwWSjEiP42gb1QA7V+B+aMi0Heq03BKqeULiU= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1 h1:4eZgyGoegoDwt1ZT9cR3f2oE/8Ys/csbiKnMYmxQ9xg= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1/go.mod h1:L7GAI5uJLx5y5vl+4w/x9kNWt0YaOZ6LfUEbhyv9Udg= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 h1:j9yeqTWEFrtimt8Nng2MIeRrpoCvQzM9/g25XTvqUGg= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1/go.mod h1:tvtbpgaVXZX4g6Pn+AnzFycuRK3MOz5HJfEGeEllXYM= +buf.build/gen/go/gportal/gpcore/grpc/go v1.6.0-20251103085422-b156624a826d.1 h1:rQT0OIQLVV3cts4cj9OjDhJ3Ho4/TL3Lq1wJIZ951+w= +buf.build/gen/go/gportal/gpcore/grpc/go v1.6.0-20251103085422-b156624a826d.1/go.mod h1:L/Fn0LfYaOU+jnZHI6VDZ66tPtYtoyIBg0tK5/QuGBE= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20251103085422-b156624a826d.1 h1:O66HGIt3igJB7DbDnBrjUd4IWz7bKB4MKDVOJFGqpZA= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20251103085422-b156624a826d.1/go.mod h1:P8EapWY+m/+4oATK4HFxRi9zB1QyW1oAz+yvxT4ckt4= code.gitea.io/sdk/gitea v0.22.1 h1:7K05KjRORyTcTYULQ/AwvlVS6pawLcWyXZcTr7gHFyA= code.gitea.io/sdk/gitea v0.22.1/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs= @@ -22,8 +22,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= -github.com/charmbracelet/colorprofile v0.3.3 h1:DjJzJtLP6/NZ8p7Cgjno0CKGr7wwRJGxWUwh2IyhfAI= -github.com/charmbracelet/colorprofile v0.3.3/go.mod h1:nB1FugsAbzq284eJcjfah2nhdSLppN2NqvfotkfRYP4= +github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= +github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= github.com/charmbracelet/keygen v0.5.4 h1:XQYgf6UEaTGgQSSmiPpIQ78WfseNQp4Pz8N/c1OsrdA= github.com/charmbracelet/keygen v0.5.4/go.mod h1:t4oBRr41bvK7FaJsAaAQhhkUuHslzFXVjOBwA55CZNM= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= @@ -34,8 +34,8 @@ github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309 h1:dCVbCRRtg9+ts github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309/go.mod h1:R9cISUs5kAH4Cq/rguNbSwcR+slE5Dfm8FEs//uoIGE= github.com/charmbracelet/wish v1.4.7 h1:O+jdLac3s6GaqkOHHSwezejNK04vl6VjO1A+hl8J8Yc= github.com/charmbracelet/wish v1.4.7/go.mod h1:OBZ8vC62JC5cvbxJLh+bIWtG7Ctmct+ewziuUWK+G14= -github.com/charmbracelet/x/ansi v0.11.1 h1:iXAC8SyMQDJgtcz9Jnw+HU8WMEctHzoTAETIeA3JXMk= -github.com/charmbracelet/x/ansi v0.11.1/go.mod h1:M49wjzpIujwPceJ+t5w3qh2i87+HRtHohgb5iTyepL0= +github.com/charmbracelet/x/ansi v0.11.3 h1:6DcVaqWI82BBVM/atTyq6yBoRLZFBsnoDoX9GCu2YOI= +github.com/charmbracelet/x/ansi v0.11.3/go.mod h1:yI7Zslym9tCJcedxz5+WBq+eUGMJT0bM06Fqy1/Y4dI= github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4= github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA= github.com/charmbracelet/x/conpty v0.2.0 h1:eKtA2hm34qNfgJCDp/M6Dc0gLy7e07YEK4qAdNGOvVY= @@ -44,8 +44,8 @@ github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSg github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= -github.com/clipperhouse/displaywidth v0.6.0 h1:k32vueaksef9WIKCNcoqRNyKbyvkvkysNYnAWz2fN4s= -github.com/clipperhouse/displaywidth v0.6.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= +github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo= +github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= @@ -78,8 +78,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= -github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= +github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4= +github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8= github.com/godbus/dbus/v5 v5.2.0/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= @@ -105,12 +105,12 @@ github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB1 github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jedib0t/go-pretty/v6 v6.7.2 h1:EYWgQNIH/+JsyHki7ns9OHyBKuHPkzrBo02uYjran7w= -github.com/jedib0t/go-pretty/v6 v6.7.2/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= +github.com/jedib0t/go-pretty/v6 v6.7.7 h1:Y1Id3lJ3k4UB8uwWWy3l8EVFnUlx5chR5+VbsofPNX0= +github.com/jedib0t/go-pretty/v6 v6.7.7/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= @@ -145,8 +145,8 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -185,16 +185,17 @@ go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6 go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= -golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= -golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 h1:zfMcR1Cs4KNuomFFgGefv5N0czO2XZpUbxGUy8i8ug0= -golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -203,11 +204,11 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -221,20 +222,20 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -245,12 +246,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 h1:wO6teAQa+/6NqTzys8iAd3kWzcWWzrIhLZOdTGfDYAo=