Unittests for expansion.py

pull/135/head
Graham Welch 10 years ago
parent 6e15ece724
commit a89b6610d2

@ -136,16 +136,17 @@ def _ProcessResource(resource, imports, env, validate_schema=False):
layout = {'name': resource['name'],
'type': resource['type']}
if IsTemplate(resource['type']) and resource['type'] in imports:
if IsTemplate(resource['type']):
# A template resource, which contains sub-resources.
expanded_template = ExpandTemplate(resource, imports, env, validate_schema)
if expanded_template['resources'] is not None:
if expanded_template['resources']:
_ValidateUniqueNames(expanded_template['resources'], resource['type'])
# Process all sub-resources of this template.
for resource_to_process in expanded_template['resources']:
processed_resource = _ProcessResource(resource_to_process, imports, env)
processed_resource = _ProcessResource(resource_to_process, imports, env,
validate_schema)
# Append all sub-resources to the config resources, and the resulting
# layout of sub-resources.
@ -228,7 +229,7 @@ def ExpandTemplate(resource, imports, env, validate_schema=False):
resource['properties'] = schema_validation.Validate(
properties, schema, source_file, imports)
except schema_validation.ValidationErrors as e:
raise ExpansionError(resource, e.message)
raise ExpansionError(resource['name'], e.message)
if source_file.endswith('jinja'):
expanded_template = ExpandJinja(

@ -0,0 +1,509 @@
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
"""Basic unit tests for template expansion library."""
import expansion
import os
import unittest
import yaml
def GetFilePath():
"""Find our source and data files."""
return os.path.dirname(os.path.abspath(__file__))
def ReadTestFile(filename):
"""Returns contents of a file from the test/ directory."""
full_path = GetFilePath() + '/../test/templates/' + filename
test_file = open(full_path, 'r')
return test_file.read()
def GetTestBasePath(filename):
"""Returns the base path of a file from the testdata/ directory."""
full_path = GetFilePath() + '/../test/templates/' + filename
return os.path.dirname(full_path)
class ExpansionTest(unittest.TestCase):
"""Tests basic functionality of the template expansion library."""
EMPTY_RESPONSE = 'config:\n resources: []\nlayout:\n resources: []\n'
def testEmptyExpansion(self):
template = ''
expanded_template = expansion.Expand(
template)
self.assertEqual('', expanded_template)
def testNoResourcesList(self):
template = 'imports: [ test.import ]'
expanded_template = expansion.Expand(
template)
self.assertEqual(self.EMPTY_RESPONSE, expanded_template)
def testResourcesListEmpty(self):
template = 'resources:'
expanded_template = expansion.Expand(
template)
self.assertEqual(self.EMPTY_RESPONSE, expanded_template)
def testSimpleNoExpansionTemplate(self):
template = ReadTestFile('simple.yaml')
expanded_template = expansion.Expand(
template)
result_file = ReadTestFile('simple_result.yaml')
self.assertEquals(result_file, expanded_template)
def testJinjaExpansion(self):
template = ReadTestFile('jinja_template.yaml')
imports = {}
imports['jinja_template.jinja'] = ReadTestFile('jinja_template.jinja')
expanded_template = expansion.Expand(
template, imports)
result_file = ReadTestFile('jinja_template_result.yaml')
self.assertEquals(result_file, expanded_template)
def testJinjaWithNoParamsExpansion(self):
template = ReadTestFile('jinja_noparams.yaml')
imports = {}
imports['jinja_noparams.jinja'] = ReadTestFile('jinja_noparams.jinja')
expanded_template = expansion.Expand(
template, imports)
result_file = ReadTestFile('jinja_noparams_result.yaml')
self.assertEquals(result_file, expanded_template)
def testPythonWithNoParamsExpansion(self):
template = ReadTestFile('python_noparams.yaml')
imports = {}
imports['python_noparams.py'] = ReadTestFile('python_noparams.py')
expanded_template = expansion.Expand(
template, imports)
result_file = ReadTestFile('python_noparams_result.yaml')
self.assertEquals(result_file, expanded_template)
def testPythonExpansion(self):
template = ReadTestFile('python_template.yaml')
imports = {}
imports['python_template.py'] = ReadTestFile('python_template.py')
expanded_template = expansion.Expand(
template, imports)
result_file = ReadTestFile('python_template_result.yaml')
self.assertEquals(result_file, expanded_template)
def testPythonAndJinjaExpansion(self):
template = ReadTestFile('python_and_jinja_template.yaml')
imports = {}
imports['python_and_jinja_template.py'] = ReadTestFile(
'python_and_jinja_template.py')
imports['python_and_jinja_template.jinja'] = ReadTestFile(
'python_and_jinja_template.jinja')
expanded_template = expansion.Expand(
template, imports)
result_file = ReadTestFile('python_and_jinja_template_result.yaml')
self.assertEquals(result_file, expanded_template)
def testNoImportErrors(self):
template = 'resources: \n- type: something.jinja\n name: something'
try:
expansion.Expand(template, {})
self.fail('Expansion should fail')
except expansion.ExpansionError as e:
self.assertTrue('Unable to find source file' in e.message)
def testInvalidConfig(self):
template = ReadTestFile('invalid_config.yaml')
try:
expansion.Expand(
template)
self.fail('Expansion should fail')
except expansion.ExpansionError as e:
self.assertNotIn(os.path.basename(expansion.__name__), e.message,
'Do not leak internals')
def testJinjaWithImport(self):
template = ReadTestFile('jinja_template_with_import.yaml')
imports = {}
imports['jinja_template_with_import.jinja'] = ReadTestFile(
'jinja_template_with_import.jinja')
imports['helpers/common.jinja'] = ReadTestFile(
'helpers/common.jinja')
yaml_template = yaml.safe_load(template)
expanded_template = expansion.Expand(
str(yaml_template), imports)
result_file = ReadTestFile('jinja_template_with_import_result.yaml')
self.assertEquals(result_file, expanded_template)
def testJinjaWithInlinedFile(self):
template = ReadTestFile('jinja_template_with_inlinedfile.yaml')
imports = {}
imports['jinja_template_with_inlinedfile.jinja'] = ReadTestFile(
'jinja_template_with_inlinedfile.jinja')
imports['helpers/common.jinja'] = ReadTestFile(
'helpers/common.jinja')
imports['description_text.txt'] = ReadTestFile('description_text.txt')
yaml_template = yaml.safe_load(template)
expanded_template = expansion.Expand(
str(yaml_template), imports)
result_file = ReadTestFile('jinja_template_with_inlinedfile_result.yaml')
self.assertEquals(result_file, expanded_template)
def testPythonWithImport(self):
template = ReadTestFile('python_template_with_import.yaml')
imports = {}
imports['python_template_with_import.py'] = ReadTestFile(
'python_template_with_import.py')
imports['helpers/common.py'] = ReadTestFile('helpers/common.py')
imports['helpers/extra/common2.py'] = ReadTestFile(
'helpers/extra/common2.py')
imports['helpers/extra'] = ReadTestFile('helpers/extra/__init__.py')
yaml_template = yaml.safe_load(template)
expanded_template = expansion.Expand(
str(yaml_template), imports)
result_file = ReadTestFile('python_template_with_import_result.yaml')
self.assertEquals(result_file, expanded_template)
def testPythonWithInlinedFile(self):
template = ReadTestFile('python_template_with_inlinedfile.yaml')
imports = {}
imports['python_template_with_inlinedfile.py'] = ReadTestFile(
'python_template_with_inlinedfile.py')
imports['helpers/common.py'] = ReadTestFile('helpers/common.py')
imports['helpers/extra/common2.py'] = ReadTestFile(
'helpers/extra/common2.py')
imports['description_text.txt'] = ReadTestFile('description_text.txt')
yaml_template = yaml.safe_load(template)
expanded_template = expansion.Expand(
str(yaml_template), imports)
result_file = ReadTestFile(
'python_template_with_inlinedfile_result.yaml')
self.assertEquals(result_file, expanded_template)
def testPythonWithEnvironment(self):
template = ReadTestFile('python_template_with_env.yaml')
imports = {}
imports['python_template_with_env.py'] = ReadTestFile(
'python_template_with_env.py')
env = {'project': 'my-project'}
expanded_template = expansion.Expand(
template, imports, env)
result_file = ReadTestFile('python_template_with_env_result.yaml')
self.assertEquals(result_file, expanded_template)
def testJinjaWithEnvironment(self):
template = ReadTestFile('jinja_template_with_env.yaml')
imports = {}
imports['jinja_template_with_env.jinja'] = ReadTestFile(
'jinja_template_with_env.jinja')
env = {'project': 'test-project', 'deployment': 'test-deployment'}
expanded_template = expansion.Expand(
template, imports, env)
result_file = ReadTestFile('jinja_template_with_env_result.yaml')
self.assertEquals(result_file, expanded_template)
def testMissingNameErrors(self):
template = 'resources: \n- type: something.jinja\n'
try:
expansion.Expand(template, {})
self.fail('Expansion should fail')
except expansion.ExpansionError as e:
self.assertTrue('not have a name' in e.message)
def testDuplicateNamesErrors(self):
template = ReadTestFile('duplicate_names.yaml')
try:
expansion.Expand(template, {})
self.fail('Expansion should fail')
except expansion.ExpansionError as e:
self.assertTrue(("Resource name 'my_instance' is not unique"
" in config.") in e.message)
def testDuplicateNamesInSubtemplates(self):
template = ReadTestFile('duplicate_names_in_subtemplates.yaml')
imports = {}
imports['duplicate_names_in_subtemplates.jinja'] = ReadTestFile(
'duplicate_names_in_subtemplates.jinja')
try:
expansion.Expand(
template, imports)
self.fail('Expansion should fail')
except expansion.ExpansionError as e:
self.assertTrue('not unique in duplicate_names_in_subtemplates.jinja'
in e.message)
def testDuplicateNamesMixedLevel(self):
template = ReadTestFile('duplicate_names_mixed_level.yaml')
imports = {}
imports['duplicate_names_B.jinja'] = ReadTestFile(
'duplicate_names_B.jinja')
imports['duplicate_names_C.jinja'] = ReadTestFile(
'duplicate_names_C.jinja')
expanded_template = expansion.Expand(
template, imports)
result_file = ReadTestFile('duplicate_names_mixed_level_result.yaml')
self.assertEquals(result_file, expanded_template)
def testDuplicateNamesParentChild(self):
template = ReadTestFile('duplicate_names_parent_child.yaml')
imports = {}
imports['duplicate_names_B.jinja'] = ReadTestFile(
'duplicate_names_B.jinja')
expanded_template = expansion.Expand(
template, imports)
result_file = ReadTestFile('duplicate_names_parent_child_result.yaml')
self.assertEquals(result_file, expanded_template)
# Note, this template will fail in the frontend for duplicate resource names
def testTemplateReturnsEmpty(self):
template = ReadTestFile('no_resources.yaml')
imports = {}
imports['no_resources.py'] = ReadTestFile(
'no_resources.py')
try:
expansion.Expand(
template, imports)
self.fail('Expansion should fail')
except expansion.ExpansionError as e:
self.assertIn('Template did not return a \'resources:\' field.',
e.message)
self.assertIn('no_resources.py', e.message)
def testJinjaDefaultsSchema(self):
# Loop 1000 times to make sure we don't rely on dictionary ordering.
for unused_x in range(0, 1000):
template = ReadTestFile('jinja_defaults.yaml')
imports = {}
imports['jinja_defaults.jinja'] = ReadTestFile(
'jinja_defaults.jinja')
imports['jinja_defaults.jinja.schema'] = ReadTestFile(
'jinja_defaults.jinja.schema')
expanded_template = expansion.Expand(
template, imports,
validate_schema=True)
result_file = ReadTestFile('jinja_defaults_result.yaml')
self.assertEquals(result_file, expanded_template)
def testPythonDefaultsOverrideSchema(self):
template = ReadTestFile('python_schema.yaml')
imports = {}
imports['python_schema.py'] = ReadTestFile('python_schema.py')
imports['python_schema.py.schema'] = ReadTestFile('python_schema.py.schema')
env = {'project': 'my-project'}
expanded_template = expansion.Expand(
template, imports, env=env,
validate_schema=True)
result_file = ReadTestFile('python_schema_result.yaml')
self.assertEquals(result_file, expanded_template)
def testJinjaMissingRequiredPropertySchema(self):
template = ReadTestFile('jinja_missing_required.yaml')
imports = {}
imports['jinja_missing_required.jinja'] = ReadTestFile(
'jinja_missing_required.jinja')
imports['jinja_missing_required.jinja.schema'] = ReadTestFile(
'jinja_missing_required.jinja.schema')
try:
expansion.Expand(
template, imports,
validate_schema=True)
self.fail('Expansion error expected')
except expansion.ExpansionError as e:
self.assertIn('Invalid properties', e.message)
self.assertIn("'important' is a required property", e.message)
self.assertIn('jinja_missing_required_resource_name', e.message)
def testJinjaErrorFileMessage(self):
template = ReadTestFile('jinja_unresolved.yaml')
imports = {}
imports['jinja_unresolved.jinja'] = ReadTestFile('jinja_unresolved.jinja')
try:
expansion.Expand(
template, imports,
validate_schema=False)
self.fail('Expansion error expected')
except expansion.ExpansionError as e:
self.assertIn('jinja_unresolved.jinja', e.message)
def testJinjaMultipleErrorsSchema(self):
template = ReadTestFile('jinja_multiple_errors.yaml')
imports = {}
imports['jinja_multiple_errors.jinja'] = ReadTestFile(
'jinja_multiple_errors.jinja')
imports['jinja_multiple_errors.jinja.schema'] = ReadTestFile(
'jinja_multiple_errors.jinja.schema')
try:
expansion.Expand(
template, imports,
validate_schema=True)
self.fail('Expansion error expected')
except expansion.ExpansionError as e:
self.assertIn('Invalid properties', e.message)
self.assertIn("'a string' is not of type 'integer'", e.message)
self.assertIn("'d' is not one of ['a', 'b', 'c']", e.message)
self.assertIn("'longer than 10 chars' is too long", e.message)
self.assertIn("{'multipleOf': 2} is not allowed for 6", e.message)
def testPythonBadSchema(self):
template = ReadTestFile('python_bad_schema.yaml')
imports = {}
imports['python_bad_schema.py'] = ReadTestFile(
'python_bad_schema.py')
imports['python_bad_schema.py.schema'] = ReadTestFile(
'python_bad_schema.py.schema')
try:
expansion.Expand(
template, imports,
validate_schema=True)
self.fail('Expansion error expected')
except expansion.ExpansionError as e:
self.assertIn('Invalid schema', e.message)
self.assertIn("'int' is not valid under any of the given schemas",
e.message)
self.assertIn("'maximum' is a dependency of u'exclusiveMaximum'",
e.message)
self.assertIn("10 is not of type u'boolean'", e.message)
self.assertIn("'not a list' is not of type u'array'", e.message)
def testNoProperties(self):
template = ReadTestFile('no_properties.yaml')
imports = {}
imports['no_properties.py'] = ReadTestFile(
'no_properties.py')
expanded_template = expansion.Expand(
template, imports,
validate_schema=True)
result_file = ReadTestFile('no_properties_result.yaml')
self.assertEquals(result_file, expanded_template)
def testNestedTemplateSchema(self):
template = ReadTestFile('use_helper.yaml')
imports = {}
imports['use_helper.jinja'] = ReadTestFile(
'use_helper.jinja')
imports['use_helper.jinja.schema'] = ReadTestFile(
'use_helper.jinja.schema')
imports['helper.jinja'] = ReadTestFile(
'helper.jinja')
imports['helper.jinja.schema'] = ReadTestFile(
'helper.jinja.schema')
expanded_template = expansion.Expand(
template, imports,
validate_schema=True)
result_file = ReadTestFile('use_helper_result.yaml')
self.assertEquals(result_file, expanded_template)
if __name__ == '__main__':
unittest.main()

@ -0,0 +1 @@
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

@ -0,0 +1,9 @@
resources:
- type: compute.v1.instance
name: my_instance
properties:
zone: test-zone-a
- type: compute.v1.instance
name: my_instance
properties:
zone: test-zone-b

@ -0,0 +1,5 @@
resources:
- type: compute.v1.instance
name: B
properties:
zone: test-zone-b

@ -0,0 +1,5 @@
resources:
- type: compute.v1.instance
name: C
properties:
zone: test-zone-c

@ -0,0 +1,9 @@
resources:
- type: compute.v1.instance
name: my_instance
properties:
zone: test-zone-a
- type: compute.v1.instance
name: my_instance
properties:
zone: test-zone-b

@ -0,0 +1,5 @@
imports: ["duplicate_names_in_subtemplates.jinja"]
resources:
- name: subtemplate
type: duplicate_names_in_subtemplates.jinja

@ -0,0 +1,7 @@
imports: ["duplicate_names_B.jinja", "duplicate_names_C.jinja"]
resources:
- name: A
type: duplicate_names_B.jinja
- name: B
type: duplicate_names_C.jinja

@ -0,0 +1,22 @@
config:
resources:
- name: B
properties:
zone: test-zone-b
type: compute.v1.instance
- name: C
properties:
zone: test-zone-c
type: compute.v1.instance
layout:
resources:
- name: A
resources:
- name: B
type: compute.v1.instance
type: duplicate_names_B.jinja
- name: B
resources:
- name: C
type: compute.v1.instance
type: duplicate_names_C.jinja

@ -0,0 +1,7 @@
imports: ["duplicate_names_B.jinja"]
resources:
- name: A
type: duplicate_names_B.jinja
- name: B
type: compute.v1.instance

@ -0,0 +1,17 @@
config:
resources:
- name: B
properties:
zone: test-zone-b
type: compute.v1.instance
- name: B
type: compute.v1.instance
layout:
resources:
- name: A
resources:
- name: B
type: compute.v1.instance
type: duplicate_names_B.jinja
- name: B
type: compute.v1.instance

@ -0,0 +1,5 @@
resources:
- name: helper
type: bar
properties:
test: {{ properties["foobar"] }}

@ -0,0 +1,4 @@
properties:
foobar:
type: string
default: Use this schema

@ -0,0 +1,3 @@
{%- macro GenerateMachineName(prefix='', suffix='') -%}
{{ prefix + "-" + suffix }}
{%- endmacro %}

@ -0,0 +1,8 @@
# Copyright 2014 Google Inc. All Rights Reserved.
"""Dummy helper methods invoked in other constructors."""
def GenerateMachineName(prefix, suffix):
"""Generates name of a VM."""
return prefix + "-" + suffix

@ -0,0 +1,8 @@
# Copyright 2014 Google Inc. All Rights Reserved.
"""Dummy helper methods invoked in other constructors."""
def GenerateMachineSize():
"""Generates size of a VM."""
return "big"

@ -0,0 +1,2 @@
resources:
- name: foo properties: bar: baz

@ -0,0 +1,16 @@
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ properties["deployment"] }}
properties:
zone: {{ properties["zone"] }}
machineType: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/zones/{{ properties["zone"] }}/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-{{ properties["deployment"] }}
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/global/networks/default

