@@ -3,6 +3,7 @@ package oracle
33import (
44 "context"
55 "encoding/json"
6+ "errors"
67 "fmt"
78 "io/ioutil"
89 "net/http"
@@ -38,13 +39,16 @@ const (
3839 MetadataUserDataKey = "user_data"
3940 metadataTenancyIDKey = "oke-tenancy-id"
4041 metadataPoolIDKey = "oke-pool-id"
42+ metadataClusterIDKey = "oke-cluster-id"
4143 envPrefix = "PX_ORACLE"
4244 envInstanceID = "INSTANCE_ID"
4345 envRegion = "INSTANCE_REGION"
4446 envAvailabilityDomain = "INSTNACE_AVAILABILITY_DOMAIN"
4547 envCompartmentID = "COMPARTMENT_ID"
4648 envTenancyID = "TENANCY_ID"
4749 envPoolID = "POOL_ID"
50+ envClusterID = "CLUSTER_ID"
51+ defaultTimeout = 5 * time .Minute
4852)
4953
5054type oracleOps struct {
@@ -56,6 +60,7 @@ type oracleOps struct {
5660 compartmentID string
5761 tenancyID string
5862 poolID string
63+ clusterID string
5964 volumeAttachmentMapping map [string ]* string
6065 storage core.BlockstorageClient
6166 compute core.ComputeClient
@@ -125,6 +130,11 @@ func getInfoFromEnv(oracleOps *oracleOps) error {
125130 if err != nil {
126131 return err
127132 }
133+
134+ oracleOps .clusterID , err = cloudops .GetEnvValueStrict (envClusterID )
135+ if err != nil {
136+ return err
137+ }
128138 return nil
129139}
130140
@@ -204,7 +214,7 @@ func GetMetadata() (map[string]interface{}, error) {
204214}
205215
206216func getInfoFromMetadata (oracleOps * oracleOps ) error {
207- var tenancyID , poolID string
217+ var tenancyID , poolID , clusterID string
208218 var ok bool
209219 metadata , err := GetMetadata ()
210220 if err != nil {
@@ -219,13 +229,17 @@ func getInfoFromMetadata(oracleOps *oracleOps) error {
219229 if poolID , ok = okeMetadata [metadataPoolIDKey ].(string ); ! ok {
220230 return fmt .Errorf ("can not get pool ID from oracle metadata service. error: [%v]" , err )
221231 }
232+ if clusterID , ok = okeMetadata [metadataClusterIDKey ].(string ); ! ok {
233+ return fmt .Errorf ("can not get cluster ID from oracle metadata service. error: [%v]" , err )
234+ }
222235 }
223236 } else {
224237 return fmt .Errorf ("can not get OKE metadata from oracle metadata service. error: [%v]" , err )
225238 }
226239 }
227240 oracleOps .tenancyID = tenancyID
228241 oracleOps .poolID = poolID
242+ oracleOps .clusterID = clusterID
229243 if oracleOps .instance , ok = metadata [metadataInstanceIDkey ].(string ); ! ok {
230244 return fmt .Errorf ("can not get instance id from oracle metadata service. error: [%v]" , err )
231245 }
@@ -459,6 +473,111 @@ func (o *oracleOps) Delete(volumeID string) error {
459473 return nil
460474}
461475
476+ func (o * oracleOps ) SetInstanceGroupSize (instanceGroupID string , count int64 , timeout time.Duration ) error {
477+
478+ if timeout == 0 * time .Second {
479+ timeout = defaultTimeout
480+ }
481+
482+ instanceGroupSize := int (count )
483+
484+ //get nodepool by ID to be updated
485+ nodePoolReq := containerengine.ListNodePoolsRequest {CompartmentId : & o .compartmentID , Name : & instanceGroupID , ClusterId : & o .clusterID }
486+ nodePools , err := o .containerEngine .ListNodePools (context .Background (), nodePoolReq )
487+ if err != nil {
488+ return err
489+ }
490+
491+ if len (nodePools .Items ) == 0 {
492+ return errors .New ("No node pool found with name " + instanceGroupID )
493+ }
494+ numberOfDomains := len (nodePools .Items [0 ].NodeConfigDetails .PlacementConfigs )
495+ totalClusterSize := numberOfDomains * instanceGroupSize
496+ logrus .Println ("Setting instanceGroupSize to " , totalClusterSize , " in total " , numberOfDomains , " regions." )
497+
498+ //get all availabliity domain
499+ nodePoolPlacementConfigDetails := make ([]containerengine.NodePoolPlacementConfigDetails , numberOfDomains )
500+
501+ for i , placementConfigs := range nodePools .Items [0 ].NodeConfigDetails .PlacementConfigs {
502+ nodePoolPlacementConfigDetails [i ].AvailabilityDomain = placementConfigs .AvailabilityDomain
503+ nodePoolPlacementConfigDetails [i ].SubnetId = placementConfigs .SubnetId
504+ }
505+
506+ //update node pools
507+ req := containerengine.UpdateNodePoolRequest {
508+ NodePoolId : nodePools .Items [0 ].Id , //get node pool id
509+ UpdateNodePoolDetails : containerengine.UpdateNodePoolDetails {
510+ NodeConfigDetails : & containerengine.UpdateNodePoolNodeConfigDetails {
511+ Size : & totalClusterSize ,
512+ PlacementConfigs : nodePoolPlacementConfigDetails ,
513+ },
514+ },
515+ }
516+
517+ resp , err := o .containerEngine .UpdateNodePool (context .Background (), req )
518+ if err != nil {
519+ return err
520+ }
521+
522+ err = o .waitTillWorkStatusIsSucceeded (resp .OpcRequestId , resp .OpcWorkRequestId , timeout )
523+ if err != nil {
524+ return err
525+ }
526+
527+ return nil
528+ }
529+
530+ func (o * oracleOps ) waitTillWorkStatusIsSucceeded (opcRequestID , opcWorkRequestID * string , timeout time.Duration ) error {
531+ workReq := containerengine.GetWorkRequestRequest {OpcRequestId : opcRequestID ,
532+ WorkRequestId : opcWorkRequestID }
533+
534+ f := func () (interface {}, bool , error ) {
535+ workResp , err := o .containerEngine .GetWorkRequest (context .Background (), workReq )
536+ if err != nil {
537+ return nil , true , err
538+ }
539+
540+ if workResp .Status == containerengine .WorkRequestStatusSucceeded {
541+ return workResp .Status , false , nil
542+ }
543+
544+ logrus .Debugf ("Work status is in [%s] state" , workResp .Status )
545+ return nil , true , fmt .Errorf ("Work status is in [%s] state" , workResp .Status )
546+ }
547+ _ , err := task .DoRetryWithTimeout (f , timeout , 10 * time .Second )
548+ return err
549+ }
550+
551+ func (o * oracleOps ) GetInstanceGroupSize (instanceGroupID string ) (int64 , error ) {
552+
553+ var count int64
554+
555+ nodePoolReq := containerengine.ListNodePoolsRequest {CompartmentId : & o .compartmentID , Name : & instanceGroupID , ClusterId : & o .clusterID }
556+ nodePools , err := o .containerEngine .ListNodePools (context .Background (), nodePoolReq )
557+ if err != nil {
558+ return 0 , err
559+ }
560+
561+ if len (nodePools .Items ) == 0 {
562+ return 0 , errors .New ("No node pool found with name " + instanceGroupID )
563+ }
564+
565+ req := containerengine.GetNodePoolRequest {NodePoolId : nodePools .Items [0 ].Id }
566+
567+ resp , err := o .containerEngine .GetNodePool (context .Background (), req )
568+
569+ if err != nil {
570+ return 0 , err
571+ }
572+
573+ for _ , node := range resp .Nodes {
574+ if node .LifecycleState == containerengine .NodeLifecycleStateActive {
575+ count ++
576+ }
577+ }
578+ return count , nil
579+ }
580+
462581// Attach volumeID, accepts attachOptions as opaque data
463582// Return attach path.
464583func (o * oracleOps ) Attach (volumeID string , options map [string ]string ) (string , error ) {
@@ -608,4 +727,5 @@ func (o *oracleOps) GetDeviceID(vol interface{}) (string, error) {
608727 return * d .Id , nil
609728 }
610729 return "" , fmt .Errorf ("invalid type: %v given to GetDeviceID" , vol )
730+
611731}
0 commit comments