Skip to content

Commit

Permalink
Merge a8719a5 into c3894d6
Browse files Browse the repository at this point in the history
  • Loading branch information
nat-henderson authored Jan 18, 2019
2 parents c3894d6 + a8719a5 commit 151377c
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 498 deletions.
23 changes: 20 additions & 3 deletions products/spanner/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,30 @@ objects:
description: |
An isolated set of Cloud Spanner resources on which databases can be
hosted.
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/spanner/'
api: 'https://cloud.google.com/spanner/docs/reference/rest/v1/projects.instances'
exports:
- name
transport: !ruby/object:Api::Resource::Transport
decoder: decode_response
collection_url_response: !ruby/object:Api::Resource::ResponseList
items: 'instances'
<%= indent(compile_file({}, 'templates/global_async.yaml.erb'), 4) %>
properties:
- !ruby/object:Api::Type::String
name: 'name'
description: |
A unique identifier for the instance, which cannot be changed after
the instance is created. Values are of the form
projects/<project>/instances/[a-z][-a-z0-9]*[a-z0-9]. The final
segment of the name must be between 6 and 30 characters in length.
the instance is created. The name must be between 6 and 30 characters
in length.
- !ruby/object:Api::Type::ResourceRef
name: 'config'
resource: 'InstanceConfig'
imports: 'name'
description: 'A reference to the instance configuration.'
required: true
- !ruby/object:Api::Type::String
name: 'displayName'
description: |
Expand All @@ -80,6 +85,7 @@ objects:
- !ruby/object:Api::Type::Integer
name: 'nodeCount'
description: 'The number of nodes allocated to this instance.'
required: true
- !ruby/object:Api::Type::KeyValuePairs
name: 'labels'
description: |
Expand Down Expand Up @@ -109,6 +115,17 @@ objects:
An object containing a list of "key": value pairs.
Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.
- !ruby/object:Api::Type::Enum
name: 'state'
description: |
Instance status: `CREATING` or `READY`.
output: true
# This attribute is not useful - we include it in Terraform for historical
# reasons, but you should most likely not use it.
exclude: true
values:
- :READY
- :CREATING
- !ruby/object:Api::Resource
name: 'Database'
base_url: projects/{{project}}/instances/{{instance}}/databases
Expand Down
29 changes: 28 additions & 1 deletion products/spanner/terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,36 @@ overrides: !ruby/object:Overrides::ResourceOverrides
encoder: templates/terraform/encoders/spanner_database.go.erb
decoder: templates/terraform/decoders/spanner_database.go.erb
InstanceConfig: !ruby/object:Overrides::Terraform::ResourceOverride
# This is appropriate for a datasource - doesn't have a create method.
exclude: true
Instance: !ruby/object:Overrides::Terraform::ResourceOverride
exclude: true
id_format: "{{project}}/{{name}}"
import_format:
- "projects/{{project}}/instances/{{name}}"
- "{{project}}/{{name}}"
- "{{name}}"
properties:
displayName: !ruby/object:Overrides::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
regex: '^(?:[a-z](?:[-_a-z0-9]{2,28}[a-z0-9])?)$'
name: !ruby/object:Overrides::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
regex: '^(?:[a-z](?:[-_a-z0-9]{4,28}[a-z0-9])?)$'
# This resource supports a sort of odd autogenerate-if-not-set
# system, which is done in the encoder. Consequently we have
# to interpret "not set" as "use the name in state".
default_from_api: true
nodeCount: !ruby/object:Overrides::Terraform::PropertyOverride
name: num_nodes
config: !ruby/object:Overrides::Terraform::PropertyOverride
custom_expand: templates/terraform/custom_expand/spanner_instance_config.go.erb
state: !ruby/object:Overrides::Terraform::PropertyOverride
exclude: false
custom_code: !ruby/object:Provider::Terraform::CustomCode
encoder: templates/terraform/encoders/spanner_instance.go.erb
update_encoder: templates/terraform/encoders/spanner_instance_update.go.erb
decoder: templates/terraform/decoders/spanner_instance.go.erb
post_create: templates/terraform/post_create/sleep.go.erb