@ -0,0 +1,18 @@
info:
title: Schema for a basic jinja template that includes default values
imports:
properties:
foo:
description: blah
type: string
zone:
type: string
default: test-zone
project:
type: string
default: test-project
deployment:
type: string
default: test-deployment

@ -0,0 +1,9 @@
imports:
- path: "jinja_defaults.jinja"
- path: "jinja_defaults.jinja.schema"
resources:
- name: jinja_defaults_name
type: jinja_defaults.jinja
properties:
foo: bar

@ -0,0 +1,29 @@
config:
resources:
- name: vm-created-by-cloud-config-test-deployment
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
layout:
resources:
- name: jinja_defaults_name
properties:
deployment: test-deployment
foo: bar
project: test-project
zone: test-zone
resources:
- name: vm-created-by-cloud-config-test-deployment
type: compute.v1.instance
type: jinja_defaults.jinja

@ -0,0 +1,4 @@
Nothing here because this file should never be called.
The validation will fail before this file is used.
{{% Invalid

@ -0,0 +1,11 @@
info:
title: Schema with a required property
imports:
required:
- important
properties:
important:
type: string

@ -0,0 +1,9 @@
imports:
- path: "jinja_missing_required.jinja"
- path: "jinja_missing_required.jinja.schema"
resources:
- name: jinja_missing_required_resource_name
type: jinja_missing_required.jinja
properties:
less-important: an optional property

@ -0,0 +1,4 @@
Nothing here because this file should never be called.
The validation will fail before this file is used.
{{% Invalid

@ -0,0 +1,22 @@
info:
title: Schema with several rules
imports:
properties:
number:
type: integer
short-string:
type: string
maxLength: 10
odd:
type: integer
not:
multipleOf: 2
abc:
type: string
enum:
- a
- b
- c

@ -0,0 +1,12 @@
imports:
- path: "jinja_multiple_errors.jinja"
- path: "jinja_multiple_errors.jinja.schema"
resources:
- name: jinja_multiple_errors
type: jinja_multiple_errors.jinja
properties:
number: a string
short-string: longer than 10 chars
odd: 6
abc: d

@ -0,0 +1,19 @@
resources:
{% for name in ['name1', 'name2'] %}
- type: compute.v1.instance
name: {{ name }}
properties:
zone: test-zone
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
{% endfor %}

@ -0,0 +1,6 @@
imports: ["jinja_noparams.jinja"]
resources:
- name: jinja_noparams_name
type: jinja_noparams.jinja

@ -0,0 +1,41 @@
config:
resources:
- name: name1
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
- name: name2
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
layout:
resources:
- name: jinja_noparams_name
resources:
- name: name1
type: compute.v1.instance
- name: name2
type: compute.v1.instance
type: jinja_noparams.jinja

@ -0,0 +1,18 @@
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ properties["deployment"] }}
properties:
zone: {{ properties["zone"] }}
machineType: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/zones/{{ properties["zone"] }}/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-{{ properties["deployment"] }}
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/global/networks/default

@ -0,0 +1,10 @@
imports: ["jinja_template.jinja"]
resources:
- name: jinja_template_name
type: jinja_template.jinja
properties:
zone: test-zone
project: test-project
deployment: test-deployment

@ -0,0 +1,28 @@
config:
resources:
- name: vm-created-by-cloud-config-test-deployment
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
layout:
resources:
- name: jinja_template_name
properties:
deployment: test-deployment
project: test-project
zone: test-zone
resources:
- name: vm-created-by-cloud-config-test-deployment
type: compute.v1.instance
type: jinja_template.jinja

@ -0,0 +1,18 @@
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ env["deployment"] }}
properties:
zone: {{ properties["zone"] }}
machineType: https://www.googleapis.com/compute/v1/projects/{{ env["project"] }}/zones/{{ properties["zone"] }}/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-{{ env["deployment"] }}-{{ env["name"] }}-{{ env["type"] }}
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/{{ env["project"] }}/global/networks/default

