Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Karbon Base #228

Merged
merged 24 commits into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a859ba3
alpha version of Karbon implementation
yannickstruyf3 Dec 7, 2020
848fa57
Applied linting recommendations
yannickstruyf3 Oct 6, 2020
dc1cb90
added default values for CNI config
yannickstruyf3 Oct 7, 2020
357d189
added additional validation
yannickstruyf3 Oct 7, 2020
7a801a8
changed cni config to typelist
yannickstruyf3 Oct 7, 2020
e1abe6a
added constants
yannickstruyf3 Oct 7, 2020
72f5282
modified for linting
yannickstruyf3 Oct 7, 2020
08ec1f0
changed typeset to typelist for cni config and modified check existan…
yannickstruyf3 Oct 9, 2020
f1f4c3b
removed unchecked d.get() and reviewed todo comments
yannickstruyf3 Oct 14, 2020
fb9251a
modified code for Karbon 2.1.2
yannickstruyf3 Oct 26, 2020
2415186
added forcenew for CNI config
yannickstruyf3 Nov 13, 2020
11d2215
added scaling capabilities
yannickstruyf3 Dec 2, 2020
ca8f30e
added read for cni_config
yannickstruyf3 Dec 3, 2020
b63b6bb
rebased v1.2.0-beta
yannickstruyf3 Dec 7, 2020
32d24e0
removed print statement
yannickstruyf3 Dec 9, 2020
5565ec1
wip: karbon acc test
marinsalinas Dec 10, 2020
f33fe4e
test: add karbon acceptance test cases
marinsalinas Dec 15, 2020
da26cd8
chore: remove log
marinsalinas Dec 15, 2020
09117ea
refactor: test use for intead if to get the cluster id
marinsalinas Dec 15, 2020
a868194
test: add scaledown karbon cluster test case
marinsalinas Dec 16, 2020
e3c588b
test: add updateCNI test case for karbon resource
marinsalinas Dec 16, 2020
84631bf
chore: fix test
marinsalinas Dec 17, 2020
7a8c58f
docs: added docs for resource and datasource(s) of cluster and privat…
Dec 11, 2020
b33022d
docs: made changes suggested by yannick and gaby
Dec 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
alpha version of Karbon implementation
  • Loading branch information
yannickstruyf3 authored and marinsalinas committed Jan 21, 2021
commit a859ba3edfcdae57c5fa03a03e3200270506deb5
46 changes: 35 additions & 11 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import (
)

const (
libraryVersion = "v3"
// libraryVersion = "v3"
defaultBaseURL = "https://%s/"
absolutePath = "api/nutanix/" + libraryVersion
userAgent = "nutanix/" + libraryVersion
mediaType = "application/json"
// absolutePath = "api/nutanix/" + libraryVersion
// userAgent = "nutanix/" + libraryVersion
mediaType = "application/json"
)

// Client Config Configuration of the client
Expand All @@ -41,6 +41,9 @@ type Client struct {

// Optional function called after every successful request made.
onRequestCompleted RequestCompletionCallback

// absolutePath: for example api/nutanix/v3
AbsolutePath string
}

// RequestCompletionCallback defines the type of the request callback function
Expand All @@ -59,7 +62,14 @@ type Credentials struct {
}

