github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/openstack/rts/v1/stacks/requests.go (about)

     1  package stacks
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  
     7  	"github.com/opentelekomcloud/gophertelekomcloud"
     8  	"github.com/opentelekomcloud/gophertelekomcloud/pagination"
     9  )
    10  
    11  // CreateOptsBuilder is the interface options structs have to satisfy in order
    12  // to be used in the main Create operation in this package. Since many
    13  // extensions decorate or modify the common logic, it is useful for them to
    14  // satisfy a basic interface in order for them to be used.
    15  type CreateOptsBuilder interface {
    16  	ToStackCreateMap() (map[string]interface{}, error)
    17  }
    18  
    19  // CreateOpts is the common options struct used in this package's Create
    20  // operation.
    21  type CreateOpts struct {
    22  	// The name of the stack. It must start with an alphabetic character.
    23  	Name string `json:"stack_name" required:"true"`
    24  	// A structure that contains either the template file or url. Call the
    25  	// associated methods to extract the information relevant to send in a create request.
    26  	TemplateOpts *Template `json:"-" required:"true"`
    27  	// Enables or disables deletion of all stack resources when a stack
    28  	// creation fails. Default is true, meaning all resources are not deleted when
    29  	// stack creation fails.
    30  	DisableRollback *bool `json:"disable_rollback,omitempty"`
    31  	// A structure that contains details for the environment of the stack.
    32  	EnvironmentOpts *Environment `json:"-"`
    33  	// User-defined parameters to pass to the template.
    34  	Parameters map[string]string `json:"parameters,omitempty"`
    35  	// The timeout for stack creation in minutes.
    36  	Timeout int `json:"timeout_mins,omitempty"`
    37  	// A list of tags to assosciate with the Stack
    38  	Tags []string `json:"-"`
    39  }
    40  
    41  // ToStackCreateMap casts a CreateOpts struct to a map.
    42  func (opts CreateOpts) ToStackCreateMap() (map[string]interface{}, error) {
    43  	b, err := golangsdk.BuildRequestBody(opts, "")
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  
    48  	if err := opts.TemplateOpts.Parse(); err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil {
    53  		return nil, err
    54  	}
    55  	opts.TemplateOpts.fixFileRefs()
    56  	b["template"] = string(opts.TemplateOpts.Bin)
    57  
    58  	files := make(map[string]string)
    59  	for k, v := range opts.TemplateOpts.Files {
    60  		files[k] = v
    61  	}
    62  
    63  	if opts.EnvironmentOpts != nil {
    64  		if err := opts.EnvironmentOpts.Parse(); err != nil {
    65  			return nil, err
    66  		}
    67  		if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil {
    68  			return nil, err
    69  		}
    70  		opts.EnvironmentOpts.fixFileRefs()
    71  		for k, v := range opts.EnvironmentOpts.Files {
    72  			files[k] = v
    73  		}
    74  		b["environment"] = string(opts.EnvironmentOpts.Bin)
    75  	}
    76  
    77  	if len(files) > 0 {
    78  		b["files"] = files
    79  	}
    80  
    81  	if opts.Tags != nil {
    82  		b["tags"] = strings.Join(opts.Tags, ",")
    83  	}
    84  
    85  	return b, nil
    86  }
    87  
    88  // Create accepts a CreateOpts struct and creates a new stack using the values
    89  // provided.
    90  func Create(c *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
    91  	b, err := opts.ToStackCreateMap()
    92  	if err != nil {
    93  		r.Err = err
    94  		return
    95  	}
    96  	_, r.Err = c.Post(createURL(c), b, &r.Body, nil)
    97  	return
    98  }
    99  
   100  // SortDir is a type for specifying in which direction to sort a list of stacks.
   101  type SortDir string
   102  
   103  // SortKey is a type for specifying by which key to sort a list of stacks.
   104  type SortKey string
   105  
   106  var (
   107  	// SortAsc is used to sort a list of stacks in ascending order.
   108  	SortAsc SortDir = "asc"
   109  	// SortDesc is used to sort a list of stacks in descending order.
   110  	SortDesc SortDir = "desc"
   111  	// SortName is used to sort a list of stacks by name.
   112  	SortName SortKey = "name"
   113  	// SortStatus is used to sort a list of stacks by status.
   114  	SortStatus SortKey = "status"
   115  	// SortCreatedAt is used to sort a list of stacks by date created.
   116  	SortCreatedAt SortKey = "created_at"
   117  	// SortUpdatedAt is used to sort a list of stacks by date updated.
   118  	SortUpdatedAt SortKey = "updated_at"
   119  )
   120  
   121  // ListOptsBuilder allows extensions to add additional parameters to the
   122  // List request.
   123  type ListOptsBuilder interface {
   124  	ToStackListQuery() (string, error)
   125  }
   126  
   127  // ListOpts allows the filtering and sorting of paginated collections through
   128  // the API. Filtering is achieved by passing in struct field values that map to
   129  // the rts attributes you want to see returned. SortKey allows you to sort
   130  // by a particular network attribute. SortDir sets the direction, and is either
   131  // `asc' or `desc'. Marker and Limit are used for pagination.
   132  type ListOpts struct {
   133  	ID      string  `q:"id"`
   134  	Status  string  `q:"status"`
   135  	Name    string  `q:"name"`
   136  	Marker  string  `q:"marker"`
   137  	Limit   int     `q:"limit"`
   138  	SortKey SortKey `q:"sort_keys"`
   139  	SortDir SortDir `q:"sort_dir"`
   140  }
   141  
   142  // ToStackListQuery formats a ListOpts into a query string.
   143  func (opts ListOpts) ToStackListQuery() (string, error) {
   144  	q, err := golangsdk.BuildQueryString(opts)
   145  	if err != nil {
   146  		return "", err
   147  	}
   148  	return q.String(), nil
   149  }
   150  
   151  func List(c *golangsdk.ServiceClient, opts ListOpts) ([]ListedStack, error) {
   152  	u := listURL(c)
   153  	pages, err := pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page {
   154  		return StackPage{pagination.LinkedPageBase{PageResult: r}}
   155  	}).AllPages()
   156  
   157  	if err != nil {
   158  		return nil, err
   159  	}
   160  
   161  	allStacks, err := ExtractStacks(pages)
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  
   166  	return FilterStacks(allStacks, opts)
   167  }
   168  
   169  func FilterStacks(stacks []ListedStack, opts ListOpts) ([]ListedStack, error) {
   170  
   171  	var refinedStacks []ListedStack
   172  	var matched bool
   173  	m := map[string]interface{}{}
   174  
   175  	if opts.ID != "" {
   176  		m["ID"] = opts.ID
   177  	}
   178  	if opts.Name != "" {
   179  		m["Name"] = opts.Name
   180  	}
   181  	if opts.Status != "" {
   182  		m["Status"] = opts.Status
   183  	}
   184  
   185  	if len(m) > 0 && len(stacks) > 0 {
   186  		for _, stack := range stacks {
   187  			matched = true
   188  
   189  			for key, value := range m {
   190  				if sVal := getStructField(&stack, key); !(sVal == value) {
   191  					matched = false
   192  				}
   193  			}
   194  
   195  			if matched {
   196  				refinedStacks = append(refinedStacks, stack)
   197  			}
   198  		}
   199  
   200  	} else {
   201  		refinedStacks = stacks
   202  	}
   203  
   204  	return refinedStacks, nil
   205  }
   206  
   207  func getStructField(v *ListedStack, field string) string {
   208  	r := reflect.ValueOf(v)
   209  	f := reflect.Indirect(r).FieldByName(field)
   210  	return f.String()
   211  }
   212  
   213  func Get(c *golangsdk.ServiceClient, stackName string) (r GetResult) {
   214  	_, r.Err = c.Get(getURL(c, stackName), &r.Body, nil)
   215  	return
   216  }
   217  
   218  // UpdateOptsBuilder is the interface options structs have to satisfy in order
   219  // to be used in the Update operation in this package.
   220  type UpdateOptsBuilder interface {
   221  	ToStackUpdateMap() (map[string]interface{}, error)
   222  }
   223  
   224  // UpdateOpts contains the common options struct used in this package's Update
   225  // operation.
   226  type UpdateOpts struct {
   227  	// A structure that contains either the template file or url. Call the
   228  	// associated methods to extract the information relevant to send in a create request.
   229  	TemplateOpts *Template `json:"-" required:"true"`
   230  	// A structure that contains details for the environment of the stack.
   231  	EnvironmentOpts *Environment `json:"-"`
   232  	// User-defined parameters to pass to the template.
   233  	Parameters map[string]string `json:"parameters,omitempty"`
   234  	// The timeout for stack creation in minutes.
   235  	Timeout int `json:"timeout_mins,omitempty"`
   236  	// Enables or disables deletion of all stack resources when a stack
   237  	// creation fails. Default is true, meaning all resources are not deleted when
   238  	// stack creation fails.
   239  	DisableRollback *bool `json:"disable_rollback,omitempty"`
   240  	// A list of tags to assosciate with the Stack
   241  	Tags []string `json:"-"`
   242  }
   243  
   244  // ToStackUpdateMap casts a CreateOpts struct to a map.
   245  func (opts UpdateOpts) ToStackUpdateMap() (map[string]interface{}, error) {
   246  	b, err := golangsdk.BuildRequestBody(opts, "")
   247  	if err != nil {
   248  		return nil, err
   249  	}
   250  
   251  	if err := opts.TemplateOpts.Parse(); err != nil {
   252  		return nil, err
   253  	}
   254  
   255  	if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil {
   256  		return nil, err
   257  	}
   258  	opts.TemplateOpts.fixFileRefs()
   259  	b["template"] = string(opts.TemplateOpts.Bin)
   260  
   261  	files := make(map[string]string)
   262  	for k, v := range opts.TemplateOpts.Files {
   263  		files[k] = v
   264  	}
   265  
   266  	if opts.EnvironmentOpts != nil {
   267  		if err := opts.EnvironmentOpts.Parse(); err != nil {
   268  			return nil, err
   269  		}
   270  		if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil {
   271  			return nil, err
   272  		}
   273  		opts.EnvironmentOpts.fixFileRefs()
   274  		for k, v := range opts.EnvironmentOpts.Files {
   275  			files[k] = v
   276  		}
   277  		b["environment"] = string(opts.EnvironmentOpts.Bin)
   278  	}
   279  
   280  	if len(files) > 0 {
   281  		b["files"] = files
   282  	}
   283  
   284  	if opts.Tags != nil {
   285  		b["tags"] = strings.Join(opts.Tags, ",")
   286  	}
   287  
   288  	return b, nil
   289  }
   290  
   291  // Update accepts an UpdateOpts struct and updates an existing stack using the values
   292  // provided.
   293  func Update(c *golangsdk.ServiceClient, stackName, stackID string, opts UpdateOptsBuilder) (r UpdateResult) {
   294  	b, err := opts.ToStackUpdateMap()
   295  	if err != nil {
   296  		r.Err = err
   297  		return
   298  	}
   299  	_, r.Err = c.Put(updateURL(c, stackName, stackID), b, nil, nil)
   300  	return
   301  }
   302  
   303  // Delete deletes a stack based on the stack name and stack ID.
   304  func Delete(c *golangsdk.ServiceClient, stackName, stackID string) (r DeleteResult) {
   305  	_, r.Err = c.Delete(deleteURL(c, stackName, stackID), nil)
   306  	return
   307  }