@ -0,0 +1,8 @@
imports: ["jinja_template_with_env.jinja"]
resources:
- name: jinja_template_with_env_name
type: jinja_template_with_env.jinja
properties:
zone: test-zone

@ -0,0 +1,26 @@
config:
resources:
- name: vm-created-by-cloud-config-test-deployment
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment-jinja_template_with_env_name-jinja_template_with_env.jinja
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
layout:
resources:
- name: jinja_template_with_env_name
properties:
zone: test-zone
resources:
- name: vm-created-by-cloud-config-test-deployment
type: compute.v1.instance
type: jinja_template_with_env.jinja

@ -0,0 +1,6 @@
{% import 'helpers/common.jinja' as common %}
resources:
- name: {{ common.GenerateMachineName("myFrontend", "prod") }}
type: compute.v1.instance
properties:
machineSize: big

@ -0,0 +1,5 @@
imports: ["jinja_template_with_import.jinja", "helpers/common.jinja"]
resources:
- name: jinja_template_with_import_name
type: jinja_template_with_import.jinja

@ -0,0 +1,13 @@
config:
resources:
- name: myFrontend-prod
properties:
machineSize: big
type: compute.v1.instance
layout:
resources:
- name: jinja_template_with_import_name
resources:
- name: myFrontend-prod
type: compute.v1.instance
type: jinja_template_with_import.jinja

