Skip to content

Commit

Permalink
Merge pull request #61 from dikhan/feature/object-type-support
Browse files Browse the repository at this point in the history
Feature/object type support
  • Loading branch information
dikhan authored Sep 26, 2018
2 parents 4169a9e + 101be69 commit 0023591
Show file tree
Hide file tree
Showing 18 changed files with 1,022 additions and 282 deletions.
73 changes: 73 additions & 0 deletions docs/how_to.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,34 @@ definitions:
- deleted
````
Alternatively, the status field can also be of 'object' type in which case the nested properties can be defined in place or
the $ref attribute can be used to link to the corresponding status schema definition. The nested properties are considered
computed automatically even if they are not marked as readOnly.
````
definitions:
LBV1:
type: "object"
...
properties:
newStatus:
$ref: "#/definitions/Status"
x-terraform-field-status: true # identifies the field that should be used as status for async operations. This is handy when the field name is not status but some other name the service provider might have chosen and enables the provider to identify the field as the status field that will be used to track progress for the async operations
readOnly: true
timeToProcess: # time that the resource will take to be processed in seconds
type: integer
default: 60 # it will take two minute to process the resource operation (POST/PUT/READ/DELETE)
simulate_failure: # allows user to set it to true and force an error on the API when the given operation (POST/PUT/READ/DELETE) is being performed
type: boolean
Status:
type: object
properties:
message:
type: string
status:
type: string
````
*Note: This extension is only supported at the operation's response level.*
Expand Down Expand Up @@ -590,6 +618,51 @@ string | Type: schema.TypeString | string value
integer | schema.TypeInt | int value
number | schema.TypeFloat | float value
boolean | schema.TypeBool | boolean value
object | schema.TypeMap | map value

Object types can be defined in two fashions:

###### Nested properties

Properties can have their schema definition in place or nested; and they must be of type 'object'.

````
definitions:
ContentDeliveryNetworkV1:
type: "object"
...
properties:
...
object_nested_scheme_property:
type: object # nested properties required type equal object to be considered as object
properties:
name:
type: string
````

###### Ref schema definition

A property that has a $ref attribute is considered automatically and object so defining the type is optional (although
it's recommended).

````
definitions:
ContentDeliveryNetworkV1:
type: "object"
...
properties:
...
object_property:
#type: object - type is optional for properties of object type that use $ref
$ref: "#/definitions/ObjectProperty"
ObjectProperty:
type: object
required:
- message
properties:
message:
type: string
````

Additionally, properties can be flagged as required as follows:

Expand Down
24 changes: 17 additions & 7 deletions examples/swaggercodegen/api/api/cdn.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@ import (
"log"
)

var db = map[string]*ContentDeliveryNetwork{}
var db = map[string]*ContentDeliveryNetworkV1{}

func ContentDeliveryNetworkCreateV1(w http.ResponseWriter, r *http.Request) {
if AuthenticateRequest(r, w) != nil {
return
}
xRequestID := r.Header.Get("X-Request-ID")
log.Printf("Header [X-Request-ID]: %s", xRequestID)
cdn := &ContentDeliveryNetwork{}
cdn := &ContentDeliveryNetworkV1{}
err := readRequest(r, cdn)
if err != nil {
sendErrorResponse(http.StatusBadRequest, err.Error(), w)
return
}
cdn.Id = uuid.New()
cdn.ObjectNestedSchemeProperty = &ContentDeliveryNetworkV1ObjectNestedSchemeProperty{
Name: "autogenerated name",
}
db[cdn.Id] = cdn
sendResponse(http.StatusCreated, w, cdn)
}
Expand All @@ -49,15 +52,22 @@ func ContentDeliveryNetworkUpdateV1(w http.ResponseWriter, r *http.Request) {
sendErrorResponse(http.StatusNotFound, err.Error(), w)
return
}
newCDN := &ContentDeliveryNetwork{}
newCDN := &ContentDeliveryNetworkV1{}
err = readRequest(r, newCDN)
if err != nil {
sendErrorResponse(http.StatusBadRequest, err.Error(), w)
return
}
newCDN.Id = cdn.Id
db[cdn.Id] = newCDN
sendResponse(http.StatusOK, w, newCDN)

cdn.Ips = newCDN.Ips
cdn.Hostnames = newCDN.Hostnames
cdn.ExampleInt = newCDN.ExampleInt
cdn.ExampleNumber = newCDN.ExampleNumber
cdn.ExampleBoolean = newCDN.ExampleBoolean
cdn.ObjectProperty = newCDN.ObjectProperty

db[cdn.Id] = cdn
sendResponse(http.StatusOK, w, cdn)
}

