@@ -30,6 +30,7 @@ import (
3030 "github.com/chainloop-dev/chainloop/app/cli/internal/action"
3131 "github.com/chainloop-dev/chainloop/app/cli/internal/telemetry"
3232 "github.com/chainloop-dev/chainloop/app/cli/internal/telemetry/posthog"
33+ v1 "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1"
3334 "github.com/chainloop-dev/chainloop/internal/grpcconn"
3435 "github.com/golang-jwt/jwt/v4"
3536 "github.com/rs/zerolog"
@@ -72,13 +73,29 @@ type parsedToken struct {
7273// Environment variable prefix for vipers
7374const envPrefix = "CHAINLOOP"
7475
76+ func Execute (l zerolog.Logger ) error {
77+ rootCmd := NewRootCmd (l )
78+ if err := rootCmd .Execute (); err != nil {
79+ // The local file is pointing to the wrong organization, we remove it
80+ if v1 .IsUserNotMemberOfOrgErrorNotInOrg (err ) {
81+ if err := setLocalOrganization ("" ); err != nil {
82+ logger .Debug ().Err (err ).Msg ("failed to remove organization from config" )
83+ }
84+ }
85+
86+ return err
87+ }
88+
89+ return nil
90+ }
91+
7592func NewRootCmd (l zerolog.Logger ) * cobra.Command {
7693 rootCmd := & cobra.Command {
7794 Use : appName ,
7895 Short : "Chainloop Command Line Interface" ,
7996 SilenceErrors : true ,
8097 SilenceUsage : true ,
81- PersistentPreRunE : func (cmd * cobra.Command , args []string ) error {
98+ PersistentPreRunE : func (cmd * cobra.Command , _ []string ) error {
8299 var err error
83100 logger , err = initLogger (l )
84101 if err != nil {
@@ -105,11 +122,31 @@ func NewRootCmd(l zerolog.Logger) *cobra.Command {
105122 }
106123
107124 controlplaneURL := viper .GetString (confOptions .controlplaneAPI .viperKey )
125+
126+ // If no organization is set in local configuration, we load it from server and save it
127+ if viper .GetString (confOptions .organization .viperKey ) == "" {
128+ conn , err := grpcconn .New (controlplaneURL , apiToken , opts ... )
129+ if err != nil {
130+ return err
131+ }
132+
133+ currentContext , err := action .NewConfigCurrentContext (newActionOpts (logger , conn )).Run ()
134+ if err == nil && currentContext .CurrentMembership != nil {
135+ if err := setLocalOrganization (currentContext .CurrentMembership .Org .Name ); err != nil {
136+ return fmt .Errorf ("writing config file: %w" , err )
137+ }
138+ }
139+ }
140+
141+ // reload the connection now that we have the org name
142+ if orgName := viper .GetString (confOptions .organization .viperKey ); orgName != "" {
143+ opts = append (opts , grpcconn .WithOrgName (orgName ))
144+ }
145+
108146 conn , err := grpcconn .New (controlplaneURL , apiToken , opts ... )
109147 if err != nil {
110148 return err
111149 }
112-
113150 actionOpts = newActionOpts (logger , conn )
114151
115152 if ! isTelemetryDisabled () {
@@ -152,7 +189,7 @@ func NewRootCmd(l zerolog.Logger) *cobra.Command {
152189
153190 return nil
154191 },
155- PersistentPostRunE : func (cmd * cobra.Command , args []string ) error {
192+ PersistentPostRunE : func (_ * cobra.Command , _ []string ) error {
156193 return cleanup (actionOpts .CPConnection )
157194 },
158195 }
@@ -189,6 +226,9 @@ func NewRootCmd(l zerolog.Logger) *cobra.Command {
189226 // Override the oauth authentication requirement for the CLI by providing an API token
190227 rootCmd .PersistentFlags ().StringVarP (& apiToken , "token" , "t" , "" , fmt .Sprintf ("API token. NOTE: Alternatively use the env variable %s" , tokenEnvVarName ))
191228
229+ rootCmd .PersistentFlags ().StringP (confOptions .organization .flagName , "n" , "" , "organization name" )
230+ cobra .CheckErr (viper .BindPFlag (confOptions .organization .viperKey , rootCmd .PersistentFlags ().Lookup (confOptions .organization .flagName )))
231+
192232 rootCmd .AddCommand (newWorkflowCmd (), newAuthCmd (), NewVersionCmd (),
193233 newAttestationCmd (), newArtifactCmd (), newConfigCmd (),
194234 newIntegrationCmd (), newOrganizationCmd (), newCASBackendCmd (),
@@ -453,3 +493,9 @@ func hashControlPlaneURL() string {
453493func apiInsecure () bool {
454494 return viper .GetBool (confOptions .insecure .viperKey )
455495}
496+
497+ // setLocalOrganization updates the local organization configuration
498+ func setLocalOrganization (orgName string ) error {
499+ viper .Set (confOptions .organization .viperKey , orgName )
500+ return viper .WriteConfig ()
501+ }
0 commit comments