@ -0,0 +1,7 @@
{% import 'helpers/common.jinja' as common %}
resources:
- name: {{ common.GenerateMachineName("myFrontend", "prod") }}
type: compute.v1.instance
properties:
description: {{ imports[properties["description-file"]] }}
machineSize: big

@ -0,0 +1,7 @@
imports: ["jinja_template_with_inlinedfile.jinja", "helpers/common.jinja", "description_text.txt"]
resources:
- name: jinja_template_with_inlinedfile_name
type: jinja_template_with_inlinedfile.jinja
properties:
description-file: description_text.txt

@ -0,0 +1,21 @@
config:
resources:
- name: myFrontend-prod
properties:
description: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
machineSize: big
type: compute.v1.instance
layout:
resources:
- name: jinja_template_with_inlinedfile_name
properties:
description-file: description_text.txt
resources:
- name: myFrontend-prod
type: compute.v1.instance
type: jinja_template_with_inlinedfile.jinja

@ -0,0 +1,18 @@
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ porcelain["deployment"] }}
properties:
zone: {{ properties["zone"] }}
machineType: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/zones/{{ properties["zone"] }}/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-{{ properties["deployment"] }}
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/global/networks/default

@ -0,0 +1,10 @@
imports: ["jinja_unresolved.jinja"]
resources:
- name: jinja_template_name
type: jinja_unresolved.jinja
properties:
zone: test-zone
project: test-project
deployment: test-deployment

