Skip to content

Commit

Permalink
improve cli api for quentin (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
strokyl authored Jul 11, 2024
1 parent 4646352 commit e268bdf
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 47 deletions.
80 changes: 56 additions & 24 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,74 @@ type Client struct {
kinds schema.KindCatalog
}

func Make(apiKey string, baseUrl string, debug bool, key, cert, cacert string, insecure bool) (*Client, error) {
type ApiParameter struct {
ApiKey string
BaseUrl string
Debug bool
Key string
Cert string
Cacert string
CdkUser string
CdkPassword string
Insecure bool
}

func Make(apiParameter ApiParameter) (*Client, error) {
//apiKey is set later because it's not mandatory for getting the openapi and parsing different kind
//or to get jwt token
restyClient := resty.New().SetDebug(debug).SetHeader("X-CDK-CLIENT", "CLI/"+utils.GetConduktorVersion())
restyClient := resty.New().SetDebug(apiParameter.Debug).SetHeader("X-CDK-CLIENT", "CLI/"+utils.GetConduktorVersion())

if apiParameter.BaseUrl == "" {
return nil, fmt.Errorf("Please set CDK_BASE_URL")
}

if (key == "" && cert != "") || (key != "" && cert == "") {
return nil, fmt.Errorf("key and cert must be provided together")
} else if key != "" && cert != "" {
certificate, err := tls.LoadX509KeyPair(cert, key)
if (apiParameter.Key == "" && apiParameter.Cert != "") || (apiParameter.Key != "" && apiParameter.Cert == "") {
return nil, fmt.Errorf("CDK_KEY and CDK_CERT must be provided together")
} else if apiParameter.Key != "" && apiParameter.Cert != "" {
certificate, err := tls.LoadX509KeyPair(apiParameter.Cert, apiParameter.Key)
restyClient.SetCertificates(certificate)
if err != nil {
return nil, err
}
}

if cacert != "" {
restyClient.SetRootCertificate(cacert)
if (apiParameter.CdkUser != "" && apiParameter.CdkPassword == "") || (apiParameter.CdkUser == "" && apiParameter.CdkPassword != "") {
return nil, fmt.Errorf("CDK_USER and CDK_PASSWORD must be provided together")
}
if apiParameter.CdkUser != "" && apiParameter.ApiKey != "" {
return nil, fmt.Errorf("Can't set both CDK_USER and CDK_API_KEY")
}

if apiParameter.Cacert != "" {
restyClient.SetRootCertificate(apiParameter.Cacert)
}

result := &Client{
apiKey: apiKey,
baseUrl: baseUrl,
apiKey: apiParameter.ApiKey,
baseUrl: apiParameter.BaseUrl,
client: restyClient,
kinds: nil,
}

if apiKey != "" {
if apiParameter.Insecure {
result.IgnoreUntrustedCertificate()
}

if apiParameter.CdkUser != "" {
jwtToken, err := result.Login(apiParameter.CdkUser, apiParameter.CdkPassword)
if err != nil {
return nil, fmt.Errorf("Could not login: %s", err)
}
result.apiKey = jwtToken.AccessToken
}

if apiParameter.ApiKey != "" {
result.setApiKeyInRestClient()
} else {
//it will be set later only when really needed
//so aim is not fail when CDK_API_KEY is not set before printing the cmd help
}

if insecure {
result.IgnoreUntrustedCertificate()
}

err := result.initKindFromApi()
if err != nil {
fmt.Fprintf(os.Stderr, "Cannot access the Conduktor API: %s\nUsing offline defaults.\n", err)
Expand All @@ -69,17 +100,18 @@ func Make(apiKey string, baseUrl string, debug bool, key, cert, cacert string, i
}

func MakeFromEnv() (*Client, error) {
baseUrl := os.Getenv("CDK_BASE_URL")
if baseUrl == "" {
return nil, fmt.Errorf("Please set CDK_BASE_URL")
apiParameter := ApiParameter{
BaseUrl: os.Getenv("CDK_BASE_URL"),
Debug: strings.ToLower(os.Getenv("CDK_DEBUG")) == "true",
Cert: os.Getenv("CDK_CERT"),
Cacert: os.Getenv("CDK_CACERT"),
ApiKey: os.Getenv("CDK_API_KEY"),
CdkUser: os.Getenv("CDK_USER"),
CdkPassword: os.Getenv("CDK_PASSWORD"),
Insecure: strings.ToLower(os.Getenv("CDK_INSECURE")) == "true",
}
debug := strings.ToLower(os.Getenv("CDK_DEBUG")) == "true"
key := os.Getenv("CDK_KEY")
cert := os.Getenv("CDK_CERT")
cacert := os.Getenv("CDK_CACERT")
insecure := strings.ToLower(os.Getenv("CDK_INSECURE")) == "true"

client, err := Make("", baseUrl, debug, key, cert, cacert, insecure)
client, err := Make(apiParameter)
if err != nil {
return nil, fmt.Errorf("Cannot create client: %s", err)
}
Expand Down
45 changes: 36 additions & 9 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ func TestApplyShouldWork(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl"
apiKey := "aToken"
client, err := Make(apiKey, baseUrl, false, "", "", "", false)
client, err := Make(ApiParameter{
ApiKey: apiKey,
BaseUrl: baseUrl,
})
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -54,7 +57,10 @@ func TestApplyWithDryModeShouldWork(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl"
apiKey := "aToken"
client, err := Make(apiKey, baseUrl, false, "", "", "", false)
client, err := Make(ApiParameter{
ApiKey: apiKey,
BaseUrl: baseUrl,
})
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -92,7 +98,10 @@ func TestApplyShouldFailIfNo2xx(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl"
apiKey := "aToken"
client, err := Make(apiKey, baseUrl, false, "", "", "", false)
client, err := Make(ApiParameter{
ApiKey: apiKey,
BaseUrl: baseUrl,
})
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -130,7 +139,10 @@ func TestGetShouldWork(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl"
apiKey := "aToken"
client, err := Make(apiKey, baseUrl, false, "", "", "", false)
client, err := Make(ApiParameter{
ApiKey: apiKey,
BaseUrl: baseUrl,
})
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -162,7 +174,10 @@ func TestGetShouldFailIfN2xx(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl"
apiKey := "aToken"
client, err := Make(apiKey, baseUrl, false, "", "", "", false)
client, err := Make(ApiParameter{
ApiKey: apiKey,
BaseUrl: baseUrl,
})
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -193,7 +208,10 @@ func TestDescribeShouldWork(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl"
apiKey := "aToken"
client, err := Make(apiKey, baseUrl, false, "", "", "", false)
client, err := Make(ApiParameter{
ApiKey: apiKey,
BaseUrl: baseUrl,
})
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -225,7 +243,10 @@ func TestDescribeShouldFailIfNo2xx(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl/api"
apiKey := "aToken"
client, err := Make(apiKey, baseUrl, false, "", "", "", false)
client, err := Make(ApiParameter{
ApiKey: apiKey,
BaseUrl: baseUrl,
})
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -256,7 +277,10 @@ func TestDeleteShouldWork(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl"
apiKey := "aToken"
client, err := Make(apiKey, baseUrl, false, "", "", "", false)
client, err := Make(ApiParameter{
ApiKey: apiKey,
BaseUrl: baseUrl,
})
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -287,7 +311,10 @@ func TestDeleteShouldFailOnNot2XX(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl"
apiKey := "aToken"
client, err := Make(apiKey, baseUrl, false, "", "", "", false)
client, err := Make(ApiParameter{
ApiKey: apiKey,
BaseUrl: baseUrl,
})
if err != nil {
panic(err)
}
Expand Down
18 changes: 14 additions & 4 deletions cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package cmd
import (
"fmt"
"os"
"strings"

"github.com/conduktor/ctl/client"
"github.com/spf13/cobra"
)

Expand All @@ -14,20 +16,28 @@ var loginCmd = &cobra.Command{
Long: `Use must use CDK_USER CDK_PASSWORD environment variables to login`,
Args: cobra.RangeArgs(0, 0),
Run: func(cmd *cobra.Command, args []string) {
specificApiClient, err := client.Make(client.ApiParameter{BaseUrl: os.Getenv("CDK_BASE_URL"), Debug: strings.ToLower(os.Getenv("CDK_DEBUG")) == "true"})
if *debug {
specificApiClient.ActivateDebug()
}
if err != nil {
fmt.Fprintf(os.Stderr, "Could not login: %s\n", err)
os.Exit(1)
}
username := os.Getenv("CDK_USER")
if username == "" {
fmt.Fprintln(os.Stderr, "Please set CDK_USER")
os.Exit(1)
os.Exit(2)
}
password := os.Getenv("CDK_PASSWORD")
if password == "" {
fmt.Fprintln(os.Stderr, "Please set CDK_PASSWORD")
os.Exit(2)
os.Exit(3)
}
token, err := apiClient().Login(username, password)
token, err := specificApiClient.Login(username, password)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not login: %s\n", err)
os.Exit(3)
os.Exit(4)
}
fmt.Println(token.AccessToken)
},
Expand Down
4 changes: 2 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func apiClient() *client.Client {
var rootCmd = &cobra.Command{
Use: "conduktor",
Short: "Command line tools for conduktor",
Long: `Make sure you've set the environment variables CDK_API_KEY (generated from Console) and CDK_BASE_URL.
Long: `Make sure you've set the environment variables CDK_USER/CDK_PASSWORD or CDK_API_KEY (generated from Console) and CDK_BASE_URL.
Additionally, you can configure client TLS authentication by providing your certificate paths in CDK_KEY and CDK_CERT.
For server TLS authentication, you can ignore the certificate by setting CDK_INSECURE=true, or provide a certificate authority using CDK_CACERT.`,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
Expand All @@ -50,7 +50,7 @@ func Execute() {

func init() {
apiClient_, apiClientError = client.MakeFromEnv()
kinds := schema.KindCatalog{}
var kinds schema.KindCatalog
if apiClientError == nil {
kinds = apiClient_.GetKinds()
} else {
Expand Down
6 changes: 3 additions & 3 deletions cmd/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ var deleteTokenCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
err := apiClient().DeleteToken(args[0])
if err != nil {
fmt.Fprintf(os.Stderr, "Could not create admin token: %s\n", err)
fmt.Fprintf(os.Stderr, "Could not delete token: %s\n", err)
os.Exit(1)
}
fmt.Println("Token deleted")
Expand All @@ -134,9 +134,9 @@ var deleteTokenCmd = &cobra.Command{

func init() {
applicationInstanceNameForList = listApplicationInstanceTokenCmd.PersistentFlags().StringP("application-instance", "i", "", "Application instance name")
rootCmd.MarkPersistentFlagRequired("application-instance")
applicationInstanceNameForCreate = createApplicationInstanceTokenCmd.PersistentFlags().StringP("application-instance", "i", "", "Application instance name")
rootCmd.MarkPersistentFlagRequired("application-instance")
listApplicationInstanceTokenCmd.MarkPersistentFlagRequired("application-instance")
createApplicationInstanceTokenCmd.MarkPersistentFlagRequired("application-instance")
listTokenCmd.AddCommand(listApplicationInstanceTokenCmd)
listTokenCmd.AddCommand(listAdminCmd)
tokenCmd.AddCommand(listTokenCmd)
Expand Down
Loading

0 comments on commit e268bdf

Please sign in to comment.