diff --git a/README.md b/README.md index d54739f..b50682b 100644 --- a/README.md +++ b/README.md @@ -32,3 +32,20 @@ How to run integration test: ./test_final_exec.sh ``` +## How to use behind teleport + +First login to your teleport proxy, for example: +``` +tsh login --proxy=teleport-01.prd.tooling.cdkt.dev --auth=github +``` + +``` +conduktor get application --cert $(tsh apps config --format=cert) --key $(tsh apps config --format=key) +``` + +Or: +``` +export CDK_CERT=$(tsh apps config --format=cert) +export CDK_KEY=$(tsh apps config --format=key) +conduktor get application +``` diff --git a/client/client.go b/client/client.go index d55b4c2..48c7c6e 100644 --- a/client/client.go +++ b/client/client.go @@ -1,6 +1,7 @@ package client import ( + "crypto/tls" "encoding/json" "fmt" "os" @@ -17,15 +18,16 @@ type Client struct { client *resty.Client } -func Make(token string, baseUrl string, debug bool) Client { +func Make(token string, baseUrl string, debug bool, key, cert string) Client { + certificate, _ := tls.LoadX509KeyPair(cert, key) return Client{ token: token, baseUrl: baseUrl, - client: resty.New().SetDebug(debug).SetHeader("Authorization", "Bearer "+token), + client: resty.New().SetDebug(debug).SetHeader("Authorization", "Bearer "+token).SetCertificates(certificate), } } -func MakeFromEnv(debug bool) Client { +func MakeFromEnv(debug bool, key, cert string) Client { token := os.Getenv("CDK_TOKEN") if token == "" { fmt.Fprintln(os.Stderr, "Please set CDK_TOKEN") @@ -36,8 +38,16 @@ func MakeFromEnv(debug bool) Client { fmt.Fprintln(os.Stderr, "Please set CDK_BASE_URL") os.Exit(2) } + finalKey := key + finalCert := cert + if finalKey == "" { + finalKey = os.Getenv("CDK_KEY") + } + if finalCert == "" { + finalCert = os.Getenv("CDK_CERT") + } - return Make(token, baseUrl, debug) + return Make(token, baseUrl, debug, finalKey, finalCert) } type UpsertResponse struct { diff --git a/client/client_test.go b/client/client_test.go index 0f4d955..cc8dfb5 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -11,7 +11,7 @@ func TestApplyShouldWork(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) @@ -46,7 +46,7 @@ func TestApplyWithDryModeShouldWork(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) @@ -81,7 +81,7 @@ func TestApplyShouldFailIfNo2xx(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) @@ -116,7 +116,7 @@ func TestGetShouldWork(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) @@ -143,7 +143,7 @@ func TestGetShouldApplyCaseTransformation(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) @@ -170,7 +170,7 @@ func TestGetShouldKeepCase(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) @@ -197,7 +197,7 @@ func TestGetShouldFailIfN2xx(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) @@ -224,7 +224,7 @@ func TestDescribeShouldWork(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) @@ -251,7 +251,7 @@ func TestDescribeShouldFailIfNo2xx(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) @@ -278,7 +278,7 @@ func TestDeleteShouldWork(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) @@ -304,7 +304,7 @@ func TestDeleteShouldFailOnNot2XX(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" token := "aToken" - client := Make(token, baseUrl, false) + client := Make(token, baseUrl, false, "", "") httpmock.ActivateNonDefault( client.client.GetClient(), ) diff --git a/cmd/apply.go b/cmd/apply.go index d6a0cb2..8b56e8f 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -26,7 +26,7 @@ var applyCmd = &cobra.Command{ } resources = append(resources, r...) } - client := client.MakeFromEnv(*debug) + client := client.MakeFromEnv(*debug, *key, *cert) for _, resource := range resources { upsertResult, err := client.Apply(&resource, *dryRun) if err != nil { diff --git a/cmd/delete.go b/cmd/delete.go index c14562b..e6a5281 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -14,7 +14,7 @@ var deleteCmd = &cobra.Command{ Long: ``, Args: cobra.ExactArgs(2), Run: func(cmd *cobra.Command, args []string) { - client := client.MakeFromEnv(*debug) + client := client.MakeFromEnv(*debug, *key, *cert) err := client.Delete(args[0], args[1]) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", err) diff --git a/cmd/get.go b/cmd/get.go index 477feef..30e581c 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -11,10 +11,14 @@ import ( var getCmd = &cobra.Command{ Use: "get kind [name]", Short: "get resource of a given kind", - Long: ``, - Args: cobra.MatchAll(cobra.MinimumNArgs(1), cobra.MaximumNArgs(2)), + Long: `If name not provided it will list all resource. For example: +conduktor get application +will list all applications. Whereas: +conduktor get application myapp +will describe the application myapp`, + Args: cobra.MatchAll(cobra.MinimumNArgs(1), cobra.MaximumNArgs(2)), Run: func(cmd *cobra.Command, args []string) { - client := client.MakeFromEnv(*debug) + client := client.MakeFromEnv(*debug, *key, *cert) var err error if len(args) == 1 { err = client.Get(args[0]) diff --git a/cmd/root.go b/cmd/root.go index 5f369c9..f6fb9ce 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -9,12 +9,15 @@ import ( ) var debug *bool +var key *string +var cert *string // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "conduktor", Short: "command line tools for conduktor", - Long: ``, + Long: `You need to define the CDK_TOKEN and CDK_BASE_URL environment variables to use this tool. +You can also use the CDK_KEY,CDK_CERT instead of --key and --cert flags to use a certificate for tls authentication.`, // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, @@ -32,4 +35,6 @@ func Execute() { func init() { debug = rootCmd.PersistentFlags().BoolP("verbose", "v", false, "Show more information for debugging") + key = rootCmd.PersistentFlags().String("key", "", "Set pem key for certificate authentication (useful for teleport)") + cert = rootCmd.PersistentFlags().String("cert", "", "Set pem cert for certificate authentication (useful for teleport)") }