@ -0,0 +1,5 @@
"""Return empty resources block."""
def GenerateConfig(_):
return """resources:"""

@ -0,0 +1,6 @@
imports:
- path: "no_properties.py"
resources:
- name: test-resource
type: no_properties.py

@ -0,0 +1,6 @@
config:
resources: []
layout:
resources:
- name: test-resource
type: no_properties.py

@ -0,0 +1,6 @@
"""Does nothing."""
def GenerateConfig(_):
"""Returns empty string."""
return ''

@ -0,0 +1,6 @@
imports:
- path: "no_resources.py"
resources:
- name: test-resource
type: no_resources.py

@ -0,0 +1,17 @@
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ properties["deployment"] }}
properties:
zone: {{ properties["zone"] }}
machineType: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/zones/{{ properties["zone"] }}/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-{{ properties["deployment"] }}
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/global/networks/default

@ -0,0 +1,37 @@
# Copyright 2014 Google Inc. All Rights Reserved.
#% description: Creates a VM running a Salt master daemon in a Docker container.
#% parameters:
#% - name: masterAddress
#% type: string
#% description: Name of the Salt master VM.
#% required: true
#% - name: project
#% type: string
#% description: Name of the Cloud project.
#% required: true
#% - name: zone
#% type: string
#% description: Zone to create the resources in.
#% required: true
"""Generates config for a VM running a SaltStack master.
Just for fun this template is in Python, while the others in this
directory are in Jinja2.
"""
def GenerateConfig(evaluation_context):
return """
resources:
- name: python_and_jinja_template_jinja_name
type: python_and_jinja_template.jinja
properties:
zone: %(zone)s
project: %(project)s
deployment: %(master)s
""" % {"master": evaluation_context.properties["masterAddress"],
"project": evaluation_context.properties["project"],
"zone": evaluation_context.properties["zone"]}

