Skip to content

Commit

Permalink
Orchestration: Add support for resource_type endpoints (#1806)
Browse files Browse the repository at this point in the history
Add client support for listing available resource types in Heat, getting
their schemata, and downloading example templates for use as provider
templates.

Fixes #1805

Signed-off-by: Zane Bitter <zbitter@redhat.com>
  • Loading branch information
zaneb authored and jtopjian committed Jan 9, 2020
1 parent aea1ee1 commit af6dbf2
Show file tree
Hide file tree
Showing 7 changed files with 782 additions and 0 deletions.
21 changes: 21 additions & 0 deletions openstack/orchestration/v1/resourcetypes/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
Package resourcetypes provides operations for listing available resource types,
obtaining their properties schema, and generating example templates that can be
customised to use as provider templates.
Example of listing available resource types:
listOpts := resourcetypes.ListOpts{
SupportStatus: resourcetypes.SupportStatusSupported,
}
resourceTypes, err := resourcetypes.List(client, listOpts).Extract()
if err != nil {
panic(err)
}
fmt.Println("Get Resource Type List")
for _, rt := range resTypes {
fmt.Println(rt.ResourceType)
}
*/
package resourcetypes
118 changes: 118 additions & 0 deletions openstack/orchestration/v1/resourcetypes/requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package resourcetypes

import (
"github.com/gophercloud/gophercloud"
)

// SupportStatus is a type for specifying by which support status to filter the
// list of resource types.
type SupportStatus string

const (
// SupportStatusUnknown is returned when the resource type does not have a
// support status.
SupportStatusUnknown SupportStatus = "UNKNOWN"
// SupportStatusSupported indicates a resource type that is expected to
// work.
SupportStatusSupported SupportStatus = "SUPPORTED"
// SupportStatusDeprecated indicates a resource type that is in the process
// being removed, and may or may not be replaced by something else.
SupportStatusDeprecated SupportStatus = "DEPRECATED"
// SupportStatusHidden indicates a resource type that has been removed.
// Existing stacks that contain resources of this type can still be
// deleted or updated to remove the resources, but they may not actually
// do anything any more.
SupportStatusHidden SupportStatus = "HIDDEN"
// SupportStatusUnsupported indicates a resource type that is provided for
// preview or other purposes and should not be relied upon.
SupportStatusUnsupported SupportStatus = "UNSUPPORTED"
)

// ListOptsBuilder allows extensions to add additional parameters to the
// List request.
type ListOptsBuilder interface {
ToResourceTypeListQuery() (string, error)
}

// ListOpts allows the filtering of collections through the API.
type ListOpts struct {
// Filters the resource type list by a regex on the name.
NameRegex string `q:"name"`
// Filters the resource list by the specified SupportStatus.
SupportStatus SupportStatus `q:"support_status"`
// Return descriptions as well as names of resource types
WithDescription bool `q:"with_description"`
}

// ToResourceTypeListQuery formats a ListOpts into a query string.
func (opts ListOpts) ToResourceTypeListQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
return q.String(), err
}

// List makes a request against the API to list available resource types.
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) (r ListResult) {
url := listURL(client)

if opts == nil {
opts = ListOpts{}
}
query, err := opts.ToResourceTypeListQuery()
if err != nil {
r.Err = err
return
}
url += query

_, r.Err = client.Get(url, &r.Body, nil)
return
}

// GetSchema retreives the schema for a given resource type.
func GetSchema(client *gophercloud.ServiceClient, resourceType string) (r GetSchemaResult) {
_, r.Err = client.Get(getSchemaURL(client, resourceType), &r.Body, nil)
return
}

// GenerateTemplateOptsBuilder allows extensions to add additional parameters
// to the GenerateTemplate request.
type GenerateTemplateOptsBuilder interface {
ToGenerateTemplateQuery() (string, error)
}

type GeneratedTemplateType string

const (
TemplateTypeHOT GeneratedTemplateType = "hot"
TemplateTypeCFn GeneratedTemplateType = "cfn"
)

// GenerateTemplateOpts allows the filtering of collections through the API.
type GenerateTemplateOpts struct {
TemplateType GeneratedTemplateType `q:"template_type"`
}

// ToGenerateTemplateQuery formats a GenerateTemplateOpts into a query string.
func (opts GenerateTemplateOpts) ToGenerateTemplateQuery() (string, error) {
if opts.TemplateType == "" {
opts.TemplateType = TemplateTypeHOT
}
q, err := gophercloud.BuildQueryString(opts)
return q.String(), err
}

// GenerateTemplate retreives an example template for a given resource type.
func GenerateTemplate(client *gophercloud.ServiceClient, resourceType string, opts GenerateTemplateOptsBuilder) (r TemplateResult) {
url := generateTemplateURL(client, resourceType)
if opts == nil {
opts = GenerateTemplateOpts{}
}
query, err := opts.ToGenerateTemplateQuery()
if err != nil {
r.Err = err
return
}
url += query
_, r.Err = client.Get(url, &r.Body, nil)
return
}
150 changes: 150 additions & 0 deletions openstack/orchestration/v1/resourcetypes/results.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package resourcetypes

