github.com/gophercloud/gophercloud@v1.11.0/openstack/clustering/v1/clusters/requests.go (about)

     1  package clusters
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/gophercloud/gophercloud"
     7  	"github.com/gophercloud/gophercloud/pagination"
     8  )
     9  
    10  // AdjustmentType represents valid values for resizing a cluster.
    11  type AdjustmentType string
    12  
    13  const (
    14  	ExactCapacityAdjustment      AdjustmentType = "EXACT_CAPACITY"
    15  	ChangeInCapacityAdjustment   AdjustmentType = "CHANGE_IN_CAPACITY"
    16  	ChangeInPercentageAdjustment AdjustmentType = "CHANGE_IN_PERCENTAGE"
    17  )
    18  
    19  // RecoveryAction represents valid values for recovering a cluster.
    20  type RecoveryAction string
    21  
    22  const (
    23  	RebootRecovery   RecoveryAction = "REBOOT"
    24  	RebuildRecovery  RecoveryAction = "REBUILD"
    25  	RecreateRecovery RecoveryAction = "RECREATE"
    26  )
    27  
    28  // CreateOptsBuilder allows extensions to add additional parameters
    29  // to the Create request.
    30  type CreateOptsBuilder interface {
    31  	ToClusterCreateMap() (map[string]interface{}, error)
    32  }
    33  
    34  // CreateOpts represents options used to create a cluster.
    35  type CreateOpts struct {
    36  	Name            string                 `json:"name" required:"true"`
    37  	DesiredCapacity int                    `json:"desired_capacity"`
    38  	ProfileID       string                 `json:"profile_id" required:"true"`
    39  	MinSize         *int                   `json:"min_size,omitempty"`
    40  	Timeout         int                    `json:"timeout,omitempty"`
    41  	MaxSize         int                    `json:"max_size,omitempty"`
    42  	Metadata        map[string]interface{} `json:"metadata,omitempty"`
    43  	Config          map[string]interface{} `json:"config,omitempty"`
    44  }
    45  
    46  // ToClusterCreateMap constructs a request body from CreateOpts.
    47  func (opts CreateOpts) ToClusterCreateMap() (map[string]interface{}, error) {
    48  	return gophercloud.BuildRequestBody(opts, "cluster")
    49  }
    50  
    51  // Create requests the creation of a new cluster.
    52  func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
    53  	b, err := opts.ToClusterCreateMap()
    54  	if err != nil {
    55  		r.Err = err
    56  		return
    57  	}
    58  	resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
    59  		OkCodes: []int{200, 201, 202},
    60  	})
    61  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
    62  	return
    63  }
    64  
    65  // Get retrieves details of a single cluster.
    66  func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
    67  	resp, err := client.Get(getURL(client, id), &r.Body, &gophercloud.RequestOpts{
    68  		OkCodes: []int{200},
    69  	})
    70  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
    71  	return
    72  }
    73  
    74  // ListOptsBuilder allows extensions to add additional parameters to
    75  // the List request.
    76  type ListOptsBuilder interface {
    77  	ToClusterListQuery() (string, error)
    78  }
    79  
    80  // ListOpts represents options to list clusters.
    81  type ListOpts struct {
    82  	Limit         int    `q:"limit"`
    83  	Marker        string `q:"marker"`
    84  	Sort          string `q:"sort"`
    85  	GlobalProject *bool  `q:"global_project"`
    86  	Name          string `q:"name,omitempty"`
    87  	Status        string `q:"status,omitempty"`
    88  }
    89  
    90  // ToClusterListQuery formats a ListOpts into a query string.
    91  func (opts ListOpts) ToClusterListQuery() (string, error) {
    92  	q, err := gophercloud.BuildQueryString(opts)
    93  	return q.String(), err
    94  }
    95  
    96  // List instructs OpenStack to provide a list of clusters.
    97  func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
    98  	url := listURL(client)
    99  	if opts != nil {
   100  		query, err := opts.ToClusterListQuery()
   101  		if err != nil {
   102  			return pagination.Pager{Err: err}
   103  		}
   104  		url += query
   105  	}
   106  
   107  	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
   108  		return ClusterPage{pagination.LinkedPageBase{PageResult: r}}
   109  	})
   110  }
   111  
   112  // UpdateOptsBuilder allows extensions to add additional parameters to the
   113  // Update request.
   114  type UpdateOptsBuilder interface {
   115  	ToClusterUpdateMap() (map[string]interface{}, error)
   116  }
   117  
   118  // UpdateOpts represents options to update a cluster.
   119  type UpdateOpts struct {
   120  	Config      string                 `json:"config,omitempty"`
   121  	Name        string                 `json:"name,omitempty"`
   122  	ProfileID   string                 `json:"profile_id,omitempty"`
   123  	Timeout     *int                   `json:"timeout,omitempty"`
   124  	Metadata    map[string]interface{} `json:"metadata,omitempty"`
   125  	ProfileOnly *bool                  `json:"profile_only,omitempty"`
   126  }
   127  
   128  // ToClusterUpdateMap assembles a request body based on the contents of
   129  // UpdateOpts.
   130  func (opts UpdateOpts) ToClusterUpdateMap() (map[string]interface{}, error) {
   131  	b, err := gophercloud.BuildRequestBody(opts, "cluster")
   132  	if err != nil {
   133  		return nil, err
   134  	}
   135  	return b, nil
   136  }
   137  
   138  // Update will update an existing cluster.
   139  func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
   140  	b, err := opts.ToClusterUpdateMap()
   141  	if err != nil {
   142  		r.Err = err
   143  		return r
   144  	}
   145  	resp, err := client.Patch(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   146  		OkCodes: []int{200, 202},
   147  	})
   148  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   149  	return
   150  }
   151  
   152  // Delete deletes the specified cluster ID.
   153  func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
   154  	resp, err := client.Delete(deleteURL(client, id), nil)
   155  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   156  	return
   157  }
   158  
   159  // ResizeOptsBuilder allows extensions to add additional parameters to the
   160  // resize request.
   161  type ResizeOptsBuilder interface {
   162  	ToClusterResizeMap() (map[string]interface{}, error)
   163  }
   164  
   165  // ResizeOpts represents options for resizing a cluster.
   166  type ResizeOpts struct {
   167  	AdjustmentType AdjustmentType `json:"adjustment_type,omitempty"`
   168  	Number         interface{}    `json:"number,omitempty"`
   169  	MinSize        *int           `json:"min_size,omitempty"`
   170  	MaxSize        *int           `json:"max_size,omitempty"`
   171  	MinStep        *int           `json:"min_step,omitempty"`
   172  	Strict         *bool          `json:"strict,omitempty"`
   173  }
   174  
   175  // ToClusterResizeMap constructs a request body from ResizeOpts.
   176  func (opts ResizeOpts) ToClusterResizeMap() (map[string]interface{}, error) {
   177  	if opts.AdjustmentType != "" && opts.Number == nil {
   178  		return nil, fmt.Errorf("Number field MUST NOT be empty when AdjustmentType field used")
   179  	}
   180  
   181  	switch opts.Number.(type) {
   182  	case nil, int, int32, int64:
   183  		// Valid type. Always allow
   184  	case float32, float64:
   185  		if opts.AdjustmentType != ChangeInPercentageAdjustment {
   186  			return nil, fmt.Errorf("Only ChangeInPercentageAdjustment allows float value for Number field")
   187  		}
   188  	default:
   189  		return nil, fmt.Errorf("Number field must be either int, float, or omitted")
   190  	}
   191  
   192  	return gophercloud.BuildRequestBody(opts, "resize")
   193  }
   194  
   195  func Resize(client *gophercloud.ServiceClient, id string, opts ResizeOptsBuilder) (r ActionResult) {
   196  	b, err := opts.ToClusterResizeMap()
   197  	if err != nil {
   198  		r.Err = err
   199  		return
   200  	}
   201  	resp, err := client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   202  		OkCodes: []int{200, 201, 202},
   203  	})
   204  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   205  	return
   206  }
   207  
   208  // ScaleInOptsBuilder allows extensions to add additional parameters to the
   209  // ScaleIn request.
   210  type ScaleInOptsBuilder interface {
   211  	ToClusterScaleInMap() (map[string]interface{}, error)
   212  }
   213  
   214  // ScaleInOpts represents options used to scale-in a cluster.
   215  type ScaleInOpts struct {
   216  	Count *int `json:"count,omitempty"`
   217  }
   218  
   219  // ToClusterScaleInMap constructs a request body from ScaleInOpts.
   220  func (opts ScaleInOpts) ToClusterScaleInMap() (map[string]interface{}, error) {
   221  	return gophercloud.BuildRequestBody(opts, "scale_in")
   222  }
   223  
   224  // ScaleIn will reduce the capacity of a cluster.
   225  func ScaleIn(client *gophercloud.ServiceClient, id string, opts ScaleInOptsBuilder) (r ActionResult) {
   226  	b, err := opts.ToClusterScaleInMap()
   227  	if err != nil {
   228  		r.Err = err
   229  		return
   230  	}
   231  	resp, err := client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   232  		OkCodes: []int{200, 201, 202},
   233  	})
   234  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   235  	return
   236  }
   237  
   238  // ScaleOutOptsBuilder allows extensions to add additional parameters to the
   239  // ScaleOut request.
   240  type ScaleOutOptsBuilder interface {
   241  	ToClusterScaleOutMap() (map[string]interface{}, error)
   242  }
   243  
   244  // ScaleOutOpts represents options used to scale-out a cluster.
   245  type ScaleOutOpts struct {
   246  	Count int `json:"count,omitempty"`
   247  }
   248  
   249  // ToClusterScaleOutMap constructs a request body from ScaleOutOpts.
   250  func (opts ScaleOutOpts) ToClusterScaleOutMap() (map[string]interface{}, error) {
   251  	return gophercloud.BuildRequestBody(opts, "scale_out")
   252  }
   253  
   254  // ScaleOut will increase the capacity of a cluster.
   255  func ScaleOut(client *gophercloud.ServiceClient, id string, opts ScaleOutOptsBuilder) (r ActionResult) {
   256  	b, err := opts.ToClusterScaleOutMap()
   257  	if err != nil {
   258  		r.Err = err
   259  		return
   260  	}
   261  	resp, err := client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   262  		OkCodes: []int{200, 201, 202},
   263  	})
   264  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   265  	return
   266  }
   267  
   268  // AttachPolicyOptsBuilder allows extensions to add additional parameters to the
   269  // AttachPolicy request.
   270  type AttachPolicyOptsBuilder interface {
   271  	ToClusterAttachPolicyMap() (map[string]interface{}, error)
   272  }
   273  
   274  // PolicyOpts params
   275  type AttachPolicyOpts struct {
   276  	PolicyID string `json:"policy_id" required:"true"`
   277  	Enabled  *bool  `json:"enabled,omitempty"`
   278  }
   279  
   280  // ToClusterAttachPolicyMap constructs a request body from AttachPolicyOpts.
   281  func (opts AttachPolicyOpts) ToClusterAttachPolicyMap() (map[string]interface{}, error) {
   282  	return gophercloud.BuildRequestBody(opts, "policy_attach")
   283  }
   284  
   285  // Attach Policy will attach a policy to a cluster.
   286  func AttachPolicy(client *gophercloud.ServiceClient, id string, opts AttachPolicyOptsBuilder) (r ActionResult) {
   287  	b, err := opts.ToClusterAttachPolicyMap()
   288  	if err != nil {
   289  		r.Err = err
   290  		return
   291  	}
   292  	resp, err := client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   293  		OkCodes: []int{200, 201, 202},
   294  	})
   295  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   296  	return
   297  }
   298  
   299  // UpdatePolicyOptsBuilder allows extensions to add additional parameters to the
   300  // UpdatePolicy request.
   301  type UpdatePolicyOptsBuilder interface {
   302  	ToClusterUpdatePolicyMap() (map[string]interface{}, error)
   303  }
   304  
   305  // UpdatePolicyOpts represents options used to update a cluster policy.
   306  type UpdatePolicyOpts struct {
   307  	PolicyID string `json:"policy_id" required:"true"`
   308  	Enabled  *bool  `json:"enabled,omitempty" required:"true"`
   309  }
   310  
   311  // ToClusterUpdatePolicyMap constructs a request body from UpdatePolicyOpts.
   312  func (opts UpdatePolicyOpts) ToClusterUpdatePolicyMap() (map[string]interface{}, error) {
   313  	return gophercloud.BuildRequestBody(opts, "policy_update")
   314  }
   315  
   316  // UpdatePolicy will update a cluster's policy.
   317  func UpdatePolicy(client *gophercloud.ServiceClient, id string, opts UpdatePolicyOptsBuilder) (r ActionResult) {
   318  	b, err := opts.ToClusterUpdatePolicyMap()
   319  	if err != nil {
   320  		r.Err = err
   321  		return
   322  	}
   323  	resp, err := client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   324  		OkCodes: []int{200, 201, 202},
   325  	})
   326  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   327  	return
   328  }
   329  
   330  // DetachPolicyOptsBuilder allows extensions to add additional parameters to the
   331  // DetachPolicy request.
   332  type DetachPolicyOptsBuilder interface {
   333  	ToClusterDetachPolicyMap() (map[string]interface{}, error)
   334  }
   335  
   336  // DetachPolicyOpts represents options used to detach a policy from a cluster.
   337  type DetachPolicyOpts struct {
   338  	PolicyID string `json:"policy_id" required:"true"`
   339  }
   340  
   341  // ToClusterDetachPolicyMap constructs a request body from DetachPolicyOpts.
   342  func (opts DetachPolicyOpts) ToClusterDetachPolicyMap() (map[string]interface{}, error) {
   343  	return gophercloud.BuildRequestBody(opts, "policy_detach")
   344  }
   345  
   346  // DetachPolicy will detach a policy from a cluster.
   347  func DetachPolicy(client *gophercloud.ServiceClient, id string, opts DetachPolicyOptsBuilder) (r ActionResult) {
   348  	b, err := opts.ToClusterDetachPolicyMap()
   349  	if err != nil {
   350  		r.Err = err
   351  		return
   352  	}
   353  	resp, err := client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   354  		OkCodes: []int{200, 201, 202},
   355  	})
   356  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   357  	return
   358  }
   359  
   360  // ListPolicyOptsBuilder allows extensions to add additional parameters to the
   361  // ListPolicies request.
   362  type ListPoliciesOptsBuilder interface {
   363  	ToClusterPoliciesListQuery() (string, error)
   364  }
   365  
   366  // ListPoliciesOpts represents options to list a cluster's policies.
   367  type ListPoliciesOpts struct {
   368  	Enabled *bool  `q:"enabled"`
   369  	Name    string `q:"policy_name"`
   370  	Type    string `q:"policy_type"`
   371  	Sort    string `q:"sort"`
   372  }
   373  
   374  // ToClusterPoliciesListQuery formats a ListOpts into a query string.
   375  func (opts ListPoliciesOpts) ToClusterPoliciesListQuery() (string, error) {
   376  	q, err := gophercloud.BuildQueryString(opts)
   377  	return q.String(), err
   378  }
   379  
   380  // ListPolicies instructs OpenStack to provide a list of policies for a cluster.
   381  func ListPolicies(client *gophercloud.ServiceClient, clusterID string, opts ListPoliciesOptsBuilder) pagination.Pager {
   382  	url := listPoliciesURL(client, clusterID)
   383  	if opts != nil {
   384  		query, err := opts.ToClusterPoliciesListQuery()
   385  		if err != nil {
   386  			return pagination.Pager{Err: err}
   387  		}
   388  		url += query
   389  	}
   390  
   391  	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
   392  		return ClusterPolicyPage{pagination.SinglePageBase(r)}
   393  	})
   394  }
   395  
   396  // GetPolicy retrieves details of a cluster policy.
   397  func GetPolicy(client *gophercloud.ServiceClient, clusterID string, policyID string) (r GetPolicyResult) {
   398  	resp, err := client.Get(getPolicyURL(client, clusterID, policyID), &r.Body, nil)
   399  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   400  	return
   401  }
   402  
   403  // RecoverOptsBuilder allows extensions to add additional parameters to the
   404  // Recover request.
   405  type RecoverOptsBuilder interface {
   406  	ToClusterRecoverMap() (map[string]interface{}, error)
   407  }
   408  
   409  // RecoverOpts represents options used to recover a cluster.
   410  type RecoverOpts struct {
   411  	Operation     RecoveryAction `json:"operation,omitempty"`
   412  	Check         *bool          `json:"check,omitempty"`
   413  	CheckCapacity *bool          `json:"check_capacity,omitempty"`
   414  }
   415  
   416  // ToClusterRecovermap constructs a request body from RecoverOpts.
   417  func (opts RecoverOpts) ToClusterRecoverMap() (map[string]interface{}, error) {
   418  	return gophercloud.BuildRequestBody(opts, "recover")
   419  }
   420  
   421  // Recover implements cluster recover request.
   422  func Recover(client *gophercloud.ServiceClient, id string, opts RecoverOptsBuilder) (r ActionResult) {
   423  	b, err := opts.ToClusterRecoverMap()
   424  	if err != nil {
   425  		r.Err = err
   426  		return
   427  	}
   428  	resp, err := client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   429  		OkCodes: []int{200, 201, 202},
   430  	})
   431  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   432  	return
   433  }
   434  
   435  // Check will perform a health check on a cluster.
   436  func Check(client *gophercloud.ServiceClient, id string) (r ActionResult) {
   437  	b := map[string]interface{}{
   438  		"check": map[string]interface{}{},
   439  	}
   440  
   441  	resp, err := client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   442  		OkCodes: []int{200, 201, 202},
   443  	})
   444  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   445  	return
   446  }
   447  
   448  // ToClusterCompleteLifecycleMap constructs a request body from CompleteLifecycleOpts.
   449  func (opts CompleteLifecycleOpts) ToClusterCompleteLifecycleMap() (map[string]interface{}, error) {
   450  	return gophercloud.BuildRequestBody(opts, "complete_lifecycle")
   451  }
   452  
   453  type CompleteLifecycleOpts struct {
   454  	LifecycleActionTokenID string `json:"lifecycle_action_token" required:"true"`
   455  }
   456  
   457  func CompleteLifecycle(client *gophercloud.ServiceClient, id string, opts CompleteLifecycleOpts) (r ActionResult) {
   458  	b, err := opts.ToClusterCompleteLifecycleMap()
   459  	if err != nil {
   460  		r.Err = err
   461  		return
   462  	}
   463  
   464  	resp, err := client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   465  		OkCodes: []int{202},
   466  	})
   467  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   468  	return
   469  }
   470  
   471  func (opts AddNodesOpts) ToClusterAddNodeMap() (map[string]interface{}, error) {
   472  	return gophercloud.BuildRequestBody(opts, "add_nodes")
   473  }
   474  
   475  type AddNodesOpts struct {
   476  	Nodes []string `json:"nodes" required:"true"`
   477  }
   478  
   479  func AddNodes(client *gophercloud.ServiceClient, id string, opts AddNodesOpts) (r ActionResult) {
   480  	b, err := opts.ToClusterAddNodeMap()
   481  	if err != nil {
   482  		r.Err = err
   483  		return
   484  	}
   485  	resp, err := client.Post(nodeURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   486  		OkCodes: []int{202},
   487  	})
   488  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   489  	return
   490  }
   491  
   492  func (opts RemoveNodesOpts) ToClusterRemoveNodeMap() (map[string]interface{}, error) {
   493  	return gophercloud.BuildRequestBody(opts, "del_nodes")
   494  }
   495  
   496  type RemoveNodesOpts struct {
   497  	Nodes []string `json:"nodes" required:"true"`
   498  }
   499  
   500  func RemoveNodes(client *gophercloud.ServiceClient, clusterID string, opts RemoveNodesOpts) (r ActionResult) {
   501  	b, err := opts.ToClusterRemoveNodeMap()
   502  	if err != nil {
   503  		r.Err = err
   504  		return
   505  	}
   506  	resp, err := client.Post(nodeURL(client, clusterID), b, &r.Body, &gophercloud.RequestOpts{
   507  		OkCodes: []int{202},
   508  	})
   509  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   510  	return
   511  }
   512  
   513  func (opts ReplaceNodesOpts) ToClusterReplaceNodeMap() (map[string]interface{}, error) {
   514  	return gophercloud.BuildRequestBody(opts, "replace_nodes")
   515  }
   516  
   517  type ReplaceNodesOpts struct {
   518  	Nodes map[string]string `json:"nodes" required:"true"`
   519  }
   520  
   521  func ReplaceNodes(client *gophercloud.ServiceClient, id string, opts ReplaceNodesOpts) (r ActionResult) {
   522  	b, err := opts.ToClusterReplaceNodeMap()
   523  	if err != nil {
   524  		r.Err = err
   525  		return
   526  	}
   527  	resp, err := client.Post(nodeURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   528  		OkCodes: []int{202},
   529  	})
   530  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   531  	return
   532  }
   533  
   534  type CollectOptsBuilder interface {
   535  	ToClusterCollectMap() (string, error)
   536  }
   537  
   538  // CollectOpts represents options to collect attribute values across a cluster
   539  type CollectOpts struct {
   540  	Path string `q:"path" required:"true"`
   541  }
   542  
   543  func (opts CollectOpts) ToClusterCollectMap() (string, error) {
   544  	return opts.Path, nil
   545  }
   546  
   547  // Collect instructs OpenStack to aggregate attribute values across a cluster
   548  func Collect(client *gophercloud.ServiceClient, id string, opts CollectOptsBuilder) (r CollectResult) {
   549  	query, err := opts.ToClusterCollectMap()
   550  	if err != nil {
   551  		r.Err = err
   552  		return
   553  	}
   554  	resp, err := client.Get(collectURL(client, id, query), &r.Body, &gophercloud.RequestOpts{
   555  		OkCodes: []int{200},
   556  	})
   557  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   558  	return
   559  }
   560  
   561  // OperationName represents valid values for cluster operation
   562  type OperationName string
   563  
   564  const (
   565  	// Nova Profile Op Names
   566  	RebootOperation         OperationName = "reboot"
   567  	RebuildOperation        OperationName = "rebuild"
   568  	ChangePasswordOperation OperationName = "change_password"
   569  	PauseOperation          OperationName = "pause"
   570  	UnpauseOperation        OperationName = "unpause"
   571  	SuspendOperation        OperationName = "suspend"
   572  	ResumeOperation         OperationName = "resume"
   573  	LockOperation           OperationName = "lock"
   574  	UnlockOperation         OperationName = "unlock"
   575  	StartOperation          OperationName = "start"
   576  	StopOperation           OperationName = "stop"
   577  	RescueOperation         OperationName = "rescue"
   578  	UnrescueOperation       OperationName = "unrescue"
   579  	EvacuateOperation       OperationName = "evacuate"
   580  
   581  	// Heat Pofile Op Names
   582  	AbandonOperation OperationName = "abandon"
   583  )
   584  
   585  // ToClusterOperationMap constructs a request body from OperationOpts.
   586  func (opts OperationOpts) ToClusterOperationMap() (map[string]interface{}, error) {
   587  	operationArg := struct {
   588  		Filters OperationFilters `json:"filters,omitempty"`
   589  		Params  OperationParams  `json:"params,omitempty"`
   590  	}{
   591  		Filters: opts.Filters,
   592  		Params:  opts.Params,
   593  	}
   594  
   595  	return gophercloud.BuildRequestBody(operationArg, string(opts.Operation))
   596  }
   597  
   598  // OperationOptsBuilder allows extensions to add additional parameters to the
   599  // Op request.
   600  type OperationOptsBuilder interface {
   601  	ToClusterOperationMap() (map[string]interface{}, error)
   602  }
   603  type OperationFilters map[string]interface{}
   604  type OperationParams map[string]interface{}
   605  
   606  // OperationOpts represents options used to perform an operation on a cluster
   607  type OperationOpts struct {
   608  	Operation OperationName    `json:"operation" required:"true"`
   609  	Filters   OperationFilters `json:"filters,omitempty"`
   610  	Params    OperationParams  `json:"params,omitempty"`
   611  }
   612  
   613  func Ops(client *gophercloud.ServiceClient, id string, opts OperationOptsBuilder) (r ActionResult) {
   614  	b, err := opts.ToClusterOperationMap()
   615  	if err != nil {
   616  		r.Err = err
   617  		return
   618  	}
   619  	resp, err := client.Post(opsURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   620  		OkCodes: []int{202},
   621  	})
   622  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   623  	return
   624  }