github.com/gophercloud/gophercloud@v1.11.0/openstack/container/v1/capsules/results.go (about)

     1  package capsules
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/gophercloud/gophercloud"
     9  	"github.com/gophercloud/gophercloud/pagination"
    10  )
    11  
    12  type commonResult struct {
    13  	gophercloud.Result
    14  }
    15  
    16  // ExtractBase is a function that accepts a result and extracts
    17  // a base a capsule resource.
    18  func (r commonResult) ExtractBase() (*Capsule, error) {
    19  	var s *Capsule
    20  	err := r.ExtractInto(&s)
    21  	return s, err
    22  }
    23  
    24  // Extract is a function that accepts a result and extracts a capsule result.
    25  // The result will be returned as an interface{} where it should be able to
    26  // be casted as either a Capsule or CapsuleV132.
    27  func (r commonResult) Extract() (interface{}, error) {
    28  	s, err := r.ExtractBase()
    29  	if err == nil {
    30  		return s, nil
    31  	}
    32  
    33  	if _, ok := err.(*json.UnmarshalTypeError); !ok {
    34  		return s, err
    35  	}
    36  
    37  	return r.ExtractV132()
    38  }
    39  
    40  // GetResult represents the result of a get operation.
    41  type GetResult struct {
    42  	commonResult
    43  }
    44  
    45  // CreateResult is the response from a Create operation. Call its Extract
    46  // method to interpret it as a Capsule.
    47  type CreateResult struct {
    48  	commonResult
    49  }
    50  
    51  // DeleteResult represents the result of a delete operation.
    52  type DeleteResult struct {
    53  	gophercloud.ErrResult
    54  }
    55  
    56  type CapsulePage struct {
    57  	pagination.LinkedPageBase
    58  }
    59  
    60  // Represents a Capsule
    61  type Capsule struct {
    62  	// UUID for the capsule
    63  	UUID string `json:"uuid"`
    64  
    65  	// User ID for the capsule
    66  	UserID string `json:"user_id"`
    67  
    68  	// Project ID for the capsule
    69  	ProjectID string `json:"project_id"`
    70  
    71  	// cpu for the capsule
    72  	CPU float64 `json:"cpu"`
    73  
    74  	// Memory for the capsule
    75  	Memory string `json:"memory"`
    76  
    77  	// The name of the capsule
    78  	MetaName string `json:"meta_name"`
    79  
    80  	// Indicates whether capsule is currently operational.
    81  	Status string `json:"status"`
    82  
    83  	// Indicates whether capsule is currently operational.
    84  	StatusReason string `json:"status_reason"`
    85  
    86  	// The created time of the capsule.
    87  	CreatedAt time.Time `json:"-"`
    88  
    89  	// The updated time of the capsule.
    90  	UpdatedAt time.Time `json:"-"`
    91  
    92  	// Links includes HTTP references to the itself, useful for passing along to
    93  	// other APIs that might want a capsule reference.
    94  	Links []interface{} `json:"links"`
    95  
    96  	// The capsule version
    97  	CapsuleVersion string `json:"capsule_version"`
    98  
    99  	// The capsule restart policy
   100  	RestartPolicy string `json:"restart_policy"`
   101  
   102  	// The capsule metadata labels
   103  	MetaLabels map[string]string `json:"meta_labels"`
   104  
   105  	// The list of containers uuids inside capsule.
   106  	ContainersUUIDs []string `json:"containers_uuids"`
   107  
   108  	// The capsule IP addresses
   109  	Addresses map[string][]Address `json:"addresses"`
   110  
   111  	// The capsule volume attached information
   112  	VolumesInfo map[string][]string `json:"volumes_info"`
   113  
   114  	// The container object inside capsule
   115  	Containers []Container `json:"containers"`
   116  
   117  	// The capsule host
   118  	Host string `json:"host"`
   119  }
   120  
   121  type Container struct {
   122  	// The Container IP addresses
   123  	Addresses map[string][]Address `json:"addresses"`
   124  
   125  	// UUID for the container
   126  	UUID string `json:"uuid"`
   127  
   128  	// User ID for the container
   129  	UserID string `json:"user_id"`
   130  
   131  	// Project ID for the container
   132  	ProjectID string `json:"project_id"`
   133  
   134  	// cpu for the container
   135  	CPU float64 `json:"cpu"`
   136  
   137  	// Memory for the container
   138  	Memory string `json:"memory"`
   139  
   140  	// Image for the container
   141  	Image string `json:"image"`
   142  
   143  	// The container container
   144  	Labels map[string]string `json:"labels"`
   145  
   146  	// The created time of the container
   147  	CreatedAt time.Time `json:"-"`
   148  
   149  	// The updated time of the container
   150  	UpdatedAt time.Time `json:"-"`
   151  
   152  	// The started time of the container
   153  	StartedAt time.Time `json:"-"`
   154  
   155  	// Name for the container
   156  	Name string `json:"name"`
   157  
   158  	// Links includes HTTP references to the itself, useful for passing along to
   159  	// other APIs that might want a capsule reference.
   160  	Links []interface{} `json:"links"`
   161  
   162  	// auto remove flag token for the container
   163  	AutoRemove bool `json:"auto_remove"`
   164  
   165  	// Host for the container
   166  	Host string `json:"host"`
   167  
   168  	// Work directory for the container
   169  	WorkDir string `json:"workdir"`
   170  
   171  	// Disk for the container
   172  	Disk int `json:"disk"`
   173  
   174  	// Image pull policy for the container
   175  	ImagePullPolicy string `json:"image_pull_policy"`
   176  
   177  	// Task state for the container
   178  	TaskState string `json:"task_state"`
   179  
   180  	// Host name for the container
   181  	HostName string `json:"hostname"`
   182  
   183  	// Environment for the container
   184  	Environment map[string]string `json:"environment"`
   185  
   186  	// Status for the container
   187  	Status string `json:"status"`
   188  
   189  	// Auto Heal flag for the container
   190  	AutoHeal bool `json:"auto_heal"`
   191  
   192  	// Status details for the container
   193  	StatusDetail string `json:"status_detail"`
   194  
   195  	// Status reason for the container
   196  	StatusReason string `json:"status_reason"`
   197  
   198  	// Image driver for the container
   199  	ImageDriver string `json:"image_driver"`
   200  
   201  	// Command for the container
   202  	Command []string `json:"command"`
   203  
   204  	// Image for the container
   205  	Runtime string `json:"runtime"`
   206  
   207  	// Interactive flag for the container
   208  	Interactive bool `json:"interactive"`
   209  
   210  	// Restart Policy for the container
   211  	RestartPolicy map[string]string `json:"restart_policy"`
   212  
   213  	// Ports information for the container
   214  	Ports []int `json:"ports"`
   215  
   216  	// Security groups for the container
   217  	SecurityGroups []string `json:"security_groups"`
   218  }
   219  
   220  type Address struct {
   221  	PreserveOnDelete bool    `json:"preserve_on_delete"`
   222  	Addr             string  `json:"addr"`
   223  	Port             string  `json:"port"`
   224  	Version          float64 `json:"version"`
   225  	SubnetID         string  `json:"subnet_id"`
   226  }
   227  
   228  // NextPageURL is invoked when a paginated collection of capsules has reached
   229  // the end of a page and the pager seeks to traverse over a new one. In order
   230  // to do this, it needs to construct the next page's URL.
   231  func (r CapsulePage) NextPageURL() (string, error) {
   232  	var s struct {
   233  		Next string `json:"next"`
   234  	}
   235  	err := r.ExtractInto(&s)
   236  	if err != nil {
   237  		return "", err
   238  	}
   239  	return s.Next, nil
   240  }
   241  
   242  // IsEmpty checks whether a CapsulePage struct is empty.
   243  func (r CapsulePage) IsEmpty() (bool, error) {
   244  	if r.StatusCode == 204 {
   245  		return true, nil
   246  	}
   247  
   248  	is, err := ExtractCapsules(r)
   249  	if err != nil {
   250  		return false, err
   251  	}
   252  
   253  	if v, ok := is.([]Capsule); ok {
   254  		return len(v) == 0, nil
   255  	}
   256  
   257  	if v, ok := is.([]CapsuleV132); ok {
   258  		return len(v) == 0, nil
   259  	}
   260  
   261  	return false, fmt.Errorf("Unable to determine Capsule type")
   262  }
   263  
   264  // ExtractCapsulesBase accepts a Page struct, specifically a CapsulePage struct,
   265  // and extracts the elements into a slice of Capsule structs. In other words,
   266  // a generic collection is mapped into the relevant slice.
   267  func ExtractCapsulesBase(r pagination.Page) ([]Capsule, error) {
   268  	var s struct {
   269  		Capsules []Capsule `json:"capsules"`
   270  	}
   271  
   272  	err := (r.(CapsulePage)).ExtractInto(&s)
   273  	return s.Capsules, err
   274  }
   275  
   276  // ExtractCapsules accepts a Page struct, specifically a CapsulePage struct,
   277  // and extracts the elements into an interface.
   278  // This interface should be able to be casted as either a Capsule or
   279  // CapsuleV132 struct
   280  func ExtractCapsules(r pagination.Page) (interface{}, error) {
   281  	s, err := ExtractCapsulesBase(r)
   282  	if err == nil {
   283  		return s, nil
   284  	}
   285  
   286  	if _, ok := err.(*json.UnmarshalTypeError); !ok {
   287  		return nil, err
   288  	}
   289  
   290  	return ExtractCapsulesV132(r)
   291  }
   292  
   293  func (r *Capsule) UnmarshalJSON(b []byte) error {
   294  	type tmp Capsule
   295  
   296  	// Support for "older" zun time formats.
   297  	var s1 struct {
   298  		tmp
   299  		CreatedAt gophercloud.JSONRFC3339ZNoT `json:"created_at"`
   300  		UpdatedAt gophercloud.JSONRFC3339ZNoT `json:"updated_at"`
   301  	}
   302  
   303  	err := json.Unmarshal(b, &s1)
   304  	if err == nil {
   305  		*r = Capsule(s1.tmp)
   306  
   307  		r.CreatedAt = time.Time(s1.CreatedAt)
   308  		r.UpdatedAt = time.Time(s1.UpdatedAt)
   309  
   310  		return nil
   311  	}
   312  
   313  	// Support for "new" zun time formats.
   314  	var s2 struct {
   315  		tmp
   316  		CreatedAt gophercloud.JSONRFC3339ZNoTNoZ `json:"created_at"`
   317  		UpdatedAt gophercloud.JSONRFC3339ZNoTNoZ `json:"updated_at"`
   318  	}
   319  
   320  	err = json.Unmarshal(b, &s2)
   321  	if err != nil {
   322  		return err
   323  	}
   324  
   325  	*r = Capsule(s2.tmp)
   326  
   327  	r.CreatedAt = time.Time(s2.CreatedAt)
   328  	r.UpdatedAt = time.Time(s2.UpdatedAt)
   329  
   330  	return nil
   331  }
   332  
   333  func (r *Container) UnmarshalJSON(b []byte) error {
   334  	type tmp Container
   335  
   336  	// Support for "older" zun time formats.
   337  	var s1 struct {
   338  		tmp
   339  		CreatedAt gophercloud.JSONRFC3339ZNoT `json:"created_at"`
   340  		UpdatedAt gophercloud.JSONRFC3339ZNoT `json:"updated_at"`
   341  		StartedAt gophercloud.JSONRFC3339ZNoT `json:"started_at"`
   342  	}
   343  
   344  	err := json.Unmarshal(b, &s1)
   345  	if err == nil {
   346  		*r = Container(s1.tmp)
   347  
   348  		r.CreatedAt = time.Time(s1.CreatedAt)
   349  		r.UpdatedAt = time.Time(s1.UpdatedAt)
   350  		r.StartedAt = time.Time(s1.StartedAt)
   351  
   352  		return nil
   353  	}
   354  
   355  	// Support for "new" zun time formats.
   356  	var s2 struct {
   357  		tmp
   358  		CreatedAt gophercloud.JSONRFC3339ZNoTNoZ `json:"created_at"`
   359  		UpdatedAt gophercloud.JSONRFC3339ZNoTNoZ `json:"updated_at"`
   360  		StartedAt gophercloud.JSONRFC3339ZNoTNoZ `json:"started_at"`
   361  	}
   362  
   363  	err = json.Unmarshal(b, &s2)
   364  	if err != nil {
   365  		return err
   366  	}
   367  
   368  	*r = Container(s2.tmp)
   369  
   370  	r.CreatedAt = time.Time(s2.CreatedAt)
   371  	r.UpdatedAt = time.Time(s2.UpdatedAt)
   372  	r.StartedAt = time.Time(s2.StartedAt)
   373  
   374  	return nil
   375  }