import (
"github.com/gophercloud/gophercloud"
)

// ResourceTypeSummary contains the result of listing an available resource
// type.
type ResourceTypeSummary struct {
ResourceType string `json:"resource_type"`
Description string `json:"description"`
}

// PropertyType represents the expected type of a property or attribute value.
type PropertyType string

const (
// StringProperty indicates a string property type.
StringProperty PropertyType = "string"
// IntegerProperty indicates an integer property type.
IntegerProperty PropertyType = "integer"
// NumberProperty indicates a number property type. It may be an integer or
// float.
NumberProperty PropertyType = "number"
// BooleanProperty indicates a boolean property type.
BooleanProperty PropertyType = "boolean"
// MapProperty indicates a map property type.
MapProperty PropertyType = "map"
// ListProperty indicates a list property type.
ListProperty PropertyType = "list"
// UntypedProperty indicates a property that could have any type.
UntypedProperty PropertyType = "any"
)

// AttributeSchema is the schema of a resource attribute
type AttributeSchema struct {
Description string `json:"description,omitempty"`
Type PropertyType `json:"type"`
}

// MinMaxConstraint is a type of constraint with minimum and maximum values.
// This is used for both Range and Length constraints.
type MinMaxConstraint struct {
Min float64 `json:"min,omitempty"`
Max float64 `json:"max,omitempty"`
}

// ModuloConstraint constrains an integer to have a certain value given a
// particular modulus.
type ModuloConstraint struct {
Step int `json:"step,omitempty"`
Offset int `json:"offset,omitempty"`
}

// ConstraintSchema describes all possible types of constraints. Besides the
// description, only one other field is ever set at a time.
type ConstraintSchema struct {
Description string `json:"description,omitempty"`
Range *MinMaxConstraint `json:"range,omitempty"`
Length *MinMaxConstraint `json:"length,omitempty"`
Modulo *ModuloConstraint `json:"modulo,omitempty"`
AllowedValues *[]interface{} `json:"allowed_values,omitempty"`
AllowedPattern *string `json:"allowed_pattern,omitempty"`
CustomConstraint *string `json:"custom_constraint,omitempty"`
}

// PropertySchema is the schema of a resource property.
type PropertySchema struct {
Type PropertyType `json:"type"`
Description string `json:"description,omitempty"`
Default interface{} `json:"default,omitempty"`
Constraints []ConstraintSchema `json:"constraints,omitempty"`
Required bool `json:"required"`
Immutable bool `json:"immutable"`
UpdateAllowed bool `json:"update_allowed"`
Schema map[string]PropertySchema `json:"schema,omitempty"`
}

// SupportStatusDetails contains information about the support status of the
// resource and its history.
type SupportStatusDetails struct {
Status SupportStatus `json:"status"`
Message string `json:"message,omitempty"`
Version string `json:"version,omitempty"`
PreviousStatus *SupportStatusDetails `json:"previous_status,omitempty"`
}

// ResourceSchema is the schema for a resource type, its attributes, and
// properties.
type ResourceSchema struct {
ResourceType string `json:"resource_type"`
SupportStatus SupportStatusDetails `json:"support_status"`
Attributes map[string]AttributeSchema `json:"attributes"`
Properties map[string]PropertySchema `json:"properties"`
}

// ListResult represents the result of a List operation.
type ListResult struct {
gophercloud.Result
}

// Extract returns a slice of ResourceTypeSummary objects and is called after
// a List operation.
func (r ListResult) Extract() (rts []ResourceTypeSummary, err error) {
var full struct {
ResourceTypes []ResourceTypeSummary `json:"resource_types"`
}
err = r.ExtractInto(&full)
if err == nil {
rts = full.ResourceTypes
return
}

var basic struct {
ResourceTypes []string `json:"resource_types"`
}
err2 := r.ExtractInto(&basic)
if err2 == nil {
err = nil
rts = make([]ResourceTypeSummary, len(basic.ResourceTypes))
for i, n := range basic.ResourceTypes {
rts[i] = ResourceTypeSummary{ResourceType: n}
}
}
return
}

// GetSchemaResult represents the result of a GetSchema operation.
type GetSchemaResult struct {
gophercloud.Result
}

// Extract returns a ResourceSchema object and is called after a GetSchema
// operation.
func (r GetSchemaResult) Extract() (rts ResourceSchema, err error) {
err = r.ExtractInto(&rts)
return
}

// TemplateResult represents the result of a Template get operation.
type TemplateResult struct {
gophercloud.Result
}

// Extract returns a Template object and is called after a Template get
// operation.
func (r TemplateResult) Extract() (template map[string]interface{}, err error) {
err = r.ExtractInto(&template)
return
}
3 changes: 3 additions & 0 deletions openstack/orchestration/v1/resourcetypes/testing/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// orchestration_resourcetypes_v1

package testing
Loading

0 comments on commit af6dbf2

Please sign in to comment.