Skip to content

Commit

Permalink
first version of v4 client
Browse files Browse the repository at this point in the history
  • Loading branch information
yannickstruyf3 committed Aug 31, 2023
1 parent ee4e007 commit ccba38f
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 0 deletions.
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ require (
github.com/google/uuid v1.3.0
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/keploy/go-sdk v0.7.2
github.com/nutanix/ntnx-api-golang-clients/clustermgmt-go-client/v4 v4.0.2-alpha.2
github.com/nutanix/ntnx-api-golang-clients/networking-go-client/v4 v4.0.1-alpha.1
github.com/nutanix/ntnx-api-golang-clients/prism-go-client/v4 v4.0.2-alpha.1
github.com/nutanix/ntnx-api-golang-clients/storage-go-client/v4 v4.0.2-alpha.3
github.com/nutanix/ntnx-api-golang-clients/vmm-go-client/v4 v4.0.2-alpha.1
github.com/onsi/ginkgo/v2 v2.7.0
github.com/onsi/gomega v1.26.0
github.com/stretchr/testify v1.8.1
Expand Down Expand Up @@ -46,6 +51,7 @@ require (
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.1.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
Expand All @@ -63,6 +69,7 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/tidwall/gjson v1.14.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
Expand Down
19 changes: 19 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,13 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ=
github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
Expand Down Expand Up @@ -163,6 +168,16 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nutanix/ntnx-api-golang-clients/clustermgmt-go-client/v4 v4.0.2-alpha.2 h1:GwunZWdO6J0X1xbTy220AIXMap6I9L5JedOzFussS/o=
github.com/nutanix/ntnx-api-golang-clients/clustermgmt-go-client/v4 v4.0.2-alpha.2/go.mod h1:sd4Fnk6MVfEDVY+8WyRoQTmLhi2SgZ3riySWErVHf8E=
github.com/nutanix/ntnx-api-golang-clients/networking-go-client/v4 v4.0.1-alpha.1 h1:i9apB9rDAF/u4GXvCG2ZhpWOtlKm0TtJMyBFRwVpiac=
github.com/nutanix/ntnx-api-golang-clients/networking-go-client/v4 v4.0.1-alpha.1/go.mod h1:+eZgV1+xL/r84qmuFSVt5R8OFRO70rEz92jOnVgJNco=
github.com/nutanix/ntnx-api-golang-clients/prism-go-client/v4 v4.0.2-alpha.1 h1:bQ5e0f0qM88HDaoR9nlff7C39254jSAaAtEQ7wkdzVs=
github.com/nutanix/ntnx-api-golang-clients/prism-go-client/v4 v4.0.2-alpha.1/go.mod h1:Yhk+xD4mN90OKEHnk5ARf97CX5p4+MEC/B/YIVoZeZ0=
github.com/nutanix/ntnx-api-golang-clients/storage-go-client/v4 v4.0.2-alpha.3 h1:K3I9YtqKcKKxSL4+tcxnFeLOoaptiVlpsOJ9Xzq3shM=
github.com/nutanix/ntnx-api-golang-clients/storage-go-client/v4 v4.0.2-alpha.3/go.mod h1:kz3gO87xtWnPOCP2kN7yw5LvCDVRnvg8BOWL7CarqXA=
github.com/nutanix/ntnx-api-golang-clients/vmm-go-client/v4 v4.0.2-alpha.1 h1:ISAnkmh9xZkRaaCX+kWGxQjQl/8qRNY7qnH5vfzphCw=
github.com/nutanix/ntnx-api-golang-clients/vmm-go-client/v4 v4.0.2-alpha.1/go.mod h1:CaWm4GFpAjQQDc6YXl/dUDrHpuW54h8j6Cj7EslE4Qk=
github.com/onsi/ginkgo/v2 v2.7.0 h1:/XxtEV3I3Eif/HobnVx9YmJgk8ENdRsuUmM+fLCFNow=
github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo=
github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
Expand All @@ -185,11 +200,14 @@ github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
Expand Down Expand Up @@ -301,6 +319,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
Expand Down
169 changes: 169 additions & 0 deletions v4/v4.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package v4

import (
"encoding/base64"
"fmt"
"net/url"
"strconv"

prismgoclient "github.com/nutanix-cloud-native/prism-go-client"
clusterApi "github.com/nutanix/ntnx-api-golang-clients/clustermgmt-go-client/v4/api"
clusterClient "github.com/nutanix/ntnx-api-golang-clients/clustermgmt-go-client/v4/client"
networkingApi "github.com/nutanix/ntnx-api-golang-clients/networking-go-client/v4/api"
networkingClient "github.com/nutanix/ntnx-api-golang-clients/networking-go-client/v4/client"
prismApi "github.com/nutanix/ntnx-api-golang-clients/prism-go-client/v4/api"
prismClient "github.com/nutanix/ntnx-api-golang-clients/prism-go-client/v4/client"
storageApi "github.com/nutanix/ntnx-api-golang-clients/storage-go-client/v4/api"
storageClient "github.com/nutanix/ntnx-api-golang-clients/storage-go-client/v4/client"
vmApi "github.com/nutanix/ntnx-api-golang-clients/vmm-go-client/v4/api"
vmClient "github.com/nutanix/ntnx-api-golang-clients/vmm-go-client/v4/client"
)

const (
defaultEndpointPort = "9440"
authorizationHeader = "Authorization"
)

// Client manages the V4 API
type Client struct {
VmApiInstance *vmApi.VmApi
ImagesApiInstance *vmApi.ImagesApi
SubnetApiInstance *networkingApi.SubnetApi
SubnetReserveUnreserveIPAPIInstance *networkingApi.SubnetReserveUnreserveIpApi
ClusterApiInstance *clusterApi.ClusterApi
TasksApiInstance *prismApi.TaskApi
StorageContainerAPI *storageApi.StorageContainerApi
}

type endpointInfo struct {
host string
port int
}

// NewV4Client return a internal to operate V4 resources
func NewV4Client(credentials prismgoclient.Credentials) (*Client, error) {
if credentials.Username == "" || credentials.Password == "" || credentials.Endpoint == "" {
return nil, fmt.Errorf("username, password and endpoint are required")
}

v4Client := &Client{}

if err := initVmApiInstance(v4Client, credentials); err != nil {
return nil, fmt.Errorf("failed to create VM API instance: %v", err)
}

if err := initSubnetApiInstance(v4Client, credentials); err != nil {
return nil, fmt.Errorf("failed to create Subnet API instance: %v", err)
}

if err := initClusterApiInstance(v4Client, credentials); err != nil {
return nil, fmt.Errorf("failed to create Cluster API instance: %v", err)
}

if err := initTasksApiInstance(v4Client, credentials); err != nil {
return nil, fmt.Errorf("failed to create Tasks API instance: %v", err)
}

if err := initStorageApiInstance(v4Client, credentials); err != nil {
return nil, fmt.Errorf("failed to create Storage API instance: %v", err)
}

return v4Client, nil
}

func initVmApiInstance(v4Client *Client, credentials prismgoclient.Credentials) error {
ep, err := getEndpointInfo(credentials)
if err != nil {
return err
}
apiClientInstance := vmClient.NewApiClient()
apiClientInstance.VerifySSL = !credentials.Insecure
apiClientInstance.Host = ep.host
apiClientInstance.Port = ep.port
apiClientInstance.AddDefaultHeader(
authorizationHeader, fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", credentials.Username, credentials.Password)))))
v4Client.VmApiInstance = vmApi.NewVmApi(apiClientInstance)
v4Client.ImagesApiInstance = vmApi.NewImagesApi(apiClientInstance)
return nil
}

func initClusterApiInstance(v4Client *Client, credentials prismgoclient.Credentials) error {
ep, err := getEndpointInfo(credentials)
if err != nil {
return err
}
apiClientInstance := clusterClient.NewApiClient()
apiClientInstance.VerifySSL = !credentials.Insecure
apiClientInstance.Host = ep.host
apiClientInstance.Port = ep.port
apiClientInstance.AddDefaultHeader(
authorizationHeader, fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", credentials.Username, credentials.Password)))))
v4Client.ClusterApiInstance = clusterApi.NewClusterApi(apiClientInstance)
return nil
}

func initTasksApiInstance(v4Client *Client, credentials prismgoclient.Credentials) error {
ep, err := getEndpointInfo(credentials)
if err != nil {
return err
}
apiClientInstance := prismClient.NewApiClient()
apiClientInstance.VerifySSL = !credentials.Insecure
apiClientInstance.Host = ep.host
apiClientInstance.Port = ep.port
apiClientInstance.AddDefaultHeader(
authorizationHeader, fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", credentials.Username, credentials.Password)))))
v4Client.TasksApiInstance = prismApi.NewTaskApi(apiClientInstance)
return nil
}

func initSubnetApiInstance(v4Client *Client, credentials prismgoclient.Credentials) error {
ep, err := getEndpointInfo(credentials)
if err != nil {
return err
}
apiClientInstance := networkingClient.NewApiClient()
apiClientInstance.SetVerifySSL(!credentials.Insecure)
apiClientInstance.Host = ep.host
apiClientInstance.Port = ep.port
apiClientInstance.AddDefaultHeader(
authorizationHeader, fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", credentials.Username, credentials.Password)))))
v4Client.SubnetApiInstance = networkingApi.NewSubnetApi(apiClientInstance)
v4Client.SubnetReserveUnreserveIPAPIInstance = networkingApi.NewSubnetReserveUnreserveIpApi(apiClientInstance)
return nil
}

func initStorageApiInstance(v4Client *Client, credentials prismgoclient.Credentials) error {
ep, err := getEndpointInfo(credentials)
if err != nil {
return err
}
apiClientInstance := storageClient.NewApiClient()
apiClientInstance.SetVerifySSL(!credentials.Insecure)
apiClientInstance.Host = ep.host
apiClientInstance.Port = ep.port
apiClientInstance.AddDefaultHeader(
authorizationHeader, fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", credentials.Username, credentials.Password)))))
v4Client.StorageContainerAPI = storageApi.NewStorageContainerApi(apiClientInstance)
return nil
}

func getEndpointInfo(credentials prismgoclient.Credentials) (*endpointInfo, error) {
u, err := url.Parse(fmt.Sprintf("https://%s", credentials.Endpoint))
if err != nil {
return nil, err
}
h := u.Hostname()
port := u.Port()
if port == "" {
port = defaultEndpointPort
}
p, err := strconv.Atoi(port)
if err != nil {
return nil, fmt.Errorf("failed to convert port number to int: %v", err)
}
return &endpointInfo{
host: h,
port: p,
}, nil
}
46 changes: 46 additions & 0 deletions v4/v4_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package v4

import (
"testing"

prismgoclient "github.com/nutanix-cloud-native/prism-go-client"
"github.com/stretchr/testify/assert"
)

func TestNewV4Client(t *testing.T) {
// verifies positive client creation
cred := prismgoclient.Credentials{
URL: "foo.com",
Username: "username",
Password: "password",
Port: "",
Endpoint: "0.0.0.0",
Insecure: true,
FoundationEndpoint: "10.0.0.0",
FoundationPort: "8000",
RequiredFields: nil,
}
v4Client, err := NewV4Client(cred)
assert.NoError(t, err)
assert.NotNil(t, v4Client)
assert.NotNil(t, v4Client.VmApiInstance)
assert.NotNil(t, v4Client.ImagesApiInstance)
assert.NotNil(t, v4Client.SubnetApiInstance)
assert.NotNil(t, v4Client.SubnetReserveUnreserveIPAPIInstance)
assert.NotNil(t, v4Client.ClusterApiInstance)
assert.NotNil(t, v4Client.TasksApiInstance)
assert.NotNil(t, v4Client.StorageContainerAPI)

// verify missing client scenario
cred = prismgoclient.Credentials{
URL: "foo.com",
Insecure: true,
RequiredFields: map[string][]string{
"prism_central": {"username", "password", "endpoint"},
},
}

v4Client, err = NewV4Client(cred)
assert.Nil(t, v4Client)
assert.EqualError(t, err, "username, password and endpoint are required")
}

0 comments on commit ccba38f

Please sign in to comment.