func ContentDeliveryNetworkDeleteV1(w http.ResponseWriter, r *http.Request) {
Expand All @@ -73,7 +83,7 @@ func ContentDeliveryNetworkDeleteV1(w http.ResponseWriter, r *http.Request) {
sendResponse(http.StatusNoContent, w, nil)
}

func retrieveCdn(r *http.Request) (*ContentDeliveryNetwork, error) {
func retrieveCdn(r *http.Request) (*ContentDeliveryNetworkV1, error) {
id := strings.TrimPrefix(r.URL.Path, "/v1/cdns/")
if id == "" {
return nil, fmt.Errorf("cdn id path param not provided")
Expand Down
8 changes: 6 additions & 2 deletions examples/swaggercodegen/api/api/content_delivery_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

package api

type ContentDeliveryNetwork struct {
type ContentDeliveryNetworkV1 struct {

Id string `json:"id,omitempty"`

Expand All @@ -25,4 +25,8 @@ type ContentDeliveryNetwork struct {
ExampleNumber float32 `json:"exampleNumber,omitempty"`

ExampleBoolean bool `json:"example_boolean,omitempty"`
}

ObjectProperty *ObjectProperty `json:"object_property"`

ObjectNestedSchemeProperty *ContentDeliveryNetworkV1ObjectNestedSchemeProperty `json:"object_nested_scheme_property,omitempty"`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Dummy Service Provider generated using 'swaggercodegen' that has two resources 'cdns' and 'lbs' which are terraform compliant
*
* This service provider allows the creation of fake 'cdns' and 'lbs' resources
*
* API version: 1.0.0
* Contact: [email protected]
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/

package api

type ContentDeliveryNetworkV1ObjectNestedSchemeProperty struct {

Name string `json:"name"`
}
10 changes: 6 additions & 4 deletions examples/swaggercodegen/api/api/lb_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ func LBGetV1(w http.ResponseWriter, r *http.Request) {
}

func LBCreateV1(w http.ResponseWriter, r *http.Request) {
lb := &Lbv1{}
lb := &Lbv1{
NewStatus: &Status{},
}
err := readRequest(r, lb)
if err != nil {
sendErrorResponse(http.StatusBadRequest, err.Error(), w)
Expand Down Expand Up @@ -146,9 +148,9 @@ func sleepAndDestroyLB(lb *Lbv1, waitTime int32) {
}

func updateLBStatus(lb *Lbv1, newStatus status) {
oldStatus := lb.Status
lb.Status = string(newStatus)
log.Printf("LB [%s] status updated '%s' => '%s'", lb.Id, oldStatus, newStatus)
oldStatus := lb.NewStatus.Status
lb.NewStatus.Status = string(newStatus)
log.Printf("LB [%s] status updated '%s' => '%s'", lb.Id, oldStatus, lb.NewStatus.Status)
}

func retrieveLB(r *http.Request) (*Lbv1, error) {
Expand Down
2 changes: 2 additions & 0 deletions examples/swaggercodegen/api/api/lbv1.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ type Lbv1 struct {

// lb resource status
Status string `json:"status,omitempty"`

NewStatus *Status `json:"newStatus,omitempty"`
}
16 changes: 16 additions & 0 deletions examples/swaggercodegen/api/api/object_property.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Dummy Service Provider generated using 'swaggercodegen' that has two resources 'cdns' and 'lbs' which are terraform compliant
*
* This service provider allows the creation of fake 'cdns' and 'lbs' resources
*
* API version: 1.0.0
* Contact: [email protected]
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/

package api

type ObjectProperty struct {

Message string `json:"message,omitempty"`
}
18 changes: 18 additions & 0 deletions examples/swaggercodegen/api/api/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Dummy Service Provider generated using 'swaggercodegen' that has two resources 'cdns' and 'lbs' which are terraform compliant
*
* This service provider allows the creation of fake 'cdns' and 'lbs' resources
*
* API version: 1.0.0
* Contact: [email protected]
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/

package api

type Status struct {

Message string `json:"message,omitempty"`

Status string `json:"status,omitempty"`
}
32 changes: 29 additions & 3 deletions examples/swaggercodegen/api/resources/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ definitions:
- label
- ips
- hostnames
- object_property
properties:
id:
type: "string"
Expand All @@ -291,6 +292,22 @@ definitions:
x-terraform-field-name: betterExampleNumberFieldName # overriding exampleNumber with a different name 'betterExampleNumberFieldName'; the preferred name is not terraform compliant either so the provider will perform the name conversion automatically when translating the name into the provider resource configuration and when saving the field into the state file
example_boolean:
type: boolean
object_property:
#type: object - type is optional for properties of object type that use $ref
$ref: "#/definitions/ObjectProperty"
object_nested_scheme_property:
type: object # nested properties required type equal object to be considered as object
readOnly: true
properties:
name:
type: string
ObjectProperty:
type: object
required:
- message
properties:
message:
type: string
LBV1:
type: "object"
required:
Expand All @@ -307,8 +324,7 @@ definitions:
type: "array"
items:
type: "string"
status:
x-terraform-field-status: true # identifies the field that should be used as status for async operations. This is handy when the field name is not status but some other name the service provider might have chosen and enables the provider to identify the field as the status field that will be used to track progress for the async operations
status: # no longer used, using the object status instead for the sake of testing
description: lb resource status
type: string
readOnly: true
Expand All @@ -321,12 +337,22 @@ definitions:
- delete_in_progress
- delete_failed
- deleted
newStatus:
$ref: "#/definitions/Status"
x-terraform-field-status: true # identifies the field that should be used as status for async operations. This is handy when the field name is not status but some other name the service provider might have chosen and enables the provider to identify the field as the status field that will be used to track progress for the async operations
readOnly: true
timeToProcess: # time that the resource will take to be processed in seconds
type: integer
default: 60 # it will take two minute to process the resource operation (POST/PUT/READ/DELETE)
simulate_failure: # allows user to set it to true and force an error on the API when the given operation (POST/PUT/READ/DELETE) is being performed
type: boolean

Status:
type: object
properties:
message:
type: string
status:
type: string
# Schema for error response body
Error:
type: object
Expand Down
5 changes: 5 additions & 0 deletions examples/swaggercodegen/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ resource "swaggercodegen_cdn_v1" "my_cdn" {
example_int = 12
better_example_number_field_name = 1.12
example_boolean = true

object_property = {
message = "some message news"
}

}

resource "swaggercodegen_lbs_v1" "my_lb" {
Expand Down
Loading

0 comments on commit 0023591

Please sign in to comment.