// NewClient returns a new Nutanix API client.
func NewClient(credentials *Credentials) (*Client, error) {
func NewClient(credentials *Credentials, userAgent string, absolutePath string) (*Client, error) {
if userAgent == "" {
return nil, fmt.Errorf("userAgent argument must be passed")
}
if absolutePath == "" {
return nil, fmt.Errorf("absolutePath argument must be passed")
}

transCfg := &http.Transport{
// nolint:gas
TLSClientConfig: &tls.Config{InsecureSkipVerify: credentials.Insecure}, // ignore expired SSL certificates
Expand All @@ -85,7 +95,7 @@ func NewClient(credentials *Credentials) (*Client, error) {
return nil, err
}

c := &Client{credentials, httpClient, baseURL, userAgent, nil, nil}
c := &Client{credentials, httpClient, baseURL, userAgent, nil, nil, absolutePath}

if credentials.SessionAuth {
log.Printf("[DEBUG] Using session_auth\n")
Expand Down Expand Up @@ -117,7 +127,7 @@ func NewClient(credentials *Credentials) (*Client, error) {

// NewRequest creates a request
func (c *Client) NewRequest(ctx context.Context, method, urlStr string, body interface{}) (*http.Request, error) {
rel, errp := url.Parse(absolutePath + urlStr)
rel, errp := url.Parse(c.AbsolutePath + urlStr)
if errp != nil {
return nil, errp
}
Expand Down Expand Up @@ -156,7 +166,7 @@ func (c *Client) NewRequest(ctx context.Context, method, urlStr string, body int

// NewUploadRequest Handles image uploads for image service
func (c *Client) NewUploadRequest(ctx context.Context, method, urlStr string, body []byte) (*http.Request, error) {
rel, errp := url.Parse(absolutePath + urlStr)
rel, errp := url.Parse(c.AbsolutePath + urlStr)
if errp != nil {
return nil, errp
}
Expand Down Expand Up @@ -235,6 +245,7 @@ func CheckResponse(r *http.Response) error {
if c >= 200 && c <= 299 {
return nil
}
log.Print("[DEBUG] after status check")

// Nutanix returns non-json response with code 401 when
// invalid credentials are used
Expand All @@ -247,26 +258,27 @@ func CheckResponse(r *http.Response) error {
if err != nil {
return err
}

log.Print("[DEBUG] after readall")
rdr2 := ioutil.NopCloser(bytes.NewBuffer(buf))

r.Body = rdr2

log.Print("[DEBUG] after rdr2")
// if has entities -> return nil
// if has message_list -> check_error["state"]
// if has status -> check_error["status.state"]
if len(buf) == 0 {
return nil
}
log.Print("[DEBUG] after len(buf)")

var res map[string]interface{}
err = json.Unmarshal(buf, &res)
if err != nil {
return fmt.Errorf("unmarshalling error response %s", err)
}
log.Print("[DEBUG] after json.Unmarshal")

errRes := &ErrorResponse{}

if status, ok := res["status"]; ok {
_, sok := status.(string)
if sok {
Expand All @@ -280,14 +292,26 @@ func CheckResponse(r *http.Response) error {
return nil
}

log.Print("[DEBUG] after bunch of switch cases")
if err != nil {
return err
}
log.Print("[DEBUG] first nil check")

//karbon error check
if message_info, ok := res["message_info"]; ok {
log.Print(message_info)
return fmt.Errorf("error: %s", message_info)
}
if message, ok := res["message"]; ok {
log.Print(message)
return fmt.Errorf("error: %s", message)
}
if errRes.State != "ERROR" {
return nil
}

log.Print("[DEBUG] after errRes.State")
pretty, _ := json.MarshalIndent(errRes, "", " ")
return fmt.Errorf("error: %s", string(pretty))
}
Expand Down
18 changes: 12 additions & 6 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,24 @@ import (
"testing"
)

const (
testLibraryVersion = "v3"
testAbsolutePath = "api/nutanix/" + testLibraryVersion
testUserAgent = "nutanix/" + testLibraryVersion
)

func setup() (*http.ServeMux, *Client, *httptest.Server) {
mux := http.NewServeMux()
server := httptest.NewServer(mux)

client, _ := NewClient(&Credentials{"", "username", "password", "", "", true, false, ""})
client, _ := NewClient(&Credentials{"", "username", "password", "", "", true, false, ""}, testUserAgent, testAbsolutePath)
client.BaseURL, _ = url.Parse(server.URL)

return mux, client, server
}

func TestNewClient(t *testing.T) {
c, err := NewClient(&Credentials{"foo.com", "username", "password", "", "", true, false, ""})
c, err := NewClient(&Credentials{"foo.com", "username", "password", "", "", true, false, ""}, testUserAgent, testAbsolutePath)

if err != nil {
t.Errorf("Unexpected Error: %v", err)
Expand All @@ -35,19 +41,19 @@ func TestNewClient(t *testing.T) {
t.Errorf("NewClient BaseURL = %v, expected %v", c.BaseURL, expectedURL)
}

if c.UserAgent != userAgent {
t.Errorf("NewClient UserAgent = %v, expected %v", c.UserAgent, userAgent)
if c.UserAgent != testUserAgent {
t.Errorf("NewClient UserAgent = %v, expected %v", c.UserAgent, testUserAgent)
}
}

func TestNewRequest(t *testing.T) {
c, err := NewClient(&Credentials{"foo.com", "username", "password", "", "", true, false, ""})
c, err := NewClient(&Credentials{"foo.com", "username", "password", "", "", true, false, ""}, testUserAgent, testAbsolutePath)

if err != nil {
t.Errorf("Unexpected Error: %v", err)
}

inURL, outURL := "/foo", fmt.Sprintf(defaultBaseURL+absolutePath+"/foo", "foo.com")
inURL, outURL := "/foo", fmt.Sprintf(defaultBaseURL+testAbsolutePath+"/foo", "foo.com")
inBody, outBody := map[string]interface{}{"name": "bar"}, `{"name":"bar"}`+"\n"

req, _ := c.NewRequest(context.TODO(), http.MethodPost, inURL, inBody)
Expand Down
38 changes: 38 additions & 0 deletions client/karbon/karbon_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package karbon

import (
"github.com/terraform-providers/terraform-provider-nutanix/client"
)

const (
absolutePath = "karbon"
userAgent = "nutanix"
)

// Client manages the V3 API
type Client struct {
client *client.Client
Cluster ClusterService
PrivateRegistry PrivateRegistryService
}

// NewKarbonAPIClient return a client to operate Karbon resources
func NewKarbonAPIClient(credentials client.Credentials) (*Client, error) {
c, err := client.NewClient(&credentials, userAgent, absolutePath)

if err != nil {
return nil, err
}

f := &Client{
client: c,
Cluster: ClusterOperations{
client: c,
},
PrivateRegistry: PrivateRegistryOperations{
client: c,
},
}

return f, nil
}
Loading