@ -0,0 +1,9 @@
imports: ["python_and_jinja_template.jinja", "python_and_jinja_template.py"]
resources:
- name: python_and_jinja_template_name
type: python_and_jinja_template.py
properties:
masterAddress: master-address
project: my-project
zone: my-zone

@ -0,0 +1,35 @@
config:
resources:
- name: vm-created-by-cloud-config-master-address
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-master-address
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/my-project/zones/my-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/my-project/global/networks/default
zone: my-zone
type: compute.v1.instance
layout:
resources:
- name: python_and_jinja_template_name
properties:
masterAddress: master-address
project: my-project
zone: my-zone
resources:
- name: python_and_jinja_template_jinja_name
properties:
deployment: master-address
project: my-project
zone: my-zone
resources:
- name: vm-created-by-cloud-config-master-address
type: compute.v1.instance
type: python_and_jinja_template.jinja
type: python_and_jinja_template.py

@ -0,0 +1,3 @@
"""Throws an exception."""
raise Exception

@ -0,0 +1,19 @@
info:
title: Schema with several errors
imports:
properties:
bad-type:
type: int
missing-cond:
type: string
exclusiveMaximum: 10
odd-string:
type: string
not:
multipleOf: 2
bad-enum:
type: string
enum: not a list

@ -0,0 +1,9 @@
imports:
- path: "python_bad_schema.py"
- path: "python_bad_schema.py.schema"
resources:
- name: python_bad_schema
type: python_bad_schema.py
properties:
innocent: true

@ -0,0 +1,14 @@
# Copyright 2014 Google Inc. All Rights Reserved.
"""Constructs a VM."""
def GenerateConfig(_):
"""Generates config of a VM."""
return """
resources:
- name: myBackend
type: compute.v1.instance
properties:
machineSize: big
"""

@ -0,0 +1,9 @@
imports: ["python_noparams.py"]
resources:
- name: myFrontend
type: compute.v1.instance
properties:
machineSize: big
- name: python_noparams_name
type: python_noparams.py

@ -0,0 +1,19 @@
config:
resources:
- name: myFrontend
properties:
machineSize: big
type: compute.v1.instance
- name: myBackend
properties:
machineSize: big
type: compute.v1.instance
layout:
resources:
- name: myFrontend
type: compute.v1.instance
- name: python_noparams_name
resources:
- name: myBackend
type: compute.v1.instance
type: python_noparams.py

@ -0,0 +1,59 @@
# Copyright 2014 Google Inc. All Rights Reserved.
#% description: Creates a VM running a Salt master daemon in a Docker container.
#% parameters:
#% - name: masterAddress
#% type: string
#% description: Name of the Salt master VM.
#% required: true
#% - name: project
#% type: string
#% description: Name of the Cloud project.
#% required: true
#% - name: zone
#% type: string
#% description: Zone to create the resources in.
#% required: true
"""Generates config for a VM running a SaltStack master.
Just for fun this template is in Python, while the others in this
directory are in Jinja2.
"""
def GenerateConfig(evaluation_context):
return """
resources:
- type: compute.v1.firewall
name: %(master)s-firewall
properties:
network: https://www.googleapis.com/compute/v1/projects/%(project)s/global/networks/default
sourceRanges: [ "0.0.0.0/0" ]
allowed:
- IPProtocol: tcp
ports: [ "4505", "4506" ]
- type: compute.v1.instance
name: %(master)s
properties:
zone: %(zone)s
machineType: https://www.googleapis.com/compute/v1/projects/%(project)s/zones/%(zone)s/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/%(project)s/global/networks/default
accessConfigs:
- name: External NAT
type: ONE_TO_ONE_NAT
metadata:
items:
- key: startup-script
value: startup-script-value
""" % {"master": evaluation_context.properties["masterAddress"],
"project": evaluation_context.env["project"],
"zone": evaluation_context.properties["zone"]}

