github.com/chnsz/golangsdk@v0.0.0-20240506093406-85a3fbfa605b/openstack/cce/v3/clusters/requests.go (about)

     1  package clusters
     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  	ID                  string `json:"uuid"`
    18  	Type                string `json:"type"`
    19  	VpcID               string `json:"vpc"`
    20  	Phase               string `json:"phase"`
    21  	EnterpriseProjectID string `json:"enterpriseProjectId"`
    22  }
    23  
    24  // List returns collection of clusters.
    25  func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Clusters, error) {
    26  	var r ListResult
    27  	_, r.Err = client.Get(rootURL(client), &r.Body, &golangsdk.RequestOpts{
    28  		OkCodes:     []int{200},
    29  		MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil,
    30  	})
    31  
    32  	allClusters, err := r.ExtractClusters()
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  
    37  	return FilterClusters(allClusters, opts), nil
    38  }
    39  
    40  func FilterClusters(clusters []Clusters, opts ListOpts) []Clusters {
    41  
    42  	var refinedClusters []Clusters
    43  	var matched bool
    44  	m := map[string]FilterStruct{}
    45  
    46  	if opts.Name != "" {
    47  		m["Name"] = FilterStruct{Value: opts.Name, Driller: []string{"Metadata"}}
    48  	}
    49  	if opts.ID != "" {
    50  		m["Id"] = FilterStruct{Value: opts.ID, Driller: []string{"Metadata"}}
    51  	}
    52  	if opts.Type != "" {
    53  		m["Type"] = FilterStruct{Value: opts.Type, Driller: []string{"Spec"}}
    54  	}
    55  	if opts.VpcID != "" {
    56  		m["VpcId"] = FilterStruct{Value: opts.VpcID, Driller: []string{"Spec", "HostNetwork"}}
    57  	}
    58  	if opts.Phase != "" {
    59  		m["Phase"] = FilterStruct{Value: opts.Phase, Driller: []string{"Status"}}
    60  	}
    61  	if opts.EnterpriseProjectID != "" {
    62  		m["enterpriseProjectId"] = FilterStruct{Value: opts.EnterpriseProjectID, Driller: []string{"Spec", "ExtendParam"}}
    63  	}
    64  
    65  	if len(m) > 0 && len(clusters) > 0 {
    66  		for _, cluster := range clusters {
    67  			matched = true
    68  
    69  			for key, value := range m {
    70  				if sVal := GetStructNestedField(&cluster, key, value.Driller); !(sVal == value.Value) {
    71  					matched = false
    72  				}
    73  			}
    74  			if matched {
    75  				refinedClusters = append(refinedClusters, cluster)
    76  			}
    77  		}
    78  
    79  	} else {
    80  		refinedClusters = clusters
    81  	}
    82  
    83  	return refinedClusters
    84  }
    85  
    86  type FilterStruct struct {
    87  	Value   string
    88  	Driller []string
    89  }
    90  
    91  func GetStructNestedField(v *Clusters, field string, structDriller []string) string {
    92  	r := reflect.ValueOf(v)
    93  	for _, drillField := range structDriller {
    94  		f := reflect.Indirect(r).FieldByName(drillField).Interface()
    95  		r = reflect.ValueOf(f)
    96  	}
    97  
    98  	if r.Kind() == reflect.Map {
    99  		keys := r.MapKeys()
   100  		for _, k := range keys {
   101  			if k.String() == field {
   102  				f1 := r.MapIndex(k)
   103  				return f1.Interface().(string)
   104  			}
   105  		}
   106  		return ""
   107  	} else {
   108  		f1 := reflect.Indirect(r).FieldByName(field)
   109  		return f1.String()
   110  	}
   111  }
   112  
   113  // CreateOptsBuilder allows extensions to add additional parameters to the
   114  // Create request.
   115  type CreateOptsBuilder interface {
   116  	ToClusterCreateMap() (map[string]interface{}, error)
   117  }
   118  
   119  // CreateOpts contains all the values needed to create a new cluster
   120  type CreateOpts struct {
   121  	// API type, fixed value Cluster
   122  	Kind string `json:"kind" required:"true"`
   123  	// API version, fixed value v3
   124  	ApiVersion string `json:"apiversion" required:"true"`
   125  	// Metadata required to create a cluster
   126  	Metadata CreateMetaData `json:"metadata" required:"true"`
   127  	// specifications to create a cluster
   128  	Spec Spec `json:"spec" required:"true"`
   129  }
   130  
   131  // Metadata required to create a cluster
   132  type CreateMetaData struct {
   133  	// Cluster unique name
   134  	Name string `json:"name" required:"true"`
   135  	// Cluster tag, key/value pair format
   136  	Labels map[string]string `json:"labels,omitempty"`
   137  	// Cluster annotation, key/value pair format
   138  	Annotations map[string]string `json:"annotations,omitempty"`
   139  	// Cluster alias
   140  	Alias string `json:"alias,omitempty"`
   141  }
   142  
   143  // ToClusterCreateMap builds a create request body from CreateOpts.
   144  func (opts CreateOpts) ToClusterCreateMap() (map[string]interface{}, error) {
   145  	return golangsdk.BuildRequestBody(opts, "")
   146  }
   147  
   148  // Create accepts a CreateOpts struct and uses the values to create a new
   149  // logical cluster.
   150  func Create(c *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
   151  	b, err := opts.ToClusterCreateMap()
   152  	if err != nil {
   153  		r.Err = err
   154  		return
   155  	}
   156  	reqOpt := &golangsdk.RequestOpts{OkCodes: []int{201}}
   157  	_, r.Err = c.Post(rootURL(c), b, &r.Body, reqOpt)
   158  	return
   159  }
   160  
   161  // Get retrieves a particular cluster based on its unique ID.
   162  func Get(c *golangsdk.ServiceClient, id string) (r GetResult) {
   163  	_, r.Err = c.Get(resourceURL(c, id), &r.Body, &golangsdk.RequestOpts{
   164  		OkCodes:     []int{200},
   165  		MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil,
   166  	})
   167  	return
   168  }
   169  
   170  // GetCert retrieves a particular cluster certificate based on its unique ID.
   171  func GetCert(c *golangsdk.ServiceClient, id string, opts GetCertOpts) (r GetCertResult) {
   172  	body, err := golangsdk.BuildRequestBody(opts, "")
   173  	if err != nil {
   174  		r.Err = err
   175  		return
   176  	}
   177  	_, r.Err = c.Post(certificateURL(c, id), body, &r.Body, nil)
   178  	return
   179  }
   180  
   181  type GetCertOpts struct {
   182  	Duration int `json:"duration" required:"true"`
   183  }
   184  
   185  // UpdateOpts contains all the values needed to update a new cluster
   186  type UpdateOpts struct {
   187  	Spec     UpdateSpec      `json:"spec" required:"true"`
   188  	Metadata *UpdateMetadata `json:"metadata,omitempty"`
   189  }
   190  
   191  type UpdateMetadata struct {
   192  	// Cluster alias
   193  	Alias string `json:"alias"`
   194  }
   195  
   196  type UpdateSpec struct {
   197  	// Cluster description
   198  	Description string `json:"description,omitempty"`
   199  	// Custom san list for certificates
   200  	CustomSan []string `json:"customSan,omitempty"`
   201  	//Container network parameters
   202  	ContainerNetwork *UpdateContainerNetworkSpec `json:"containerNetwork,omitempty"`
   203  	// ENI network parameters
   204  	EniNetwork *EniNetworkSpec `json:"eniNetwork,omitempty"`
   205  	// Node network parameters
   206  	HostNetwork *UpdateHostNetworkSpec `json:"hostNetwork,omitempty"`
   207  }
   208  
   209  type UpdateContainerNetworkSpec struct {
   210  	// List of container CIDR blocks. In clusters of v1.21 and later, the cidrs field is used.
   211  	// When the cluster network type is vpc-router, you can add multiple container CIDR blocks.
   212  	// In versions earlier than v1.21, if the cidrs field is used, the first CIDR element in the array is used as the container CIDR block.
   213  	Cidrs []CidrSpec `json:"cidrs,omitempty"`
   214  }
   215  
   216  type UpdateHostNetworkSpec struct {
   217  	//The ID of the Security Group used to create the node
   218  	SecurityGroup string `json:"SecurityGroup,omitempty"`
   219  }
   220  
   221  // UpdateOptsBuilder allows extensions to add additional parameters to the
   222  // Update request.
   223  type UpdateOptsBuilder interface {
   224  	ToClusterUpdateMap() (map[string]interface{}, error)
   225  }
   226  
   227  // ToClusterUpdateMap builds an update body based on UpdateOpts.
   228  func (opts UpdateOpts) ToClusterUpdateMap() (map[string]interface{}, error) {
   229  	return golangsdk.BuildRequestBody(opts, "")
   230  }
   231  
   232  // Update allows clusters to update description.
   233  func Update(c *golangsdk.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
   234  	b, err := opts.ToClusterUpdateMap()
   235  	if err != nil {
   236  		r.Err = err
   237  		return
   238  	}
   239  	_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &golangsdk.RequestOpts{
   240  		OkCodes: []int{200},
   241  	})
   242  	return
   243  }
   244  
   245  type DeleteOpts struct {
   246  	ErrorStatus string `q:"errorStatus"`
   247  	DeleteEfs   string `q:"delete_efs"`
   248  	DeleteENI   string `q:"delete_eni"`
   249  	DeleteEvs   string `q:"delete_evs"`
   250  	DeleteNet   string `q:"delete_net"`
   251  	DeleteObs   string `q:"delete_obs"`
   252  	DeleteSfs   string `q:"delete_sfs"`
   253  	DeleteSfs30 string `q:"delete_sfs30"`
   254  }
   255  
   256  type DeleteOptsBuilder interface {
   257  	ToDeleteQuery() (string, error)
   258  }
   259  
   260  func (opts DeleteOpts) ToDeleteQuery() (string, error) {
   261  	q, err := golangsdk.BuildQueryString(opts)
   262  	return q.String(), err
   263  }
   264  
   265  // DeleteWithOpts will permanently delete a particular cluster based on its unique ID,
   266  // and can delete associated resources based on DeleteOpts.
   267  func DeleteWithOpts(c *golangsdk.ServiceClient, id string, opts DeleteOptsBuilder) (r DeleteResult) {
   268  	url := resourceURL(c, id)
   269  	if opts != nil {
   270  		var query string
   271  		query, r.Err = opts.ToDeleteQuery()
   272  		if r.Err != nil {
   273  			return
   274  		}
   275  		url += query
   276  	}
   277  	_, r.Err = c.Delete(url, &golangsdk.RequestOpts{
   278  		OkCodes:     []int{200},
   279  		MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil,
   280  	})
   281  	return
   282  }
   283  
   284  // Delete will permanently delete a particular cluster based on its unique ID.
   285  func Delete(c *golangsdk.ServiceClient, id string) (r DeleteResult) {
   286  	_, r.Err = c.Delete(resourceURL(c, id), &golangsdk.RequestOpts{
   287  		OkCodes:     []int{200},
   288  		MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil,
   289  	})
   290  	return
   291  }
   292  
   293  type UpdateIpOpts struct {
   294  	Action    string `json:"action" required:"true"`
   295  	Spec      IpSpec `json:"spec,omitempty"`
   296  	ElasticIp string `json:"elasticIp"`
   297  }
   298  
   299  type IpSpec struct {
   300  	ID string `json:"id" required:"true"`
   301  }
   302  
   303  type UpdateIpOptsBuilder interface {
   304  	ToMasterIpUpdateMap() (map[string]interface{}, error)
   305  }
   306  
   307  func (opts UpdateIpOpts) ToMasterIpUpdateMap() (map[string]interface{}, error) {
   308  	return golangsdk.BuildRequestBody(opts, "spec")
   309  }
   310  
   311  // Update the access information of a specified cluster.
   312  func UpdateMasterIp(c *golangsdk.ServiceClient, id string, opts UpdateIpOptsBuilder) (r UpdateIpResult) {
   313  	b, err := opts.ToMasterIpUpdateMap()
   314  	if err != nil {
   315  		r.Err = err
   316  		return
   317  	}
   318  	_, r.Err = c.Put(masterIpURL(c, id), b, nil, &golangsdk.RequestOpts{
   319  		OkCodes: []int{200},
   320  	})
   321  	return
   322  }
   323  
   324  func Operation(c *golangsdk.ServiceClient, id, action string) (r OperationResult) {
   325  	_, r.Err = c.Post(operationURL(c, id, action), nil, nil, &golangsdk.RequestOpts{
   326  		OkCodes:     []int{200},
   327  		MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil,
   328  	})
   329  	return
   330  }
   331  
   332  type ResizeOpts struct {
   333  	FavorResize string             `json:"flavorResize" required:"true"`
   334  	ExtendParam *ResizeExtendParam `json:"extendParam,omitempty"`
   335  }
   336  
   337  type ResizeExtendParam struct {
   338  	DecMasterFlavor string `json:"decMasterFlavor,omitempty"`
   339  	IsAutoPay       string `json:"isAutoPay,omitempty"`
   340  }
   341  
   342  type ResizeResp struct {
   343  	JobID   string `json:"jobID"`
   344  	OrderID string `json:"orderID"`
   345  }
   346  
   347  func Resize(c *golangsdk.ServiceClient, id string, opts ResizeOpts) (ResizeResp, error) {
   348  	var r ResizeResp
   349  	b, err := golangsdk.BuildRequestBody(opts, "")
   350  	if err != nil {
   351  		return r, err
   352  	}
   353  
   354  	_, err = c.Post(operationURL(c, id, "resize"), b, &r, &golangsdk.RequestOpts{
   355  		OkCodes:     []int{201},
   356  		MoreHeaders: RequestOpts.MoreHeaders,
   357  	})
   358  	return r, err
   359  }
   360  
   361  type UpdateTagsOpts struct {
   362  	Tags []tags.ResourceTag `json:"tags" required:"true"`
   363  }
   364  
   365  // AddTags will add tags to the cluster.
   366  func AddTags(c *golangsdk.ServiceClient, id string, tagList []tags.ResourceTag) (r UpdateIpResult) {
   367  	opts := UpdateTagsOpts{
   368  		Tags: tagList,
   369  	}
   370  	b, err := golangsdk.BuildRequestBody(opts, "")
   371  	if err != nil {
   372  		r.Err = err
   373  		return
   374  	}
   375  	_, r.Err = c.Post(tagsURL(c, id, "create"), b, nil, &golangsdk.RequestOpts{
   376  		OkCodes: []int{204},
   377  	})
   378  	return
   379  }
   380  
   381  // RemoveTags will remove tags from the cluster.
   382  func RemoveTags(c *golangsdk.ServiceClient, id string, tagList []tags.ResourceTag) (r UpdateIpResult) {
   383  	tagsWithKeys := make([]tags.ResourceTag, len(tagList))
   384  	for i, v := range tagList {
   385  		tagsWithKeys[i] = tags.ResourceTag{
   386  			Key: v.Key,
   387  		}
   388  	}
   389  	opts := UpdateTagsOpts{
   390  		Tags: tagsWithKeys,
   391  	}
   392  	b, err := golangsdk.BuildRequestBody(opts, "")
   393  	if err != nil {
   394  		r.Err = err
   395  		return
   396  	}
   397  	_, r.Err = c.Post(tagsURL(c, id, "delete"), b, nil, &golangsdk.RequestOpts{
   398  		OkCodes: []int{204},
   399  	})
   400  	return
   401  }