feat(cli) add --insecure flag to gordon remotes add
Allows setting insecure_tls per-remote from the CLI instead of manually editing remotes.toml. Also shows TLS status in remotes list.
- commit
- 5b20b2509e09b84d36d31d46fc4e7863c6cbc1fe
- author
- brice · · 2026-02-07 07:47 UTC
- parent
- 00c89f2
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
3 files · +25 -10
M docs/cli/remotes.md +4 -0
| @@ -59,6 +59,7 @@ gordon remotes add <name> <url> [options] | |||
| 59 | 59 | |--------|-------------| | |
| 60 | 60 | | `--token` | Store token directly in config | | |
| 61 | 61 | | `--token-env` | Store environment variable name (token resolved at runtime) | | |
| 62 | + | | `--insecure` | Skip TLS certificate verification for this remote | | |
| 62 | 63 | ||
| 63 | 64 | ### Examples | |
| 64 | 65 | ||
| @@ -71,6 +72,9 @@ gordon remotes add prod https://gordon.mydomain.com --token eyJ... | |||
| 71 | 72 | ||
| 72 | 73 | # With environment variable reference (recommended) | |
| 73 | 74 | gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN | |
| 75 | + | ||
| 76 | + | # With self-signed certificate | |
| 77 | + | gordon remotes add dev https://dev.internal --insecure | |
| 74 | 78 | ``` | |
| 75 | 79 | ||
| 76 | 80 | ### Token Security | |
| @@ -59,6 +59,7 @@ gordon remotes add <name> <url> [options] | |||||
| 59 | |--------|-------------| | 59 | |--------|-------------| | ||
| 60 | | `--token` | Store token directly in config | | 60 | | `--token` | Store token directly in config | | ||
| 61 | | `--token-env` | Store environment variable name (token resolved at runtime) | | 61 | | `--token-env` | Store environment variable name (token resolved at runtime) | | ||
| 62 | + | | `--insecure` | Skip TLS certificate verification for this remote | | |||
| 62 | 63 | ||||
| 63 | ### Examples | 64 | ### Examples | ||
| 64 | 65 | ||||
| @@ -71,6 +72,9 @@ gordon remotes add prod https://gordon.mydomain.com --token eyJ... | |||||
| 71 | 72 | ||||
| 72 | # With environment variable reference (recommended) | 73 | # With environment variable reference (recommended) | ||
| 73 | gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN | 74 | gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN | ||
| 75 | + | ||||
| 76 | + | # With self-signed certificate | |||
| 77 | + | gordon remotes add dev https://dev.internal --insecure | |||
| 74 | ``` | 78 | ``` | ||
| 75 | 79 | ||||
| 76 | ### Token Security | 80 | ### Token Security | ||
M internal/adapters/in/cli/remote/config.go +4 -3
| @@ -248,15 +248,16 @@ func resolveInsecureTLS(flagInsecure bool, config *ClientConfig, remotes *Client | |||
| 248 | 248 | } | |
| 249 | 249 | ||
| 250 | 250 | // AddRemote adds a new remote to the remotes configuration. | |
| 251 | - | func AddRemote(name, url, token string) error { | |
| 251 | + | func AddRemote(name, url, token string, insecureTLS bool) error { | |
| 252 | 252 | config, err := LoadRemotes("") | |
| 253 | 253 | if err != nil { | |
| 254 | 254 | return err | |
| 255 | 255 | } | |
| 256 | 256 | ||
| 257 | 257 | config.Remotes[name] = RemoteEntry{ | |
| 258 | - | URL: url, | |
| 259 | - | Token: token, | |
| 258 | + | URL: url, | |
| 259 | + | Token: token, | |
| 260 | + | InsecureTLS: insecureTLS, | |
| 260 | 261 | } | |
| 261 | 262 | ||
| 262 | 263 | return SaveRemotes("", config) | |
| @@ -248,15 +248,16 @@ func resolveInsecureTLS(flagInsecure bool, config *ClientConfig, remotes *Client | |||||
| 248 | } | 248 | } | ||
| 249 | 249 | ||||
| 250 | // AddRemote adds a new remote to the remotes configuration. | 250 | // AddRemote adds a new remote to the remotes configuration. | ||
| 251 | - | func AddRemote(name, url, token string) error { | 251 | + | func AddRemote(name, url, token string, insecureTLS bool) error { |
| 252 | config, err := LoadRemotes("") | 252 | config, err := LoadRemotes("") | ||
| 253 | if err != nil { | 253 | if err != nil { | ||
| 254 | return err | 254 | return err | ||
| 255 | } | 255 | } | ||
| 256 | 256 | ||||
| 257 | config.Remotes[name] = RemoteEntry{ | 257 | config.Remotes[name] = RemoteEntry{ | ||
| 258 | - | URL: url, | 258 | + | URL: url, |
| 259 | - | Token: token, | 259 | + | Token: token, |
| 260 | + | InsecureTLS: insecureTLS, | |||
| 260 | } | 261 | } | ||
| 261 | 262 | ||||
| 262 | return SaveRemotes("", config) | 263 | return SaveRemotes("", config) | ||
M internal/adapters/in/cli/remotes.go +17 -7
| @@ -71,7 +71,12 @@ func newRemotesListCmd() *cobra.Command { | |||
| 71 | 71 | tokenStatus = fmt.Sprintf("$%s", r.TokenEnv) | |
| 72 | 72 | } | |
| 73 | 73 | ||
| 74 | - | rows = append(rows, []string{name, r.URL, tokenStatus, status}) | |
| 74 | + | tlsStatus := "" | |
| 75 | + | if r.InsecureTLS { | |
| 76 | + | tlsStatus = styles.Theme.Warning.Render("insecure") | |
| 77 | + | } | |
| 78 | + | ||
| 79 | + | rows = append(rows, []string{name, r.URL, tokenStatus, tlsStatus, status}) | |
| 75 | 80 | } | |
| 76 | 81 | ||
| 77 | 82 | // Render table | |
| @@ -80,6 +85,7 @@ func newRemotesListCmd() *cobra.Command { | |||
| 80 | 85 | {Title: "Name", Width: 15}, | |
| 81 | 86 | {Title: "URL", Width: 35}, | |
| 82 | 87 | {Title: "Token", Width: 15}, | |
| 88 | + | {Title: "TLS", Width: 10}, | |
| 83 | 89 | {Title: "Status", Width: 10}, | |
| 84 | 90 | }), | |
| 85 | 91 | components.WithRows(rows), | |
| @@ -96,6 +102,7 @@ func newRemotesListCmd() *cobra.Command { | |||
| 96 | 102 | func newRemotesAddCmd() *cobra.Command { | |
| 97 | 103 | var token string | |
| 98 | 104 | var tokenEnv string | |
| 105 | + | var insecureTLS bool | |
| 99 | 106 | ||
| 100 | 107 | cmd := &cobra.Command{ | |
| 101 | 108 | Use: "add <name> <url>", | |
| @@ -105,7 +112,8 @@ func newRemotesAddCmd() *cobra.Command { | |||
| 105 | 112 | Examples: | |
| 106 | 113 | gordon remotes add prod https://gordon.mydomain.com | |
| 107 | 114 | gordon remotes add prod https://gordon.mydomain.com --token eyJ... | |
| 108 | - | gordon remotes add staging https://staging.mydomain.com --token-env STAGING_TOKEN`, | |
| 115 | + | gordon remotes add staging https://staging.mydomain.com --token-env STAGING_TOKEN | |
| 116 | + | gordon remotes add dev https://dev.internal --insecure`, | |
| 109 | 117 | Args: cobra.ExactArgs(2), | |
| 110 | 118 | RunE: func(cmd *cobra.Command, args []string) error { | |
| 111 | 119 | name := args[0] | |
| @@ -115,11 +123,11 @@ Examples: | |||
| 115 | 123 | finalToken := token | |
| 116 | 124 | if tokenEnv != "" { | |
| 117 | 125 | // Store token_env reference instead of actual token | |
| 118 | - | if err := addRemoteWithEnv(name, url, tokenEnv); err != nil { | |
| 126 | + | if err := addRemoteWithEnv(name, url, tokenEnv, insecureTLS); err != nil { | |
| 119 | 127 | return fmt.Errorf("failed to add remote: %w", err) | |
| 120 | 128 | } | |
| 121 | 129 | } else { | |
| 122 | - | if err := remote.AddRemote(name, url, finalToken); err != nil { | |
| 130 | + | if err := remote.AddRemote(name, url, finalToken, insecureTLS); err != nil { | |
| 123 | 131 | return fmt.Errorf("failed to add remote: %w", err) | |
| 124 | 132 | } | |
| 125 | 133 | } | |
| @@ -136,20 +144,22 @@ Examples: | |||
| 136 | 144 | ||
| 137 | 145 | cmd.Flags().StringVar(&token, "token", "", "Authentication token") | |
| 138 | 146 | cmd.Flags().StringVar(&tokenEnv, "token-env", "", "Environment variable containing token") | |
| 147 | + | cmd.Flags().BoolVar(&insecureTLS, "insecure", false, "Skip TLS certificate verification") | |
| 139 | 148 | ||
| 140 | 149 | return cmd | |
| 141 | 150 | } | |
| 142 | 151 | ||
| 143 | 152 | // addRemoteWithEnv adds a remote with a token environment variable reference. | |
| 144 | - | func addRemoteWithEnv(name, url, tokenEnv string) error { | |
| 153 | + | func addRemoteWithEnv(name, url, tokenEnv string, insecureTLS bool) error { | |
| 145 | 154 | config, err := remote.LoadRemotes("") | |
| 146 | 155 | if err != nil { | |
| 147 | 156 | return err | |
| 148 | 157 | } | |
| 149 | 158 | ||
| 150 | 159 | config.Remotes[name] = remote.RemoteEntry{ | |
| 151 | - | URL: url, | |
| 152 | - | TokenEnv: tokenEnv, | |
| 160 | + | URL: url, | |
| 161 | + | TokenEnv: tokenEnv, | |
| 162 | + | InsecureTLS: insecureTLS, | |
| 153 | 163 | } | |
| 154 | 164 | ||
| 155 | 165 | return remote.SaveRemotes("", config) | |
| @@ -71,7 +71,12 @@ func newRemotesListCmd() *cobra.Command { | |||||
| 71 | tokenStatus = fmt.Sprintf("$%s", r.TokenEnv) | 71 | tokenStatus = fmt.Sprintf("$%s", r.TokenEnv) | ||
| 72 | } | 72 | } | ||
| 73 | 73 | ||||
| 74 | - | rows = append(rows, []string{name, r.URL, tokenStatus, status}) | 74 | + | tlsStatus := "" |
| 75 | + | if r.InsecureTLS { | |||
| 76 | + | tlsStatus = styles.Theme.Warning.Render("insecure") | |||
| 77 | + | } | |||
| 78 | + | ||||
| 79 | + | rows = append(rows, []string{name, r.URL, tokenStatus, tlsStatus, status}) | |||
| 75 | } | 80 | } | ||
| 76 | 81 | ||||
| 77 | // Render table | 82 | // Render table | ||
| @@ -80,6 +85,7 @@ func newRemotesListCmd() *cobra.Command { | |||||
| 80 | {Title: "Name", Width: 15}, | 85 | {Title: "Name", Width: 15}, | ||
| 81 | {Title: "URL", Width: 35}, | 86 | {Title: "URL", Width: 35}, | ||
| 82 | {Title: "Token", Width: 15}, | 87 | {Title: "Token", Width: 15}, | ||
| 88 | + | {Title: "TLS", Width: 10}, | |||
| 83 | {Title: "Status", Width: 10}, | 89 | {Title: "Status", Width: 10}, | ||
| 84 | }), | 90 | }), | ||
| 85 | components.WithRows(rows), | 91 | components.WithRows(rows), | ||
| @@ -96,6 +102,7 @@ func newRemotesListCmd() *cobra.Command { | |||||
| 96 | func newRemotesAddCmd() *cobra.Command { | 102 | func newRemotesAddCmd() *cobra.Command { | ||
| 97 | var token string | 103 | var token string | ||
| 98 | var tokenEnv string | 104 | var tokenEnv string | ||
| 105 | + | var insecureTLS bool | |||
| 99 | 106 | ||||
| 100 | cmd := &cobra.Command{ | 107 | cmd := &cobra.Command{ | ||
| 101 | Use: "add <name> <url>", | 108 | Use: "add <name> <url>", | ||
| @@ -105,7 +112,8 @@ func newRemotesAddCmd() *cobra.Command { | |||||
| 105 | Examples: | 112 | Examples: | ||
| 106 | gordon remotes add prod https://gordon.mydomain.com | 113 | gordon remotes add prod https://gordon.mydomain.com | ||
| 107 | gordon remotes add prod https://gordon.mydomain.com --token eyJ... | 114 | gordon remotes add prod https://gordon.mydomain.com --token eyJ... | ||
| 108 | - | gordon remotes add staging https://staging.mydomain.com --token-env STAGING_TOKEN`, | 115 | + | gordon remotes add staging https://staging.mydomain.com --token-env STAGING_TOKEN |
| 116 | + | gordon remotes add dev https://dev.internal --insecure`, | |||
| 109 | Args: cobra.ExactArgs(2), | 117 | Args: cobra.ExactArgs(2), | ||
| 110 | RunE: func(cmd *cobra.Command, args []string) error { | 118 | RunE: func(cmd *cobra.Command, args []string) error { | ||
| 111 | name := args[0] | 119 | name := args[0] | ||
| @@ -115,11 +123,11 @@ Examples: | |||||
| 115 | finalToken := token | 123 | finalToken := token | ||
| 116 | if tokenEnv != "" { | 124 | if tokenEnv != "" { | ||
| 117 | // Store token_env reference instead of actual token | 125 | // Store token_env reference instead of actual token | ||
| 118 | - | if err := addRemoteWithEnv(name, url, tokenEnv); err != nil { | 126 | + | if err := addRemoteWithEnv(name, url, tokenEnv, insecureTLS); err != nil { |
| 119 | return fmt.Errorf("failed to add remote: %w", err) | 127 | return fmt.Errorf("failed to add remote: %w", err) | ||
| 120 | } | 128 | } | ||
| 121 | } else { | 129 | } else { | ||
| 122 | - | if err := remote.AddRemote(name, url, finalToken); err != nil { | 130 | + | if err := remote.AddRemote(name, url, finalToken, insecureTLS); err != nil { |
| 123 | return fmt.Errorf("failed to add remote: %w", err) | 131 | return fmt.Errorf("failed to add remote: %w", err) | ||
| 124 | } | 132 | } | ||
| 125 | } | 133 | } | ||
| @@ -136,20 +144,22 @@ Examples: | |||||
| 136 | 144 | ||||
| 137 | cmd.Flags().StringVar(&token, "token", "", "Authentication token") | 145 | cmd.Flags().StringVar(&token, "token", "", "Authentication token") | ||
| 138 | cmd.Flags().StringVar(&tokenEnv, "token-env", "", "Environment variable containing token") | 146 | cmd.Flags().StringVar(&tokenEnv, "token-env", "", "Environment variable containing token") | ||
| 147 | + | cmd.Flags().BoolVar(&insecureTLS, "insecure", false, "Skip TLS certificate verification") | |||
| 139 | 148 | ||||
| 140 | return cmd | 149 | return cmd | ||
| 141 | } | 150 | } | ||
| 142 | 151 | ||||
| 143 | // addRemoteWithEnv adds a remote with a token environment variable reference. | 152 | // addRemoteWithEnv adds a remote with a token environment variable reference. | ||
| 144 | - | func addRemoteWithEnv(name, url, tokenEnv string) error { | 153 | + | func addRemoteWithEnv(name, url, tokenEnv string, insecureTLS bool) error { |
| 145 | config, err := remote.LoadRemotes("") | 154 | config, err := remote.LoadRemotes("") | ||
| 146 | if err != nil { | 155 | if err != nil { | ||
| 147 | return err | 156 | return err | ||
| 148 | } | 157 | } | ||
| 149 | 158 | ||||
| 150 | config.Remotes[name] = remote.RemoteEntry{ | 159 | config.Remotes[name] = remote.RemoteEntry{ | ||
| 151 | - | URL: url, | 160 | + | URL: url, |
| 152 | - | TokenEnv: tokenEnv, | 161 | + | TokenEnv: tokenEnv, |
| 162 | + | InsecureTLS: insecureTLS, | |||
| 153 | } | 163 | } | ||
| 154 | 164 | ||||
| 155 | return remote.SaveRemotes("", config) | 165 | return remote.SaveRemotes("", config) | ||