@ -0,0 +1,14 @@
info:
title: A simple python template that has a schema.
imports:
properties:
masterAddress:
type: string
default: slave-address
description: masterAddress
zone:
type: string
default: not-test-zone
description: zone

@ -0,0 +1,10 @@
imports:
- path: "python_schema.py"
- path: "python_schema.py.schema"
resources:
- name: python_schema
type: python_schema.py
properties:
masterAddress: master-address
zone: my-zone

@ -0,0 +1,46 @@
config:
resources:
- name: master-address-firewall
properties:
allowed:
- IPProtocol: tcp
ports:
- '4505'
- '4506'
network: https://www.googleapis.com/compute/v1/projects/my-project/global/networks/default
sourceRanges:
- 0.0.0.0/0
type: compute.v1.firewall
- name: master-address
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/my-project/zones/my-zone/machineTypes/f1-micro
metadata:
items:
- key: startup-script
value: startup-script-value
networkInterfaces:
- accessConfigs:
- name: External NAT
type: ONE_TO_ONE_NAT
network: https://www.googleapis.com/compute/v1/projects/my-project/global/networks/default
zone: my-zone
type: compute.v1.instance
layout:
resources:
- name: python_schema
properties:
masterAddress: master-address
zone: my-zone
resources:
- name: master-address-firewall
type: compute.v1.firewall
- name: master-address
type: compute.v1.instance
type: python_schema.py

@ -0,0 +1,59 @@
# Copyright 2014 Google Inc. All Rights Reserved.
#% description: Creates a VM running a Salt master daemon in a Docker container.
#% parameters:
#% - name: masterAddress
#% type: string
#% description: Name of the Salt master VM.
#% required: true
#% - name: project
#% type: string
#% description: Name of the Cloud project.
#% required: true
#% - name: zone
#% type: string
#% description: Zone to create the resources in.
#% required: true
"""Generates config for a VM running a SaltStack master.
Just for fun this template is in Python, while the others in this
directory are in Jinja2.
"""
def GenerateConfig(evaluation_context):
return """
resources:
- type: compute.v1.firewall
name: %(master)s-firewall
properties:
network: https://www.googleapis.com/compute/v1/projects/%(project)s/global/networks/default
sourceRanges: [ "0.0.0.0/0" ]
allowed:
- IPProtocol: tcp
ports: [ "4505", "4506" ]
- type: compute.v1.instance
name: %(master)s
properties:
zone: %(zone)s
machineType: https://www.googleapis.com/compute/v1/projects/%(project)s/zones/%(zone)s/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/%(project)s/global/networks/default
accessConfigs:
- name: External NAT
type: ONE_TO_ONE_NAT
metadata:
items:
- key: startup-script
value: startup-script-value
""" % {"master": evaluation_context.properties["masterAddress"],
"project": evaluation_context.properties["project"],
"zone": evaluation_context.properties["zone"]}

@ -0,0 +1,9 @@
imports: ["python_template.py"]
resources:
- name: python_template_name
type: python_template.py
properties:
masterAddress: master-address
project: my-project
zone: my-zone

@ -0,0 +1,47 @@
config:
resources:
- name: master-address-firewall
properties:
allowed:
- IPProtocol: tcp
ports:
- '4505'
- '4506'
network: https://www.googleapis.com/compute/v1/projects/my-project/global/networks/default
sourceRanges:
- 0.0.0.0/0
type: compute.v1.firewall
- name: master-address
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/my-project/zones/my-zone/machineTypes/f1-micro
metadata:
items:
- key: startup-script
value: startup-script-value
networkInterfaces:
- accessConfigs:
- name: External NAT
type: ONE_TO_ONE_NAT
network: https://www.googleapis.com/compute/v1/projects/my-project/global/networks/default
zone: my-zone
type: compute.v1.instance
layout:
resources:
- name: python_template_name
properties:
masterAddress: master-address
project: my-project
zone: my-zone
resources:
- name: master-address-firewall
type: compute.v1.firewall
- name: master-address
type: compute.v1.instance
type: python_template.py

@ -0,0 +1,59 @@
# Copyright 2014 Google Inc. All Rights Reserved.
#% description: Creates a VM running a Salt master daemon in a Docker container.
#% parameters:
#% - name: masterAddress
#% type: string
#% description: Name of the Salt master VM.
#% required: true
#% - name: project
#% type: string
#% description: Name of the Cloud project.
#% required: true
#% - name: zone
#% type: string
#% description: Zone to create the resources in.
#% required: true
"""Generates config for a VM running a SaltStack master.
Just for fun this template is in Python, while the others in this
directory are in Jinja2.
"""
def GenerateConfig(evaluation_context):
return """
resources:
- type: compute.v1.firewall
name: %(master)s-firewall
properties:
network: https://www.googleapis.com/compute/v1/projects/%(project)s/global/networks/default
sourceRanges: [ "0.0.0.0/0" ]
allowed:
- IPProtocol: tcp
ports: [ "4505", "4506" ]
- type: compute.v1.instance
name: %(master)s
properties:
zone: %(zone)s
machineType: https://www.googleapis.com/compute/v1/projects/%(project)s/zones/%(zone)s/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/%(project)s/global/networks/default
accessConfigs:
- name: External NAT
type: ONE_TO_ONE_NAT
metadata:
items:
- key: startup-script
value: startup-script-value
""" % {"master": evaluation_context.properties["masterAddress"],
"project": evaluation_context.env["project"],
"zone": evaluation_context.properties["zone"]}

