Skip to content

Commit

Permalink
Use a cached prism-go-client with session auth
Browse files Browse the repository at this point in the history
This will reduce the number of basic auth calls that will
be made to IAM stack.
  • Loading branch information
thunderboltsid committed Jul 8, 2024
1 parent 6d541c1 commit 1c71a1f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 49 deletions.
11 changes: 6 additions & 5 deletions internal/testing/mock/mock_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,17 @@ package mock

import (
"k8s.io/client-go/informers"
coreinformers "k8s.io/client-go/informers/core/v1"

"github.com/nutanix-cloud-native/cloud-provider-nutanix/pkg/provider/interfaces"
)

// MockClient is a mock implementation of the interfaces.Client interface
type MockClient struct {
mockPrism MockPrism
sharedInformers informers.SharedInformerFactory
secretInformer coreinformers.SecretInformer
configMapInformer coreinformers.ConfigMapInformer
mockPrism MockPrism
sharedInformers informers.SharedInformerFactory
}

// CreateMockClient creates a new MockClient
func CreateMockClient(mockEnvironment MockEnvironment) *MockClient {
return &MockClient{
mockPrism: MockPrism{
Expand All @@ -38,10 +37,12 @@ func CreateMockClient(mockEnvironment MockEnvironment) *MockClient {
}
}

// Get returns the mockPrism
func (mc *MockClient) Get() (interfaces.Prism, error) {
return &mc.mockPrism, nil
}

// SetInformers sets the sharedInformers
func (mc *MockClient) SetInformers(sharedInformers informers.SharedInformerFactory) {
mc.sharedInformers = sharedInformers
}
58 changes: 28 additions & 30 deletions pkg/provider/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,64 +20,62 @@ import (
"context"
"fmt"

prismgoclient "github.com/nutanix-cloud-native/prism-go-client"
"github.com/nutanix-cloud-native/prism-go-client/environment"
credentialTypes "github.com/nutanix-cloud-native/prism-go-client/environment/credentials"
kubernetesEnv "github.com/nutanix-cloud-native/prism-go-client/environment/providers/kubernetes"
envTypes "github.com/nutanix-cloud-native/prism-go-client/environment/types"
prismClientV3 "github.com/nutanix-cloud-native/prism-go-client/v3"
credentialtypes "github.com/nutanix-cloud-native/prism-go-client/environment/credentials"
kubernetesenv "github.com/nutanix-cloud-native/prism-go-client/environment/providers/kubernetes"
envtypes "github.com/nutanix-cloud-native/prism-go-client/environment/types"
prismclientv3 "github.com/nutanix-cloud-native/prism-go-client/v3"
"k8s.io/client-go/informers"
coreinformers "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/klog/v2"

"github.com/nutanix-cloud-native/cloud-provider-nutanix/internal/constants"
"github.com/nutanix-cloud-native/cloud-provider-nutanix/pkg/provider/config"
"github.com/nutanix-cloud-native/cloud-provider-nutanix/pkg/provider/interfaces"
)

const errEnvironmentNotReady = "environment not initialized or ready yet"

type nutanixClient struct {
env *envTypes.Environment
env *envtypes.Environment
config config.Config
secretInformer coreinformers.SecretInformer
sharedInformers informers.SharedInformerFactory
configMapInformer coreinformers.ConfigMapInformer
clientCache *prismclientv3.ClientCache
}

func (n *nutanixClient) Get() (interfaces.Prism, error) {
if err := n.setupEnvironment(); err != nil {
return nil, fmt.Errorf("%s: %v", errEnvironmentNotReady, err)
}
// Key returns the constant client name
// This implements the CachedClientParams interface of prism-go-client

Check warning on line 50 in pkg/provider/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/provider/client.go#L49-L50

Added lines #L49 - L50 were not covered by tests
func (n *nutanixClient) Key() string {
return constants.ClientName
}

// ManagementEndpoint returns the management endpoint of the Nutanix cluster

Check warning on line 55 in pkg/provider/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/provider/client.go#L52-L55

Added lines #L52 - L55 were not covered by tests
// This implements the CachedClientParams interface of prism-go-client
func (n *nutanixClient) ManagementEndpoint() envtypes.ManagementEndpoint {

Check warning on line 57 in pkg/provider/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/provider/client.go#L57

Added line #L57 was not covered by tests
env := *n.env
me, err := env.GetManagementEndpoint(envTypes.Topology{})
mgmtEndpoint, err := env.GetManagementEndpoint(envtypes.Topology{})
if err != nil {
return nil, err
}
creds := &prismgoclient.Credentials{
URL: me.Address.Host, // Not really an URL
Endpoint: me.Address.Host,
Insecure: me.Insecure,
Username: me.ApiCredentials.Username,
Password: me.ApiCredentials.Password,
klog.Errorf("failed to get management endpoint: %v", err)
return envtypes.ManagementEndpoint{}
}

clientOpts := make([]prismClientV3.ClientOption, 0)
if me.AdditionalTrustBundle != "" {
clientOpts = append(clientOpts, prismClientV3.WithPEMEncodedCertBundle([]byte(me.AdditionalTrustBundle)))
}
return *mgmtEndpoint
}

Check warning on line 66 in pkg/provider/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/provider/client.go#L65-L66

Added lines #L65 - L66 were not covered by tests

nutanixClient, err := prismClientV3.NewV3Client(*creds, clientOpts...)
if err != nil {
return nil, err
func (n *nutanixClient) Get() (interfaces.Prism, error) {
if err := n.setupEnvironment(); err != nil {
return nil, fmt.Errorf("%s: %v", errEnvironmentNotReady, err)

Check warning on line 70 in pkg/provider/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/provider/client.go#L70

Added line #L70 was not covered by tests
}

_, err = nutanixClient.V3.GetCurrentLoggedInUser(context.Background())
client, err := n.clientCache.GetOrCreate(n)
if err != nil {
return nil, err
}

return nutanixClient.V3, nil
return client.V3, nil
}

func (n *nutanixClient) setupEnvironment() error {
Expand All @@ -96,12 +94,12 @@ func (n *nutanixClient) setupEnvironment() error {
}
additionalTrustBundleRef := pc.AdditionalTrustBundle
if additionalTrustBundleRef != nil &&
additionalTrustBundleRef.Kind == credentialTypes.NutanixTrustBundleKindConfigMap &&
additionalTrustBundleRef.Kind == credentialtypes.NutanixTrustBundleKindConfigMap &&

Check warning on line 97 in pkg/provider/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/provider/client.go#L97

Added line #L97 was not covered by tests
additionalTrustBundleRef.Namespace == "" {
additionalTrustBundleRef.Namespace = ccmNamespace
}

env := environment.NewEnvironment(kubernetesEnv.NewProvider(pc,
env := environment.NewEnvironment(kubernetesenv.NewProvider(pc,
n.secretInformer, n.configMapInformer))
n.env = &env
return nil
Expand Down
25 changes: 13 additions & 12 deletions pkg/provider/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"fmt"
"strings"

prismClientV3 "github.com/nutanix-cloud-native/prism-go-client/v3"
prismclientv3 "github.com/nutanix-cloud-native/prism-go-client/v3"
v1 "k8s.io/api/core/v1"
"k8s.io/client-go/informers"
clientset "k8s.io/client-go/kubernetes"
Expand All @@ -45,7 +45,8 @@ func newNutanixManager(config config.Config) (*nutanixManager, error) {
m := &nutanixManager{
config: config,
nutanixClient: &nutanixClient{
config: config,
config: config,
clientCache: prismclientv3.NewClientCache(prismclientv3.WithSessionAuth(true)),
},
}
return m, nil
Expand Down Expand Up @@ -218,7 +219,7 @@ func (n *nutanixManager) isNodeShutdown(ctx context.Context, node *v1.Node) (boo
return false, nil
}

func (n *nutanixManager) isVMShutdown(vm *prismClientV3.VMIntentResponse) bool {
func (n *nutanixManager) isVMShutdown(vm *prismclientv3.VMIntentResponse) bool {
return *vm.Spec.Resources.PowerState == constants.PoweredOffState
}

Expand Down Expand Up @@ -261,7 +262,7 @@ func (n *nutanixManager) generateProviderID(ctx context.Context, vmUUID string)
return fmt.Sprintf("%s://%s", constants.ProviderName, strings.ToLower(vmUUID)), nil
}

func (n *nutanixManager) getNodeAddresses(ctx context.Context, vm *prismClientV3.VMIntentResponse) ([]v1.NodeAddress, error) {
func (n *nutanixManager) getNodeAddresses(ctx context.Context, vm *prismclientv3.VMIntentResponse) ([]v1.NodeAddress, error) {
if vm == nil {
return nil, fmt.Errorf("vm cannot be nil when getting node addresses")
}
Expand Down Expand Up @@ -292,7 +293,7 @@ func (n *nutanixManager) stripNutanixIDFromProviderID(providerID string) string
return strings.TrimPrefix(providerID, fmt.Sprintf("%s://", constants.ProviderName))
}

func (n *nutanixManager) getTopologyInfo(ctx context.Context, nutanixClient interfaces.Prism, vm *prismClientV3.VMIntentResponse) (config.TopologyInfo, error) {
func (n *nutanixManager) getTopologyInfo(ctx context.Context, nutanixClient interfaces.Prism, vm *prismclientv3.VMIntentResponse) (config.TopologyInfo, error) {
topologyDiscovery := n.config.TopologyDiscovery

switch topologyDiscovery.Type {
Expand All @@ -304,7 +305,7 @@ func (n *nutanixManager) getTopologyInfo(ctx context.Context, nutanixClient inte
return config.TopologyInfo{}, fmt.Errorf("unsupported topology discovery type: %s", topologyDiscovery.Type)
}

func (n *nutanixManager) getTopologyInfoUsingPrism(ctx context.Context, nClient interfaces.Prism, vm *prismClientV3.VMIntentResponse) (config.TopologyInfo, error) {
func (n *nutanixManager) getTopologyInfoUsingPrism(ctx context.Context, nClient interfaces.Prism, vm *prismclientv3.VMIntentResponse) (config.TopologyInfo, error) {
ti := config.TopologyInfo{}
if nClient == nil {
return ti, fmt.Errorf("nutanix client cannot be nil when searching for Prism topology info")
Expand All @@ -326,7 +327,7 @@ func (n *nutanixManager) getTopologyInfoUsingPrism(ctx context.Context, nClient
return ti, nil
}

func (n *nutanixManager) getTopologyInfoUsingCategories(ctx context.Context, nutanixClient interfaces.Prism, vm *prismClientV3.VMIntentResponse) (config.TopologyInfo, error) {
func (n *nutanixManager) getTopologyInfoUsingCategories(ctx context.Context, nutanixClient interfaces.Prism, vm *prismclientv3.VMIntentResponse) (config.TopologyInfo, error) {
tc := &config.TopologyInfo{}
if vm == nil {
return *tc, fmt.Errorf("vm cannot be nil while getting topology info")
Expand Down Expand Up @@ -369,7 +370,7 @@ func (n *nutanixManager) getZoneInfoFromCategories(categories map[string]string,
return nil
}

func (n *nutanixManager) getTopologyInfoFromCluster(ctx context.Context, nClient interfaces.Prism, vm *prismClientV3.VMIntentResponse, ti *config.TopologyInfo) error {
func (n *nutanixManager) getTopologyInfoFromCluster(ctx context.Context, nClient interfaces.Prism, vm *prismclientv3.VMIntentResponse, ti *config.TopologyInfo) error {
if nClient == nil {
return fmt.Errorf("nutanix client cannot be nil when searching for topology info")
}
Expand All @@ -390,7 +391,7 @@ func (n *nutanixManager) getTopologyInfoFromCluster(ctx context.Context, nClient
return nil
}

func (n *nutanixManager) getTopologyInfoFromVM(vm *prismClientV3.VMIntentResponse, ti *config.TopologyInfo) error {
func (n *nutanixManager) getTopologyInfoFromVM(vm *prismclientv3.VMIntentResponse, ti *config.TopologyInfo) error {
if vm == nil {
return fmt.Errorf("vm cannot be nil when searching for topology info")
}
Expand All @@ -413,7 +414,7 @@ func (n *nutanixManager) hasEmptyTopologyInfo(ti config.TopologyInfo) bool {
return false
}

func (n *nutanixManager) getPrismCentralCluster(ctx context.Context, nClient interfaces.Prism) (*prismClientV3.ClusterIntentResponse, error) {
func (n *nutanixManager) getPrismCentralCluster(ctx context.Context, nClient interfaces.Prism) (*prismclientv3.ClusterIntentResponse, error) {
const filter = ""
if nClient == nil {
return nil, fmt.Errorf("nutanix client cannot be nil when getting prism central cluster")
Expand All @@ -423,7 +424,7 @@ func (n *nutanixManager) getPrismCentralCluster(ctx context.Context, nClient int
return nil, err
}

foundPCs := make([]*prismClientV3.ClusterIntentResponse, 0)
foundPCs := make([]*prismclientv3.ClusterIntentResponse, 0)
for _, s := range responsePEs.Entities {
if n.hasPEClusterServiceEnabled(s, constants.PrismCentralService) {
foundPCs = append(foundPCs, s)
Expand All @@ -439,7 +440,7 @@ func (n *nutanixManager) getPrismCentralCluster(ctx context.Context, nClient int
return nil, fmt.Errorf("more than one Prism Central cluster ")
}

func (n *nutanixManager) hasPEClusterServiceEnabled(peCluster *prismClientV3.ClusterIntentResponse, serviceName string) bool {
func (n *nutanixManager) hasPEClusterServiceEnabled(peCluster *prismclientv3.ClusterIntentResponse, serviceName string) bool {
if peCluster.Status == nil ||
peCluster.Status.Resources == nil ||
peCluster.Status.Resources.Config == nil {
Expand Down
3 changes: 1 addition & 2 deletions pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package provider
import (
"fmt"
"io"
"io/ioutil"

clientset "k8s.io/client-go/kubernetes"
cloudprovider "k8s.io/cloud-provider"
Expand All @@ -46,7 +45,7 @@ func init() {
}

func newNtnxCloud(configReader io.Reader) (cloudprovider.Interface, error) {
bytes, err := ioutil.ReadAll(configReader)
bytes, err := io.ReadAll(configReader)
if err != nil {
klog.Infof("Error in initializing %s cloudprovid config %q\n", constants.ProviderName, err)
return nil, err
Expand Down

0 comments on commit 1c71a1f

Please sign in to comment.