# This is for copying files over
files: !ruby/object:Provider::Config::Files
Expand Down
27 changes: 27 additions & 0 deletions templates/terraform/custom_expand/spanner_instance_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<%- # the license inside this block applies to this file
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-%>
func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
r := regexp.MustCompile("projects/(.+)/notes/(.+)")
if r.MatchString(v.(string)) {
return v.(string), nil
}

project, err := getProject(d, config)
if err != nil {
return nil, err
}

return fmt.Sprintf("projects/%s/notes/%s", project, v.(string)), nil
}
27 changes: 27 additions & 0 deletions templates/terraform/custom_expand/spanner_instance_config.go.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<%- # the license inside this block applies to this file
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-%>
func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
r := regexp.MustCompile("projects/(.+)/instanceConfigs/(.+)")
if r.MatchString(v.(string)) {
return v.(string), nil
}

project, err := getProject(d, config)
if err != nil {
return nil, err
}

return fmt.Sprintf("projects/%s/instanceConfigs/%s", project, v.(string)), nil
}
2 changes: 0 additions & 2 deletions templates/terraform/decoders/spanner_database.go.erb
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
config := meta.(*Config)
d.SetId(res["name"].(string))
log.Printf("[DEBUG] name = %s", res["name"])
if err := parseImportId([]string{"projects/(?P<project>[^/]+)/instances/(?P<instance>[^/]+)/databases/(?P<name>[^/]+)"}, d, config); err != nil {
return nil, err
}
res["project"] = d.Get("project").(string)
res["instance"] = d.Get("instance").(string)
res["name"] = d.Get("name").(string)
log.Printf("[DEBUG] result %#v", res)
id, err := replaceVars(d, config, "{{instance}}/{{name}}")
if err != nil {
return nil, err
Expand Down
13 changes: 13 additions & 0 deletions templates/terraform/decoders/spanner_instance.go.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
config := meta.(*Config)
d.SetId(res["name"].(string))
if err := parseImportId([]string{"projects/(?P<project>[^/]+)/instances/(?P<name>[^/]+)"}, d, config); err != nil {
return nil, err
}
res["project"] = d.Get("project").(string)
res["name"] = d.Get("name").(string)
id, err := replaceVars(d, config, "{{project}}/{{name}}")
if err != nil {
return nil, err
}
d.SetId(id)
return res, nil
10 changes: 10 additions & 0 deletions templates/terraform/encoders/spanner_instance.go.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
newObj := make(map[string]interface{})
newObj["instance"] = obj
if obj["name"] == nil {
d.Set("name", resource.PrefixedUniqueId("tfgen-spanid-")[:30])
newObj["instanceId"] = d.Get("name").(string)
} else {
newObj["instanceId"] = obj["name"]
}
delete(obj, "name")
return newObj, nil
19 changes: 19 additions & 0 deletions templates/terraform/encoders/spanner_instance_update.go.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
project, err := getProject(d, meta.(*Config))
if err != nil {
return nil, err
}
obj["name"] = fmt.Sprintf("projects/%s/instances/%s", project, obj["name"])
newObj := make(map[string]interface{})
newObj["instance"] = obj
updateMask := make([]string, 0)
if d.HasChange("num_nodes") {
updateMask = append(updateMask, "nodeCount")
}
if d.HasChange("display_name") {
updateMask = append(updateMask, "displayName")
}
if d.HasChange("labels") {
updateMask = append(updateMask, "labels")
}
newObj["fieldMask"] = strings.Join(updateMask, ",")
return newObj, nil
3 changes: 3 additions & 0 deletions templates/terraform/post_create/sleep.go.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Spanner instances are, ironically, eventually consistent.
// We ensure that the Read sees the instance as created by sleeping, briefly.
time.Sleep(5 * time.Second)
Loading

0 comments on commit 151377c

Please sign in to comment.