@ -0,0 +1,8 @@
imports: ["python_template_with_env.py"]
resources:
- name: python_template_with_env_name
type: python_template_with_env.py
properties:
masterAddress: master-address
zone: my-zone

@ -0,0 +1,46 @@
config:
resources:
- name: master-address-firewall
properties:
allowed:
- IPProtocol: tcp
ports:
- '4505'
- '4506'
network: https://www.googleapis.com/compute/v1/projects/my-project/global/networks/default
sourceRanges:
- 0.0.0.0/0
type: compute.v1.firewall
- name: master-address
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/my-project/zones/my-zone/machineTypes/f1-micro
metadata:
items:
- key: startup-script
value: startup-script-value
networkInterfaces:
- accessConfigs:
- name: External NAT
type: ONE_TO_ONE_NAT
network: https://www.googleapis.com/compute/v1/projects/my-project/global/networks/default
zone: my-zone
type: compute.v1.instance
layout:
resources:
- name: python_template_with_env_name
properties:
masterAddress: master-address
zone: my-zone
resources:
- name: master-address-firewall
type: compute.v1.firewall
- name: master-address
type: compute.v1.instance
type: python_template_with_env.py

@ -0,0 +1,20 @@
# Copyright 2014 Google Inc. All Rights Reserved.
"""Constructs a VM."""
import json
import helpers.common
import helpers.extra.common2
def GenerateConfig(_):
"""Generates config of a VM."""
return """
resources:
- name: %s
type: compute.v1.instance
properties:
machineSize: %s
""" % (helpers.common.GenerateMachineName(
json.dumps('myFrontend').strip('"'), 'prod'),
helpers.extra.common2.GenerateMachineSize())

@ -0,0 +1,5 @@
imports: ["python_template_with_import.py", "helpers/common.py", "helpers/common2.py", "helpers/__init__.py"]
resources:
- name: python_template_with_import_name
type: python_template_with_import.py

@ -0,0 +1,13 @@
config:
resources:
- name: myFrontend-prod
properties:
machineSize: big
type: compute.v1.instance
layout:
resources:
- name: python_template_with_import_name
resources:
- name: myFrontend-prod
type: compute.v1.instance
type: python_template_with_import.py

@ -0,0 +1,22 @@
# Copyright 2014 Google Inc. All Rights Reserved.
"""Constructs a VM."""
# Verify that both ways of hierarchical imports work.
from helpers import common
import helpers.extra.common2
def GenerateConfig(evaluation_context):
"""Generates config of a VM."""
return """
resources:
- name: %s
type: compute.v1.instance
properties:
description: %s
machineSize: %s
""" % (common.GenerateMachineName("myFrontend", "prod"),
evaluation_context.imports[
evaluation_context.properties["description-file"]],
helpers.extra.common2.GenerateMachineSize())

@ -0,0 +1,7 @@
imports: ["python_template_with_inlinedfile.py", "helpers/common.py", "helpers/common2.py", "helpers/__init__.py", "description_text.txt"]
resources:
- name: python_template_with_inlinedfile_name
type: python_template_with_inlinedfile.py
properties:
description-file: description_text.txt

@ -0,0 +1,21 @@
config:
resources:
- name: myFrontend-prod
properties:
description: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
machineSize: big
type: compute.v1.instance
layout:
resources:
- name: python_template_with_inlinedfile_name
properties:
description-file: description_text.txt
resources:
- name: myFrontend-prod
type: compute.v1.instance
type: python_template_with_inlinedfile.py

@ -0,0 +1,9 @@
# Copyright 2014 Google Inc. All Rights Reserved.
"""A python script that raise exceptions.
"""
def GenerateConfig(unused_context):
raise NameError('No file found')

@ -0,0 +1,9 @@
imports: ["python_with_exception.py"]
resources:
- name: python_with_exception_name
type: python_with_exception.py
properties:
masterAddress: master-address
project: my-project
zone: my-zone

@ -0,0 +1,18 @@
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ params["deployment"] }}
properties:
zone: test-zone
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default

@ -0,0 +1,21 @@
config:
resources:
- name: vm-created-by-cloud-config-{{ params["deployment"] }}
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
layout:
resources:
- name: vm-created-by-cloud-config-{{ params["deployment"] }}
type: compute.v1.instance

@ -0,0 +1,7 @@
resources:
- name: use-helper
type: foo
properties:
test: {{ properties['barfoo'] }}
- name: use-helper-helper
type: helper.jinja

@ -0,0 +1,4 @@
properties:
barfoo:
type: string
default: Use this schema also

@ -0,0 +1,3 @@
resources:
- name: use-helper
type: use_helper.jinja

@ -0,0 +1,26 @@
config:
resources:
- name: use-helper
properties:
test: Use this schema also
type: foo
- name: helper
properties:
test: Use this schema
type: bar
layout:
resources:
- name: use-helper
properties:
barfoo: Use this schema also
resources:
- name: use-helper
type: foo
- name: use-helper-helper
properties:
foobar: Use this schema
resources:
- name: helper
type: bar
type: helper.jinja
type: use_helper.jinja
Loading…
Cancel
Save