github.com/chnsz/golangsdk@v0.0.0-20240506093406-85a3fbfa605b/openstack/cce/v3/nodes/requests.go (about) 1 package nodes 2 3 import ( 4 "reflect" 5 6 "github.com/chnsz/golangsdk" 7 "github.com/chnsz/golangsdk/openstack/common/tags" 8 ) 9 10 var RequestOpts golangsdk.RequestOpts = golangsdk.RequestOpts{ 11 MoreHeaders: map[string]string{"Content-Type": "application/json"}, 12 } 13 14 // ListOpts allows the filtering of list data using given parameters. 15 type ListOpts struct { 16 Name string `json:"name"` 17 Uid string `json:"uid"` 18 Phase string `json:"phase"` 19 } 20 21 // List returns collection of nodes. 22 func List(client *golangsdk.ServiceClient, clusterID string, opts ListOpts) ([]Nodes, error) { 23 var r ListResult 24 _, r.Err = client.Get(rootURL(client, clusterID), &r.Body, &golangsdk.RequestOpts{ 25 OkCodes: []int{200}, 26 MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, 27 }) 28 29 allNodes, err := r.ExtractNode() 30 31 if err != nil { 32 return nil, err 33 } 34 35 return FilterNodes(allNodes, opts), nil 36 } 37 38 func FilterNodes(nodes []Nodes, opts ListOpts) []Nodes { 39 40 var refinedNodes []Nodes 41 var matched bool 42 43 m := map[string]FilterStruct{} 44 45 if opts.Name != "" { 46 m["Name"] = FilterStruct{Value: opts.Name, Driller: []string{"Metadata"}} 47 } 48 if opts.Uid != "" { 49 m["Id"] = FilterStruct{Value: opts.Uid, Driller: []string{"Metadata"}} 50 } 51 52 if opts.Phase != "" { 53 m["Phase"] = FilterStruct{Value: opts.Phase, Driller: []string{"Status"}} 54 } 55 56 if len(m) > 0 && len(nodes) > 0 { 57 for _, nodes := range nodes { 58 matched = true 59 60 for key, value := range m { 61 if sVal := GetStructNestedField(&nodes, key, value.Driller); !(sVal == value.Value) { 62 matched = false 63 } 64 } 65 if matched { 66 refinedNodes = append(refinedNodes, nodes) 67 } 68 } 69 } else { 70 refinedNodes = nodes 71 } 72 return refinedNodes 73 } 74 75 func GetStructNestedField(v *Nodes, field string, structDriller []string) string { 76 r := reflect.ValueOf(v) 77 for _, drillField := range structDriller { 78 f := reflect.Indirect(r).FieldByName(drillField).Interface() 79 r = reflect.ValueOf(f) 80 } 81 f1 := reflect.Indirect(r).FieldByName(field) 82 return string(f1.String()) 83 } 84 85 type FilterStruct struct { 86 Value string 87 Driller []string 88 } 89 90 // CreateOptsBuilder allows extensions to add additional parameters to the 91 // Create request. 92 type CreateOpts struct { 93 // API type, fixed value Node 94 Kind string `json:"kind" required:"true"` 95 // API version, fixed value v3 96 ApiVersion string `json:"apiversion" required:"true"` 97 // Metadata required to create a Node 98 Metadata CreateMetaData `json:"metadata"` 99 // specifications to create a Node 100 Spec Spec `json:"spec" required:"true"` 101 } 102 103 // Metadata required to create a Node 104 type CreateMetaData struct { 105 // Node name 106 Name string `json:"name,omitempty"` 107 // Node tag, key value pair format 108 Labels map[string]string `json:"labels,omitempty"` 109 // Node annotation, key value pair format 110 Annotations map[string]string `json:"annotations,omitempty"` 111 } 112 113 // Create accepts a CreateOpts struct and uses the values to create a new 114 // logical Node. When it is created, the Node does not have an internal 115 // interface 116 type CreateOptsBuilder interface { 117 ToNodeCreateMap() (map[string]interface{}, error) 118 } 119 120 // ToNodeCreateMap builds a create request body from CreateOpts. 121 func (opts CreateOpts) ToNodeCreateMap() (map[string]interface{}, error) { 122 return golangsdk.BuildRequestBody(opts, "") 123 } 124 125 // Create accepts a CreateOpts struct and uses the values to create a new 126 // logical node. 127 func Create(c *golangsdk.ServiceClient, clusterid string, opts CreateOptsBuilder) (r CreateResult) { 128 b, err := opts.ToNodeCreateMap() 129 if err != nil { 130 r.Err = err 131 return 132 } 133 reqOpt := &golangsdk.RequestOpts{OkCodes: []int{201}} 134 _, r.Err = c.Post(rootURL(c, clusterid), b, &r.Body, reqOpt) 135 return 136 } 137 138 type AddOpts struct { 139 // API type, fixed value List 140 Kind string `json:"kind" required:"true"` 141 // API version, fixed value v3 142 ApiVersion string `json:"apiversion" required:"true"` 143 // List of nodes to add 144 NodeList []AddNode `json:"nodeList" required:"true"` 145 } 146 147 type AddNode struct { 148 ServerID string `json:"serverID" required:"true"` 149 Spec AddNodeSpec `json:"spec" required:"true"` 150 } 151 152 type AddNodeSpec struct { 153 // The OS of the node 154 Os string `json:"os" required:"true"` 155 // Node login parameters 156 Login LoginSpec `json:"login" required:"true"` 157 //Node name 158 Name string `json:"name,omitempty"` 159 // ECS server config of the node 160 ServerConfig *ServerConfig `json:"serverConfig,omitempty"` 161 // Volume management config of the node 162 VolumeConfig *VolumeConfig `json:"volumeConfig,omitempty"` 163 // Runtime config of the node 164 RuntimeConfig *RuntimeConfig `json:"runtimeConfig,omitempty"` 165 // Kubernetes options of the node 166 K8sOptions *K8sOptions `json:"k8sOptions,omitempty"` 167 // Custom lifecycle config of the node 168 Lifecycle *Lifecycle `json:"lifecycle,omitempty"` 169 // Extended parameter 170 ExtendParam map[string]interface{} `json:"extendParam,omitempty"` 171 // The initialized conditions 172 InitializedConditions []string `json:"initializedConditions,omitempty"` 173 } 174 175 type ServerConfig struct { 176 // Tag of a VM, key value pair format 177 UserTags []tags.ResourceTag `json:"userTags,omitempty"` 178 // System disk parameter of the node 179 RootVolume *RootVolume 180 } 181 182 type RootVolume struct { 183 // Custom image ID 184 ImageID string `json:"imageID,omitempty"` 185 // User master key ID, default to empty, means the disk in not encrypted 186 CmkID string `json:"cmkID,omitempty"` 187 } 188 189 type VolumeConfig struct { 190 // Docker data disk configurations 191 LvmConfig string `json:"lvmConfig,omitempty"` 192 // Disk initialization configuration management parameters 193 Storage *StorageSpec `json:"storage,omitempty"` 194 } 195 196 type RuntimeConfig struct { 197 // The available disk space of a single Docker container on the node in device mapper mode 198 DockerBaseSize int `json:"dockerBaseSize,omitempty"` 199 // The runtime spec 200 Runtime *RunTimeSpec `json:"runtime,omitempty"` 201 } 202 203 type K8sOptions struct { 204 // Tag of a Kubernetes node, key value pair format 205 Labels map[string]string `json:"labels,omitempty"` 206 // taints to created nodes to configure anti-affinity 207 Taints []TaintSpec `json:"taints,omitempty"` 208 // The maximum number of pods allowed to be created on a node 209 MaxPods int `json:"maxPods,omitempty"` 210 // NIC queue number configuration 211 NicMultiQueue string `json:"nicMultiqueue,omitempty"` 212 // NIC pre-binding ratio configuration 213 NicThreshold string `json:"nicThreshold,omitempty"` 214 } 215 216 type Lifecycle struct { 217 // Preinstall script 218 Preinstall string `json:"preInstall,omitempty"` 219 // Postinstall script 220 PostInstall string `json:"postInstall,omitempty"` 221 } 222 223 type AddOptsBuilder interface { 224 ToNodeAddMap() (map[string]interface{}, error) 225 } 226 227 func (opts AddOpts) ToNodeAddMap() (map[string]interface{}, error) { 228 return golangsdk.BuildRequestBody(opts, "") 229 } 230 231 func Add(c *golangsdk.ServiceClient, clusterid string, opts AddOptsBuilder) (r AddResult) { 232 b, err := opts.ToNodeAddMap() 233 if err != nil { 234 r.Err = err 235 return 236 } 237 reqOpt := &golangsdk.RequestOpts{OkCodes: []int{200}} 238 _, r.Err = c.Post(addNodeURL(c, clusterid), b, &r.Body, reqOpt) 239 return 240 } 241 242 type ResetOpts struct { 243 // API type, fixed value List 244 Kind string `json:"kind" required:"true"` 245 // API version, fixed value v3 246 ApiVersion string `json:"apiversion" required:"true"` 247 // List of nodes to reset 248 NodeList []ResetNode `json:"nodeList" required:"true"` 249 } 250 251 type ResetNode struct { 252 NodeID string `json:"nodeID" required:"true"` 253 Spec AddNodeSpec `json:"spec" required:"true"` 254 } 255 256 type ResetOptsBuilder interface { 257 ToNodeResetMap() (map[string]interface{}, error) 258 } 259 260 func (opts ResetOpts) ToNodeResetMap() (map[string]interface{}, error) { 261 return golangsdk.BuildRequestBody(opts, "") 262 } 263 264 func Reset(c *golangsdk.ServiceClient, clusterid string, opts ResetOptsBuilder) (r AddResult) { 265 b, err := opts.ToNodeResetMap() 266 if err != nil { 267 r.Err = err 268 return 269 } 270 _, r.Err = c.Post(resetNodeURL(c, clusterid), b, &r.Body, nil) 271 return 272 } 273 274 // Get retrieves a particular nodes based on its unique ID and cluster ID. 275 func Get(c *golangsdk.ServiceClient, clusterid, nodeid string) (r GetResult) { 276 _, r.Err = c.Get(resourceURL(c, clusterid, nodeid), &r.Body, &golangsdk.RequestOpts{ 277 OkCodes: []int{200}, 278 MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, 279 }) 280 return 281 } 282 283 // UpdateOptsBuilder allows extensions to add additional parameters to the 284 // Update request. 285 type UpdateOptsBuilder interface { 286 ToNodeUpdateMap() (map[string]interface{}, error) 287 } 288 289 // UpdateOpts contains all the values needed to update a new node 290 type UpdateOpts struct { 291 Metadata UpdateMetadata `json:"metadata,omitempty"` 292 } 293 294 type UpdateMetadata struct { 295 Name string `json:"name,omitempty"` 296 } 297 298 // ToNodeUpdateMap builds an update body based on UpdateOpts. 299 func (opts UpdateOpts) ToNodeUpdateMap() (map[string]interface{}, error) { 300 return golangsdk.BuildRequestBody(opts, "") 301 } 302 303 // Update allows nodes to be updated. 304 func Update(c *golangsdk.ServiceClient, clusterid, nodeid string, opts UpdateOptsBuilder) (r UpdateResult) { 305 b, err := opts.ToNodeUpdateMap() 306 if err != nil { 307 r.Err = err 308 return 309 } 310 _, r.Err = c.Put(resourceURL(c, clusterid, nodeid), b, &r.Body, &golangsdk.RequestOpts{ 311 OkCodes: []int{200}, 312 }) 313 return 314 } 315 316 // Delete will permanently delete a particular node based on its unique ID and cluster ID. 317 func Delete(c *golangsdk.ServiceClient, clusterid, nodeid string) (r DeleteResult) { 318 _, r.Err = c.Delete(resourceURL(c, clusterid, nodeid), &golangsdk.RequestOpts{ 319 OkCodes: []int{200}, 320 MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, 321 }) 322 return 323 } 324 325 type RemoveOptsBuilder interface { 326 ToNodeRemoveMap() (map[string]interface{}, error) 327 } 328 329 type RemoveOpts struct { 330 // API type, fixed value RemoveNodesTask 331 Kind string `json:"kind,omitempty"` 332 // API version, fixed value v3 333 Apiversion string `json:"apiVersion,omitempty"` 334 335 Spec RemoveNodeSpec `json:"spec" required:"true"` 336 } 337 338 type RemoveNodeSpec struct { 339 Login LoginSpec `json:"login" required:"true"` 340 Nodes []NodeItem `json:"nodes,omitempty"` 341 } 342 343 type NodeItem struct { 344 Uid string `json:"uid,omitempty"` 345 } 346 347 func (opts RemoveOpts) ToNodeRemoveMap() (map[string]interface{}, error) { 348 return golangsdk.BuildRequestBody(opts, "") 349 } 350 351 func Remove(c *golangsdk.ServiceClient, clusterid string, opts RemoveOptsBuilder) (r DeleteResult) { 352 b, err := opts.ToNodeRemoveMap() 353 if err != nil { 354 r.Err = err 355 return 356 } 357 358 _, r.Err = c.Put(removeNodeURL(c, clusterid), b, nil, &golangsdk.RequestOpts{ 359 OkCodes: []int{200}, 360 MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, 361 }) 362 363 return 364 } 365 366 // GetJobDetails retrieves a particular job based on its unique ID 367 func GetJobDetails(c *golangsdk.ServiceClient, jobid string) (r GetResult) { 368 _, r.Err = c.Get(getJobURL(c, jobid), &r.Body, &golangsdk.RequestOpts{ 369 OkCodes: []int{200}, 370 MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, 371 }) 372 return 373 }