Retire Packaging Deb project repos

This commit is part of a series to retire the Packaging Deb
project. Step 2 is to remove all content from the project
repos, replacing it with a README notification where to find
ongoing work, and how to recover the repo if needed at some
future point (as in
https://docs.openstack.org/infra/manual/drivers.html#retiring-a-project).

Change-Id: I604718b2ec740780a762c5c2dcc2cce0d317f55d
This commit is contained in:
Tony Breeds 2017-09-12 15:38:51 -06:00
parent 13f1f0d9fa
commit ab8e888c69
1188 changed files with 14 additions and 330543 deletions

View File

@ -1,7 +0,0 @@
[run]
branch = True
source = heat,contrib
omit = */tests/*
[report]
ignore_errors = True

29
.gitignore vendored
View File

@ -1,29 +0,0 @@
*.pyc
*.swp
*~
build
dist
*.egg*
tags
*.log
heat-test.db
heat.sqlite
.venv
AUTHORS
ChangeLog
templates/cloudformation-examples
.tox
.coverage
.coverage.*
cover
.testrepository
.project
.pydevproject
doc/source/api/
etc/heat/heat.conf.sample
.idea
# integration tests requirements are auto-generated from stub file
heat_integrationtests/requirements.txt
# Files created by releasenotes build
releasenotes/build

View File

@ -1,4 +0,0 @@
[gerrit]
host=review.openstack.org
port=29418
project=openstack/heat.git

View File

@ -1,8 +0,0 @@
[DEFAULT]
test_command=
PYTHON=$(echo ${PYTHON:-python} | sed 's/--source heat//g')
START_AT=${TESTR_START_DIR:-.}
${PYTHON} -m subunit.run discover -s $START_AT -t . $LISTOPT $IDOPTION
if [ "$START_AT" = "." ]; then for plugin in $START_AT/contrib/*; do ${PYTHON} -m subunit.run discover -s $plugin $LISTOPT $IDOPTION; done; fi
test_id_option=--load-list $IDFILE
test_list_option=--list

View File

@ -1,16 +0,0 @@
If you would like to contribute to the development of OpenStack,
you must follow the steps in this page:
http://docs.openstack.org/infra/manual/developers.html
Once those steps have been completed, changes to OpenStack
should be submitted for review via the Gerrit tool, following
the workflow documented at:
http://docs.openstack.org/infra/manual/developers.html#development-workflow
Pull requests submitted through GitHub will be ignored.
Bugs should be filed on Launchpad, not GitHub:
https://bugs.launchpad.net/heat

View File

@ -1,55 +0,0 @@
Heat style commandments
=======================
- Step 1: Read the OpenStack style commandments
http://docs.openstack.org/developer/hacking/
- Step 2: Read on
Heat specific commandments
--------------------------
None so far
Creating unit tests
-------------------
For every new feature, unit tests should be created that both test and
(implicitly) document the usage of said features. If submitting a patch for a
bug that had no unit test, a new passing unit test should be added. If a
submitted bug fix does have a unit test, be sure to add a new one that fails
without the patch and passes with the patch.
For more information on creating unit tests and utilizing the testing
infrastructure in OpenStack Heat, please read heat/tests/testing-overview.txt.
Running tests
-------------
The testing system is based on a combination of tox and testr. The canonical
approach to running tests is to simply run the command `tox`. This will
create virtual environments, populate them with dependencies and run all of
the tests that OpenStack CI systems run. Behind the scenes, tox is running
`testr run --parallel`, but is set up such that you can supply any additional
testr arguments that are needed to tox. For example, you can run:
`tox -- --analyze-isolation` to cause tox to tell testr to add
--analyze-isolation to its argument list.
It is also possible to run the tests inside of a virtual environment
you have created, or it is possible that you have all of the dependencies
installed locally already. In this case, you can interact with the testr
command directly. Running `testr run` will run the entire test suite. `testr
run --parallel` will run it in parallel (this is the default incantation tox
uses.) More information about testr can be found at:
http://wiki.openstack.org/testr
Note that unit tests use a database if available. See
``tools/test-setup.sh`` on how to set up the databases the same way as
done in the OpenStack CI systems.
Heat Specific Commandments
--------------------------
- [Heat301] Use LOG.warning() rather than LOG.warn().
- [Heat302] Python 3: do not use dict.iteritems.
- [Heat303] Python 3: do not use dict.iterkeys.
- [Heat304] Python 3: do not use dict.itervalues.

176
LICENSE
View File

@ -1,176 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

14
README Normal file
View File

@ -0,0 +1,14 @@
This project is no longer maintained.
The contents of this repository are still available in the Git
source code management system. To see the contents of this
repository before it reached its end of life, please check out the
previous commit with "git checkout HEAD^1".
For ongoing work on maintaining OpenStack packages in the Debian
distribution, please see the Debian OpenStack packaging team at
https://wiki.debian.org/OpenStack/.
For any further questions, please email
openstack-dev@lists.openstack.org or join #openstack-dev on
Freenode.

View File

@ -1,63 +0,0 @@
========================
Team and repository tags
========================
.. image:: http://governance.openstack.org/badges/heat.svg
:target: http://governance.openstack.org/reference/tags/index.html
.. Change things from this point on
====
Heat
====
Heat is a service to orchestrate multiple composite cloud applications using
templates, through both an OpenStack-native REST API and a
CloudFormation-compatible Query API.
Why heat? It makes the clouds rise and keeps them there.
Getting Started
---------------
If you'd like to run from the master branch, you can clone the git repo:
git clone https://git.openstack.org/openstack/heat
* Wiki: http://wiki.openstack.org/Heat
* Developer docs: http://docs.openstack.org/developer/heat
* Template samples: https://git.openstack.org/cgit/openstack/heat-templates
* Agents: https://git.openstack.org/cgit/openstack/heat-agents
Python client
-------------
https://git.openstack.org/cgit/openstack/python-heatclient
References
----------
* http://docs.amazonwebservices.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html
* http://docs.amazonwebservices.com/AWSCloudFormation/latest/UserGuide/create-stack.html
* http://docs.amazonwebservices.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html
* http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=tosca
We have integration with
------------------------
* https://git.openstack.org/cgit/openstack/python-novaclient (instance)
* https://git.openstack.org/cgit/openstack/python-keystoneclient (auth)
* https://git.openstack.org/cgit/openstack/python-swiftclient (s3)
* https://git.openstack.org/cgit/openstack/python-neutronclient (networking)
* https://git.openstack.org/cgit/openstack/python-ceilometerclient (metering)
* https://git.openstack.org/cgit/openstack/python-aodhclient (alarming service)
* https://git.openstack.org/cgit/openstack/python-cinderclient (storage service)
* https://git.openstack.org/cgit/openstack/python-glanceclient (image service)
* https://git.openstack.org/cgit/openstack/python-troveclient (database as a Service)
* https://git.openstack.org/cgit/openstack/python-saharaclient (hadoop cluster)
* https://git.openstack.org/cgit/openstack/python-barbicanclient (key management service)
* https://git.openstack.org/cgit/openstack/python-designateclient (DNS service)
* https://git.openstack.org/cgit/openstack/python-magnumclient (container service)
* https://git.openstack.org/cgit/openstack/python-manilaclient (shared file system service)
* https://git.openstack.org/cgit/openstack/python-mistralclient (workflow service)
* https://git.openstack.org/cgit/openstack/python-zaqarclient (messaging service)
* https://git.openstack.org/cgit/openstack/python-monascaclient (monitoring service)
* https://git.openstack.org/cgit/openstack/python-senlinclient (clustering service)

View File

@ -1,237 +0,0 @@
# -*- coding: utf-8 -*-
#
# 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.
#
# heat documentation build config file, copied from:
# nova documentation build configuration file, created by
# sphinx-quickstart on Sat May 1 15:17:47 2010.
#
# This file is execfile()d with the current directory set to
# its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import os
import subprocess
import sys
import warnings
import openstackdocstheme
html_theme = 'openstackdocs'
html_theme_path = [openstackdocstheme.get_html_theme_path()]
html_theme_options = {
"sidebar_mode": "toc",
}
extensions = [
'os_api_ref',
]
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('../../'))
sys.path.insert(0, os.path.abspath('../'))
sys.path.insert(0, os.path.abspath('./'))
# -- General configuration ----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#
# source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Orchestration API Reference'
copyright = u'2010-present, OpenStack Foundation'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
from heat.version import version_info
# The full version, including alpha/beta/rc tags.
release = version_info.release_string()
# The short X.Y version.
version = version_info.version_string()
# Config logABug feature
giturl = u'http://git.openstack.org/cgit/openstack/heat/tree/api-ref/source'
# source tree
# html_context allows us to pass arbitrary values into the html template
html_context = {'bug_tag': 'api-ref',
'giturl': giturl,
'bug_project': 'heat'}
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'
# The reST default role (used for this markup: `text`) to use
# for all documents.
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
add_module_names = False
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# -- Options for man page output ----------------------------------------------
# Grouping the document tree for man pages.
# List of tuples 'sourcefile', 'target', u'title', u'Authors name', 'manual'
# -- Options for HTML output --------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
# html_theme_path = ["."]
# html_theme = '_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
# html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
# html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
# html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
# html_last_updated_fmt = '%b %d, %Y'
git_cmd = ["git", "log", "--pretty=format:'%ad, commit %h'", "--date=local",
"-n1"]
try:
html_last_updated_fmt = subprocess.check_output(git_cmd).decode('utf-8')
except Exception:
warnings.warn('Cannot get last updated time from git repository. '
'Not setting "html_last_updated_fmt".')
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
# html_additional_pages = {}
# If false, no module index is generated.
# html_use_modindex = True
# If false, no index is generated.
# html_use_index = True
# If true, the index is split into individual pages for each letter.
# html_split_index = False
# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'heatdoc'
# -- Options for LaTeX output -------------------------------------------------
# The paper size ('letter' or 'a4').
# latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
# latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass
# [howto/manual]).
latex_documents = [
('index', 'Heat.tex', u'OpenStack Orchestration API Documentation',
u'OpenStack Foundation', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False
# Additional stuff for the LaTeX preamble.
# latex_preamble = ''
# Documents to append as an appendix to all manuals.
# latex_appendices = []
# If false, no module index is generated.
# latex_use_modindex = True

View File

@ -1,24 +0,0 @@
..
Copyright 2010 OpenStack Foundation
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.
==========================
Orchestration Service APIs
==========================
.. toctree::
:maxdepth: 1
v1/index

View File

@ -1,45 +0,0 @@
.. -*- rst -*-
==========
Build info
==========
Show build information
======================
.. rest_method:: GET /v1/{tenant_id}/build_info
Shows build information for an Orchestration deployment.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 401
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- api: build_api
- engine: build_engine
Response Example
----------------
.. literalinclude:: samples/build-info-response.json
:language: javascript

View File

@ -1,214 +0,0 @@
.. -*- rst -*-
======
Events
======
The orchestration service provides APIs to check the events occurred on a
stack or a specific resource in a stack.
List stack events
=================
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/events
Lists events for a stack.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- resource_action: resource_action_query
- resource_status: resource_status_query
- resource_name: resource_name_query
- resource_type: resource_type_query
- limit: limit
- marker: marker
- sort_keys: sort_keys
- sort_dir: sort_dir
- nested_depth: nested_depth
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- event_time: event_time
- id: event_id
- links: event_links
- logical_resource_id: logical_resource_id
- physical_resource_id: physical_resource_id
- resource_name: resource_name
- resource_status: resource_status
- resource_status_reason: resource_status_reason
Response Example
----------------
.. literalinclude:: samples/events-list-response.json
:language: javascript
Find stack events
=================
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/events
Finds the canonical URL for the event list of a stack.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 302
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- location: location
- code: code
- message: message
- title: title
Response Example
----------------
.. literalinclude:: samples/events-find-response.json
:language: javascript
List resource events
====================
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/resources/{resource_name}/events
Lists events for a stack resource.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- resource_name: resource_name_url
- resource_action: resource_action_query
- resource_status: resource_status_query
- resource_name: resource_name_query
- resource_type: resource_type_query
- limit: limit
- marker: marker
- sort_keys: sort_keys
- sort_dir: sort_dir
- nested_depth: nested_depth
Response Example
----------------
.. literalinclude:: samples/events-list-response.json
:language: javascript
Show event details
==================
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/resources/{resource_name}/events/{event_id}
Shows details for an event.
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- resource_name: resource_name_url
- event_id: event_id_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- event: event
- event_time: event_time
- id: event_id
- links: event_links
- logical_resource_id: logical_resource_id
- physical_resource_id: physical_resource_id
- resource_name: resource_name
- resource_properties: resource_properties
- resource_status: resource_status
- resource_status_reason: resource_status_reason
- resource_type: resource_type
Response Example
----------------
.. literalinclude:: samples/event-show-response.json
:language: javascript

View File

@ -1,13 +0,0 @@
.. -*- rst -*-
=======================
General API information
=======================
Authenticated calls that target a known URI but that use an HTTP
method that the implementation does not support return a ``405
Method Not Allowed`` error code. In addition, the HTTP ``OPTIONS``
method is supported for each known URI. In both cases, the
``Allow`` response header indicates the HTTP methods that are
supported for the resource.

View File

@ -1,35 +0,0 @@
..
Copyright 2010 OpenStack Foundation
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.
:tocdepth: 2
============================
Orchestration Service API v1
============================
.. include:: build-info.inc
.. include:: general-info.inc
.. include:: versions.inc
.. include:: stacks.inc
.. include:: resources.inc
.. include:: stack-outputs.inc
.. include:: stack-snapshots.inc
.. include:: stack-actions.inc
.. include:: events.inc
.. include:: stack-templates.inc
.. include:: software-config.inc
.. include:: resource-types.inc
.. include:: services.inc

File diff suppressed because it is too large Load Diff

View File

@ -1,201 +0,0 @@
.. -*- rst -*-
==============
Resource Types
==============
List resource types
===================
.. rest_method:: GET /v1/{tenant_id}/resource_types
Lists all supported template resource types.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- name: type_name_query
- support_status: support_status_query
- version: type_version_query
- with_description: with_description
Response Parameters
-------------------
Note that the format of the response from this API varies when different query
parameters are specified. The default response has the following format:
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- resource_types: resource_types_simple
When ``with_description`` is specified, the response has the following format:
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- resource_types: resource_types_advanced
- resource_type: resource_type
- description: resource_type_description
Response Example
----------------
The following is an example of the simple response:
.. literalinclude:: samples/resource-types-list-response.json
:language: javascript
The following is an example of the response when ``with_description`` is
specified:
.. literalinclude:: samples/resource-types-list-advanced-response.json
:language: javascript
Show resource type template
===========================
.. rest_method:: GET /v1/{tenant_id}/resource_types/{type_name}/template
Shows the template representation for a resource type.
The returned template contains a single resource type. Each resource property
is mapped to a template parameter and each resource attribute is mapped to a
template output.
You can use these templates as a starting place for creating customized,
template-based resources or as examples of using the particular resource in
another template.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- type_name: type_name
- template_type: template_type_query
Response Parameters
-------------------
The format of the response varies when ``template_type`` is set to different
values. When it is set to ``cfn`` or omitted, the response has the following
format:
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- Description: Description
- Outputs: Outputs
- HeatTemplateFormatVersion: HeatTemplateFormatVersion
- Parameters: Parameters
- Resources: Resources
When the ``template_type`` is explicitly set to ``hot``, the response has the
following format:
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- heat_template_version: heat_template_version
- description: template_description
- outputs: template_outputs
- parameters: template_parameters
- resources: template_resources
Response Example
----------------
The following is a sample of the response when ``template_type`` is set to
``cfn`` or omitted:
.. literalinclude:: samples/resource-type-template-response.json
:language: javascript
The following is a sample of the response when ``template_type`` is explicitly
set to ``hot``:
.. literalinclude:: samples/resource-type-template-hot-response.json
:language: javascript
Show resource type schema
=========================
.. rest_method:: GET /v1/{tenant_id}/resource_types/{type_name}
Shows the interface schema for a resource type.
A schema describes the properties that can be set on the resource, their types,
constraints, descriptions, and default values. Additionally, the response
shows the resource attributes and their descriptions.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- type_name: type_name
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- attributes: attributes
- properties: properties
- resource_type: resource_type
- support_status: support_status
Response Example
----------------
.. literalinclude:: samples/resource-schema-response.json
:language: javascript

View File

@ -1,298 +0,0 @@
.. -*- rst -*-
===============
Stack resources
===============
Find stack resources
====================
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_identity}/resources
Finds the canonical URL for a resource list of a stack.
The canonical URL is returned for only non-deleted stacks. To fetch
the resource list for deleted stacks, use the following endpoint:
::
/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/resources
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 302
.. rest_status_code:: error status.yaml
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_identity: stack_identity
Response Parameter
------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- location: location
Response Example
----------------
.. literalinclude:: samples/stack-find-response.json
:language: javascript
List stack resources
====================
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/resources
Lists resources in a stack based on filtering parameters like resource
name, status, type, action, id and physical_resource_id. These parameters could
be used multiple times.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- type: resource_type_query
- status: resource_status_query
- name: resource_name_query
- action: resource_action_query
- id: resource_id_query
- physical_resource_id: physical_resource_id_query
- nested_depth: nested_depth
- with_detail: with_detail
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- resources: resources_list
- creation_time: creation_time
- links: links
- logical_resource_id: logical_resource_id
- physical_resource_id: physical_resource_id
- required_by: required_by
- resource_name: resource_name
- resource_status: resource_status
- resource_status_reason: resource_status_reason
- resource_type: resource_type
- updated_time: updated_time
Response Example
----------------
.. literalinclude:: samples/resources-list-response.json
:language: javascript
Show resource data
==================
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/resources/{resource_name}
Shows data for a resource.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- resource_name: resource_name_url
- with_attr: with_attr
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- resource: resource
- attributes: attributes
- creation_time: creation_time
- description: description
- links: resource_links
- logical_resource_id: logical_resource_id
- physical_resource_id: physical_resource_id
- required_by: required_by
- resource_name: resource_name
- resource_status: resource_status
- resource_status_reason: resource_status_reason
- resource_type: resource_type
- updated_time: updated_time
Response Example
----------------
.. literalinclude:: samples/resource-show-response.json
:language: javascript
Show resource metadata
======================
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/resources/{resource_name}/metadata
Shows metadata for a resource.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- resource_name: resource_name_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- metadata: metadata
Response Example
----------------
.. literalinclude:: samples/resource-metadata-response.json
:language: javascript
Send a signal to a resource
===========================
.. rest_method:: POST /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/resources/{resource_name}/signal
Sends a signal to a resource.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400: resource_signal
- 401
- 404
Request Parameters
------------------
The contents of the request body depends on the resource to which you send a
signal.
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- resource_name: resource_name_url
Response Example
----------------
This operation does not return a response body.
Mark a resource as unhealthy
============================
.. rest_method:: PATCH /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/resources/{resource_name_or_physical_id}
Mark the specified resource in the stack as unhealthy.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- resource_name_or_physical_id: resource_name_or_physical_id_url
- mark_unhealthy: mark_unhealthy
- resource_status_reason: resource_update_status_reason
Response Example
----------------
This operation does not return a response body.

View File

@ -1,8 +0,0 @@
{
"api": {
"revision": "{api_build_revision}"
},
"engine": {
"revision": "{engine_build_revision}"
}
}

View File

@ -1,28 +0,0 @@
{
"inputs": [
{
"default": null,
"type": "String",
"name": "foo",
"description": null
},
{
"default": null,
"type": "String",
"name": "bar",
"description": null
}
],
"group": "script",
"name": "a-config-we5zpvyu7b5o",
"outputs": [
{
"type": "String",
"name": "result",
"error_output": false,
"description": null
}
],
"config": "#!/bin/sh -x\necho \"Writing to /tmp/$bar\"\necho $foo > /tmp/$bar\necho -n \"The file /tmp/$bar contains `cat /tmp/$bar` for server $deploy_server_id during $deploy_action\" > $heat_outputs_path.result\necho \"Written to /tmp/$bar\"\necho \"Output to stderr\" 1>&2",
"options": null
}

View File

@ -1,32 +0,0 @@
{
"software_config": {
"creation_time": "2015-01-31T15:12:36Z",
"inputs": [
{
"default": null,
"type": "String",
"name": "foo",
"description": null
},
{
"default": null,
"type": "String",
"name": "bar",
"description": null
}
],
"group": "script",
"name": "a-config-we5zpvyu7b5o",
"outputs": [
{
"type": "String",
"name": "result",
"error_output": false,
"description": null
}
],
"options": null,
"config": "#!/bin/sh -x\necho \"Writing to /tmp/$bar\"\necho $foo > /tmp/$bar\necho -n \"The file /tmp/$bar contains `cat /tmp/$bar` for server $deploy_server_id during $deploy_action\" > $heat_outputs_path.result\necho \"Written to /tmp/$bar\"\necho \"Output to stderr\" 1>&2",
"id": "ddee7aca-aa32-4335-8265-d436b20db4f1"
}
}

View File

@ -1,32 +0,0 @@
{
"software_config": {
"inputs": [
{
"default": null,
"type": "String",
"name": "foo",
"description": null
},
{
"default": null,
"type": "String",
"name": "bar",
"description": null
}
],
"group": "script",
"name": "a-config-we5zpvyu7b5o",
"outputs": [
{
"type": "String",
"name": "result",
"error_output": false,
"description": null
}
],
"creation_time": "2015-01-31T15:12:36Z",
"id": "ddee7aca-aa32-4335-8265-d436b20db4f1",
"config": "#!/bin/sh -x\necho \"Writing to /tmp/$bar\"\necho $foo > /tmp/$bar\necho -n \"The file /tmp/$bar contains `cat /tmp/$bar` for server $deploy_server_id during $deploy_action\" > $heat_outputs_path.result\necho \"Written to /tmp/$bar\"\necho \"Output to stderr\" 1>&2",
"options": null
}
}

View File

@ -1,8 +0,0 @@
{
"software_configs": [{
"group": "script",
"name": "a-config-we5zpvyu7b5o",
"creation_time": "2015-01-31T15:12:36Z",
"id": "ddee7aca-aa32-4335-8265-d436b20db4f1",
}]
}

View File

@ -1,8 +0,0 @@
{
"status": "IN_PROGRESS",
"server_id": "ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5",
"config_id": "8da95794-2ad9-4979-8ae5-739ce314c5cd",
"stack_user_project_id": "c024bfada67845ddb17d2b0c0be8cd79",
"action": "CREATE",
"status_reason": "Deploy data available"
}

View File

@ -1,14 +0,0 @@
{
"software_deployment": {
"status": "IN_PROGRESS",
"server_id": "ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5",
"config_id": "8da95794-2ad9-4979-8ae5-739ce314c5cd",
"output_values": null,
"input_values": null,
"action": "CREATE",
"status_reason": "Deploy data available",
"id": "ef422fa5-719a-419e-a10c-72e3a367b0b8",
"creation_time": "2015-01-31T15:12:36Z",
"updated_time": "2015-01-31T15:18:21Z"
}
}

View File

@ -1,130 +0,0 @@
{
"metadata": [
{
"inputs": [
{
"default": null,
"type": "String",
"name": "foo",
"value": "fooooo",
"description": null
},
{
"default": null,
"type": "String",
"name": "bar",
"value": "baaaaa",
"description": null
},
{
"type": "String",
"name": "deploy_server_id",
"value": "ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5",
"description": "ID of the server being deployed to"
},
{
"type": "String",
"name": "deploy_action",
"value": "CREATE",
"description": "Name of the current action being deployed"
},
{
"type": "String",
"name": "deploy_stack_id",
"value": "a/9bd57090-8954-48ab-bab9-adf9e1ac70fc",
"description": "ID of the stack this deployment belongs to"
},
{
"type": "String",
"name": "deploy_resource_name",
"value": "deployment",
"description": "Name of this deployment resource in the stack"
},
{
"type": "String",
"name": "deploy_signal_id",
"value": "http://192.168.20.103:8000/v1/signal/arn%3Aopenstack%3Aheat%3A%3Ae2a84fbdaeb047ae8da4b503f3b69f1f%3Astacks%2Fa%2F9bd57090-8954-48ab-bab9-adf9e1ac70fc%2Fresources%2Fdeployment?Timestamp=2014-03-19T20%3A30%3A59Z&SignatureMethod=HmacSHA256&AWSAccessKeyId=ca3571413e4a49998d580215517b3685&SignatureVersion=2&Signature=w6Iu%2BNbg86mqwSOUf1GLuKPO7KaD82PiGpL4ig9Q1l4%3D",
"description": "ID of signal to use for signalling output values"
}
],
"group": "script",
"name": "a-config-we5zpvyu7b5o",
"outputs": [
{
"type": "String",
"name": "result",
"error_output": false,
"description": null
}
],
"options": null,
"creation_time": "2015-01-31T15:12:36Z",
"updated_time": "2015-01-31T15:18:21Z",
"config": "#!/bin/sh -x\necho \"Writing to /tmp/$bar\"\necho $foo > /tmp/$bar\necho -n \"The file /tmp/$bar contains `cat /tmp/$bar` for server $deploy_server_id during $deploy_action\" > $heat_outputs_path.result\necho \"Written to /tmp/$bar\"\necho \"Output to stderr\" 1>&2",
"id": "3d5ec2a8-7004-43b6-a7f6-542bdbe9d434"
},
{
"inputs": [
{
"default": null,
"type": "String",
"name": "foo",
"value": "fu",
"description": null
},
{
"default": null,
"type": "String",
"name": "bar",
"value": "barmy",
"description": null
},
{
"type": "String",
"name": "deploy_server_id",
"value": "ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5",
"description": "ID of the server being deployed to"
},
{
"type": "String",
"name": "deploy_action",
"value": "CREATE",
"description": "Name of the current action being deployed"
},
{
"type": "String",
"name": "deploy_stack_id",
"value": "a/9bd57090-8954-48ab-bab9-adf9e1ac70fc",
"description": "ID of the stack this deployment belongs to"
},
{
"type": "String",
"name": "deploy_resource_name",
"value": "other_deployment",
"description": "Name of this deployment resource in the stack"
},
{
"type": "String",
"name": "deploy_signal_id",
"value": "http://192.168.20.103:8000/v1/signal/arn%3Aopenstack%3Aheat%3A%3Ae2a84fbdaeb047ae8da4b503f3b69f1f%3Astacks%2Fa%2F9bd57090-8954-48ab-bab9-adf9e1ac70fc%2Fresources%2Fother_deployment?Timestamp=2014-03-19T20%3A30%3A59Z&SignatureMethod=HmacSHA256&AWSAccessKeyId=7b761482f8254946bcd3d5ccb36fe939&SignatureVersion=2&Signature=giMfv%2BhrAw6y%2FCMKQIQz2IhO5PkAj5%2BfP5YsL6rul3o%3D",
"description": "ID of signal to use for signalling output values"
}
],
"group": "script",
"name": "a-config-we5zpvyu7b5o",
"outputs": [
{
"type": "String",
"name": "result",
"error_output": false,
"description": null
}
],
"options": null,
"creation_time": "2015-01-31T16:14:13Z",
"updated_time": "2015-01-31T16:18:19Z",
"config": "#!/bin/sh -x\necho \"Writing to /tmp/$bar\"\necho $foo > /tmp/$bar\necho -n \"The file /tmp/$bar contains `cat /tmp/$bar` for server $deploy_server_id during $deploy_action\" > $heat_outputs_path.result\necho \"Written to /tmp/$bar\"\necho \"Output to stderr\" 1>&2",
"id": "8da95794-2ad9-4979-8ae5-739ce314c5cd"
}
]
}

View File

@ -1,14 +0,0 @@
{
"software_deployment": {
"status": "IN_PROGRESS",
"server_id": "ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5",
"config_id": "3d5ec2a8-7004-43b6-a7f6-542bdbe9d434",
"output_values": null,
"input_values": null,
"action": "CREATE",
"status_reason": "Deploy data available",
"id": "06e87bcc-33a2-4bce-aebd-533e698282d3",
"creation_time": "2015-01-31T15:12:36Z",
"updated_time": "2015-01-31T15:18:21Z"
}
}

View File

@ -1,10 +0,0 @@
{
"status": "COMPLETE",
"output_values": {
"deploy_stdout": "Writing to /tmp/baaaaa\nWritten to /tmp/baaaaa\n",
"deploy_stderr": "+ echo Writing to /tmp/baaaaa\n+ echo fooooo\n+ cat /tmp/baaaaa\n+ echo -n The file /tmp/baaaaa contains fooooo for server ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5 during CREATE\n+ echo Written to /tmp/baaaaa\n+ echo Output to stderr\nOutput to stderr\n",
"deploy_status_code": 0,
"result": "The file /tmp/baaaaa contains fooooo for server ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5 during CREATE"
},
"status_reason": "Outputs received"
}

View File

@ -1,19 +0,0 @@
{
"software_deployment": {
"status": "COMPLETE",
"server_id": "ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5",
"config_id": "3d5ec2a8-7004-43b6-a7f6-542bdbe9d434",
"output_values": {
"deploy_stdout": "Writing to /tmp/baaaaa\nWritten to /tmp/baaaaa\n",
"deploy_stderr": "+ echo Writing to /tmp/baaaaa\n+ echo fooooo\n+ cat /tmp/baaaaa\n+ echo -n The file /tmp/baaaaa contains fooooo for server ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5 during CREATE\n+ echo Written to /tmp/baaaaa\n+ echo Output to stderr\nOutput to stderr\n",
"deploy_status_code": 0,
"result": "The file /tmp/baaaaa contains fooooo for server ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5 during CREATE"
},
"input_values": null,
"action": "CREATE",
"status_reason": "Outputs received",
"id": "06e87bcc-33a2-4bce-aebd-533e698282d3",
"creation_time": "2015-01-31T15:12:36Z",
"updated_time": "2015-01-31T15:18:21Z"
}
}

View File

@ -1,21 +0,0 @@
{
"software_deployments": [
{
"status": "COMPLETE",
"server_id": "ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5",
"config_id": "8da95794-2ad9-4979-8ae5-739ce314c5cd",
"output_values": {
"deploy_stdout": "Writing to /tmp/barmy\nWritten to /tmp/barmy\n",
"deploy_stderr": "+ echo Writing to /tmp/barmy\n+ echo fu\n+ cat /tmp/barmy\n+ echo -n The file /tmp/barmy contains fu for server ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5 during CREATE\n+ echo Written to /tmp/barmy\n+ echo Output to stderr\nOutput to stderr\n",
"deploy_status_code": 0,
"result": "The file /tmp/barmy contains fu for server ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5 during CREATE"
},
"input_values": null,
"action": "CREATE",
"status_reason": "Outputs received",
"id": "ef422fa5-719a-419e-a10c-72e3a367b0b8",
"creation_time": "2015-01-31T15:12:36Z",
"updated_time": "2015-01-31T15:18:21Z"
}
]
}

View File

@ -1,33 +0,0 @@
{
"event": {
"event_time": "2015-06-25T14:59:53",
"id": "8db23e2e-72b2-47a2-9ed9-b52417f56e50",
"links": [
{
"href": "http://hostname/v1/1234/stacks/mystack/56789/resources/random_key_name/events/8db23e2e-72b2-47a2-9ed9-b52417f56e50",
"rel": "self"
},
{
"href": "http://hostname/v1/1234/stacks/mystack/56789/resources/random_key_name",
"rel": "resource"
},
{
"href": "http://hostname/v1/1234/stacks/mystack/56789",
"rel": "stack"
}
],
"logical_resource_id": "random_key_name",
"physical_resource_id": null,
"resource_name": "random_key_name",
"resource_properties": {
"character_classes": null,
"character_sequences": null,
"length": 8,
"salt": null,
"sequence": null
},
"resource_status": "CREATE_IN_PROGRESS",
"resource_status_reason": "state changed",
"resource_type": "OS::Heat::RandomString"
}
}

View File

@ -1,5 +0,0 @@
{
"code": "302 Found",
"message": "The resource was found at <a href=\"http://192.168.42.11:8004/v1/369166a68a3a49b78b4e138531556e55/stacks/s1/da778f26-6d25-4634-9531-d438188e48fd/events?sort_dir=asc\">http://192.168.42.11:8004/v1/369166a68a3a49b78b4e138531556e55/stacks/s1/da778f26-6d25-4634-9531-d438188e48fd/events?sort_dir=asc</a>;\nyou should be redirected automatically.\n\n",
"title": "Found"
}

View File

@ -1,50 +0,0 @@
{
"events": [
{
"event_time": "2014-07-23T08:14:47Z",
"id": "474bfdf0-a450-46ec-a78a-0c7faa404073",
"links": [
{
"href": "http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/aws_port/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/port/events/474bfdf0-a450-46ec-a78a-0c7faa404073",
"rel": "self"
},
{
"href": "http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/aws_port/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/port",
"rel": "resource"
},
{
"href": "http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/aws_port/db467ed1-50b5-4a3e-aeb1-396ff1d151c5",
"rel": "stack"
}
],
"logical_resource_id": "port",
"physical_resource_id": null,
"resource_name": "port",
"resource_status": "CREATE_FAILED",
"resource_status_reason": "NotFound: Subnet f8a699d0-3537-429e-87a5-6b5a8d0c2bf0 could not be found"
},
{
"event_time": "2014-07-23T08:14:47Z",
"id": "66fa95b6-e6f8-4f05-b1af-e828f5aba04c",
"links": [
{
"href": "http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/aws_port/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/port/events/66fa95b6-e6f8-4f05-b1af-e828f5aba04c",
"rel": "self"
},
{
"href": "http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/aws_port/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/port",
"rel": "resource"
},
{
"href": "http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/aws_port/db467ed1-50b5-4a3e-aeb1-396ff1d151c5",
"rel": "stack"
}
],
"logical_resource_id": "port",
"physical_resource_id": null,
"resource_name": "port",
"resource_status": "CREATE_IN_PROGRESS",
"resource_status_reason": "state changed"
}
]
}

View File

@ -1,6 +0,0 @@
{
"metadata": {
"some_key": "some_value",
"some_other_key": "some_other_value"
}
}

View File

@ -1,30 +0,0 @@
{
"attributes": {
"an_attribute": {
"description": "A runtime value of the resource."
}
},
"properties": {
"a_property": {
"constraints": [
{
"description": "Must be between 1 and 255 characters",
"length": {
"max": 255,
"min": 1
}
}
],
"description": "A resource description.",
"required": true,
"type": "string",
"update_allowed": false
}
},
"resource_type": "OS::Heat::AResourceName",
"support_status": {
"message": "A status message",
"status": "SUPPORTED",
"version": "2014.1"
}
}

View File

@ -1,27 +0,0 @@
{
"resource": {
"attributes": {
"value": "I9S20uIp"
},
"creation_time": "2015-06-25T14:59:53",
"description": "",
"links": [
{
"href": "http://hostname/v1/1234/stacks/mystack/629a32d0-ac4f-4f63-b58d-f0d047b1ba4c/resources/random_key_name",
"rel": "self"
},
{
"href": "http://hostname/v1/1234/stacks/mystack/629a32d0-ac4f-4f63-b58d-f0d047b1ba4c",
"rel": "stack"
}
],
"logical_resource_id": "random_key_name",
"physical_resource_id": "mystack-random_key_name-pmjmy5pks735",
"required_by": [],
"resource_name": "random_key_name",
"resource_status": "CREATE_COMPLETE",
"resource_status_reason": "state changed",
"resource_type": "OS::Heat::RandomString",
"updated_time": "2015-06-25T14:59:53"
}
}

View File

@ -1,57 +0,0 @@
{
"description": "Initial template of KeyPair",
"heat_template_version": "2016-10-14",
"outputs": {
"private_key": {
"description": "The private key if it has been saved.",
"value": "{\"get_attr\": [\"KeyPair\", \"private_key\"]}"
},
"public_key": {
"description": "The public key.",
"value": "{\"get_attr\": [\"KeyPair\", \"public_key\"]}"
},
"show": {
"description": "Detailed information about resource.",
"value": "{\"get_attr\": [\"KeyPair\", \"show\"]}"
}
},
"parameters": {
"name": {
"constraints": [
{
"length": {
"max": 255,
"min": 1
}
}
],
"description": "The name of the key pair.",
"type": "string"
},
"public_key": {
"description": "The optional public key. This allows users to supply the public key from a pre-existing key pair. If not supplied, a new key pair will be generated.",
"type": "string"
},
"save_private_key": {
"default": false,
"description": "True if the system should remember a generated private key; False otherwise.",
"type": "boolean"
}
},
"resources": {
"KeyPair": {
"properties": {
"name": {
"get_param": "name"
},
"public_key": {
"get_param": "public_key"
},
"save_private_key": {
"get_param": "save_private_key"
}
},
"type": "OS::Nova::KeyPair"
}
}
}

View File

@ -1,57 +0,0 @@
{
"Description": "Initial template of KeyPair",
"HeatTemplateFormatVersion": "2012-12-12",
"Outputs": {
"private_key": {
"Description": "The private key if it has been saved.",
"Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"private_key\"]}"
},
"public_key": {
"Description": "The public key.",
"Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"public_key\"]}"
},
"show": {
"Description": "Detailed information about resource.",
"Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"show\"]}"
}
},
"Parameters": {
"name": {
"Description": "The name of the key pair.",
"MaxLength": 255,
"MinLength": 1,
"Type": "String"
},
"public_key": {
"Description": "The optional public key. This allows users to supply the public key from a pre-existing key pair. If not supplied, a new key pair will be generated.",
"Type": "String"
},
"save_private_key": {
"AllowedValues": [
"True",
"true",
"False",
"false"
],
"Default": false,
"Description": "True if the system should remember a generated private key; False otherwise.",
"Type": "Boolean"
}
},
"Resources": {
"KeyPair": {
"Properties": {
"name": {
"Ref": "name"
},
"public_key": {
"Ref": "public_key"
},
"save_private_key": {
"Ref": "save_private_key"
}
},
"Type": "OS::Nova::KeyPair"
}
}
}

View File

@ -1,24 +0,0 @@
{
"resource_types": [
{
"description": "No description given",
"resource_type": "AWS::EC2::Instance"
},
{
"description": "Resource for defining which resources can be accessed by users.\n\nNOTE: Now this resource is actually associated with an AWS user resource,\nnot any OS:: resource though it is registered under the OS namespace below.\n\nResource for defining resources that users are allowed to access by the\nDescribeStackResource API.\n",
"resource_type": "OS::Heat::AccessPolicy"
},
{
"description": "A resource to manage scaling of `OS::Heat::AutoScalingGroup`.\n\n**Note** while it may incidentally support\n`AWS::AutoScaling::AutoScalingGroup` for now, please do not use it for that\npurpose and use `AWS::AutoScaling::ScalingPolicy` instead.\n\nResource to manage scaling for `OS::Heat::AutoScalingGroup`, i.e. define\nwhich metric should be scaled and scaling adjustment, set cooldown etc.\n",
"resource_type": "OS::Heat::ScalingPolicy"
},
{
"description": "Represents a child stack to allow composition of templates.",
"resource_type": "AWS::CloudFormation::Stack"
},
{
"description": "Heat Template Resource for Keystone Group.\n\nGroups are a container representing a collection of users. A group itself\nmust be owned by a specific domain, and hence all group names are not\nglobally unique, but only unique to their domain.\n",
"resource_type": "OS::Keystone::Group"
}
]
}

View File

@ -1,7 +0,0 @@
{
"resource_types": [
"AWS::EC2::Instance",
"OS::Heat::ScalingPolicy",
"AWS::CloudFormation::Stack"
]
}

View File

@ -1,25 +0,0 @@
{
"resources": [
{
"creation_time": "2015-06-25T14:59:53",
"links": [
{
"href": "http://hostname/v1/1234/stacks/mystack/629a32d0-ac4f-4f63-b58d-f0d047b1ba4c/resources/random_key_name",
"rel": "self"
},
{
"href": "http://hostname/v1/1234/stacks/mystack/629a32d0-ac4f-4f63-b58d-f0d047b1ba4c",
"rel": "stack"
}
],
"logical_resource_id": "random_key_name",
"physical_resource_id": "mystack-random_key_name-pmjmy5pks735",
"required_by": [],
"resource_name": "random_key_name",
"resource_status": "CREATE_COMPLETE",
"resource_status_reason": "state changed",
"resource_type": "OS::Heat::RandomString",
"updated_time": "2015-06-25T14:59:53"
}
]
}

View File

@ -1,30 +0,0 @@
{
"services": [
{
"binary": "heat-engine",
"created_at": "2015-02-03T05:55:59.000000",
"deleted_at": null,
"engine_id": "9d9242c3-4b9e-45e1-9e74-7615fbf20e5d",
"host": "engine-1",
"hostname": "mrkanag",
"id": "e1908f44-42f9-483f-b778-bc814072c33d",
"report_interval": 60,
"status": "up",
"topic": "engine",
"updated_at": "2015-02-03T05:57:59.000000"
},
{
"binary": "heat-engine",
"created_at": "2015-02-03T06:03:14.000000",
"deleted_at": null,
"engine_id": "2d2434bf-adb6-4453-9c6b-b22fb8bd2306",
"host": "engine",
"hostname": "mrkanag",
"id": "582b5657-6db7-48ad-8483-0096350faa21",
"report_interval": 60,
"status": "down",
"topic": "engine",
"updated_at": "2015-02-03T06:09:55.000000"
}
]
}

View File

@ -1,73 +0,0 @@
{
"action": "CREATE",
"environment": {},
"files": {},
"id": "16934ca3-40e0-4fb2-a289-a700662ec05a",
"name": "g",
"project_id": "369166a68a3a49b78b4e138531556e55",
"resources": {
"server": {
"status": "COMPLETE",
"name": "server",
"resource_data": {},
"resource_id": "39d5dad7-7d7a-4cc8-bd84-851e9e2ff4ea",
"action": "CREATE",
"type": "OS::Nova::Server",
"metadata": {}
}
},
"stack_user_project_id": "9bbd353467bc4f069a3692d223a48aac",
"status": "COMPLETE",
"tags": null,
"template": {
"outputs": {
"instance_ip": {
"value": {
"str_replace": {
"params": {
"username": "ec2-user",
"hostname": {
"get_attr": [
"server",
"first_address"
]
}
},
"template": "ssh username@hostname"
}
}
}
},
"heat_template_version": "2013-05-23",
"resources": {
"server": {
"type": "OS::Nova::Server",
"properties": {
"key_name": {
"get_param": "key_name"
},
"image": {
"get_param": "image"
},
"flavor": {
"get_param": "flavor"
}
}
}
},
"parameters": {
"key_name": {
"default": "heat_key",
"type": "string"
},
"image": {
"default": "fedora-amd64",
"type": "string"
},
"flavor": {
"default": "m1.small",
"type": "string"
}
}
}
}

View File

@ -1,3 +0,0 @@
{
"cancel_update": null
}

View File

@ -1,3 +0,0 @@
{
"check": null
}

View File

@ -1,3 +0,0 @@
{
"resume": null
}

View File

@ -1,3 +0,0 @@
{
"suspend": null
}

View File

@ -1,33 +0,0 @@
{
"adopt_stack_data": {
"action": "CREATE",
"id": "bxxxxx4-0xx2-4xx1-axx6-exxxxxxxc",
"name": "teststack",
"resources": {
"MyServer": {
"action": "CREATE",
"metadata": {},
"name": "MyServer",
"resource_data": {},
"resource_id": "cxxxx3-dxx3-4xx-bxx2-3xxxxxxxxa",
"status": "COMPLETE",
"type": "OS::Trove::Instance"
}
},
"status": "COMPLETE",
"template": {
"heat_template_version": "2013-05-23",
"resources": {
"MyServer": {
"type": "OS::Trove::Instance",
"properties": {
"flavor": "m1.small",
"size": 10
}
}
}
}
},
"stack_name": "new_stack",
"timeout_mins": 30
}

View File

@ -1,32 +0,0 @@
{
"files": {},
"disable_rollback": true,
"parameters": {
"flavor": "m1.heat"
},
"stack_name": "teststack",
"template": {
"heat_template_version": "2013-05-23",
"description": "Simple template to test heat commands",
"parameters": {
"flavor": {
"default": "m1.tiny",
"type": "string"
}
},
"resources": {
"hello_world": {
"type": "OS::Nova::Server",
"properties": {
"key_name": "heat_key",
"flavor": {
"get_param": "flavor"
},
"image": "40be8d1a-3eb9-40de-8abd-43237517384f",
"user_data": "#!/bin/bash -xv\necho \"hello world\" &gt; /root/hello-world.txt\n"
}
}
}
},
"timeout_mins": 60
}

View File

@ -1,11 +0,0 @@
{
"stack": {
"id": "3095aefc-09fb-4bc7-b1f0-f21a304e864c",
"links": [
{
"href": "http://192.168.123.200:8004/v1/eb1c63a4f77141548385f113a28f0f52/stacks/teststack/3095aefc-09fb-4bc7-b1f0-f21a304e864c",
"rel": "self"
}
]
}
}

View File

@ -1,9 +0,0 @@
{
"encrypted_param_names": [],
"event_sinks": [],
"parameter_defaults": {},
"parameters": {},
"resource_registry": {
"resources": {}
}
}

View File

@ -1,60 +0,0 @@
{
"action": "SUSPEND",
"environment": {
"event_sinks": [],
"parameter_defaults": {},
"parameters": {},
"resource_registry": {
"resources": {}
}
},
"files": {},
"id": "da778f26-6d25-4634-9531-d438188e48fd",
"name": "s1",
"project_id": "369166a68a3a49b78b4e138531556e55",
"resources": {
"random": {
"action": "SUSPEND",
"metadata": {},
"name": "random",
"resource_data": {
"value": "wCPWWoGJH5SZKtNFAgqGcbiWokCkRgam"
},
"resource_id": "s1-random-pzuzs6pbjhho",
"status": "COMPLETE",
"type": "OS::Heat::RandomString"
}
},
"stack_user_project_id": "a4e6fd443f5b4d4694331ff441ad2397",
"status": "COMPLETE",
"tags": null,
"template": {
"heat_template_version": "2014-10-16",
"outputs": {
"result": {
"value": {
"get_attr": [
"random",
"value"
]
}
}
},
"parameters": {
"str_length": {
"default": 32,
"type": "number"
}
},
"resources": {
"random": {
"properties": {
"length": {
"get_param": "str_length"
}
},
"type": "OS::Heat::RandomString"
}
}
}
}

View File

@ -1,3 +0,0 @@
{
"file:///home/username/hello.sh": "#!/bin/sh\necho hello\n"
}

View File

@ -1,5 +0,0 @@
{
"code": "302 Found",
"message": "The resource was found at <a href=\"http://192.168.42.11:8004/v1/369166a68a3a49b78b4e138531556e55/stacks/s2/321c4eed-c87f-4cea-8288-9238f3b92e63\">http://192.168.42.11:8004/v1/369166a68a3a49b78b4e138531556e55/stacks/s2/321c4eed-c87f-4cea-8288-9238f3b92e63</a>;\nyou should be redirected automatically.\n\n",
"title": "Found"
}

View File

@ -1,5 +0,0 @@
{
"code": "302 Found",
"message": "The resource was found at <a href=\"http://192.168.42.11:8004/v1/369166a68a3a49b78b4e138531556e55/stacks/s1/da778f26-6d25-4634-9531-d438188e48fd\">http://192.168.42.11:8004/v1/369166a68a3a49b78b4e138531556e55/stacks/s1/da778f26-6d25-4634-9531-d438188e48fd</a>;\nyou should be redirected automatically.\n\n",
"title": "Found"
}

View File

@ -1,8 +0,0 @@
{
"output": {
"output_key": "output_name",
"output_value": "output_value",
"description": "output description",
"output_error": "error message"
}
}

View File

@ -1,8 +0,0 @@
{
"outputs": [
{
"output_key": "output name",
"description": "output description"
}
]
}

View File

@ -1,171 +0,0 @@
{
"stack": {
"capabilities": [],
"creation_time": "2015-01-31T15:12:36Z",
"deletion_time": null,
"description": "HOT template for Nova Server resource.\n",
"disable_rollback": true,
"id": "None",
"links": [
{
"href": "http://192.168.122.102:8004/v1/6e18cc2bdbeb48a5basad2dc499f6804/stacks/test_stack/None",
"rel": "self"
}
],
"notification_topics": [],
"outputs": [],
"parameters": {
"OS::project_id": "6e18cc2bdbeb48a5basad2dc499f6804",
"OS::stack_id": "None",
"OS::stack_name": "teststack",
"admin_user": "cloud-user",
"flavor": "m1.small",
"image": "F20-cfg",
"key_name": "heat_key",
"server_name": "MyServer"
},
"parent": null,
"resources": [
{
"attributes": {},
"description": "",
"metadata": {},
"physical_resource_id": "",
"properties": {
"description": "Ping and SSH",
"name": "the_sg",
"rules": [
{
"direction": "ingress",
"ethertype": "IPv4",
"port_range_max": null,
"port_range_min": null,
"protocol": "icmp",
"remote_group_id": null,
"remote_ip_prefix": null,
"remote_mode": "remote_ip_prefix"
},
{
"direction": "ingress",
"ethertype": "IPv4",
"port_range_max": 65535,
"port_range_min": 1,
"protocol": "tcp",
"remote_group_id": null,
"remote_ip_prefix": null,
"remote_mode": "remote_ip_prefix"
},
{
"direction": "ingress",
"ethertype": "IPv4",
"port_range_max": 65535,
"port_range_min": 1,
"protocol": "udp",
"remote_group_id": null,
"remote_ip_prefix": null,
"remote_mode": "remote_ip_prefix"
}
]
},
"required_by": [
"server1"
],
"resource_action": "INIT",
"resource_identity": {
"path": "/resources/the_sg_res",
"stack_id": "None",
"stack_name": "teststack",
"tenant": "6e18cc2bdbeb48a5b3cad2dc499f6804"
},
"resource_name": "the_sg_res",
"resource_status": "COMPLETE",
"resource_status_reason": "",
"resource_type": "OS::Neutron::SecurityGroup",
"stack_identity": {
"path": "",
"stack_id": "None",
"stack_name": "teststack",
"tenant": "6e18cc2bdbeb48a5b3cad2dc499f6804"
},
"stack_name": "teststack",
"updated_time": "2015-01-31T15:12:36Z"
},
{
"attributes": {
"accessIPv4": "",
"accessIPv6": "",
"addresses": "",
"console_urls": "",
"first_address": "",
"instance_name": "",
"name": "MyServer",
"networks": "",
"show": ""
},
"description": "",
"metadata": {},
"physical_resource_id": "",
"properties": {
"admin_pass": null,
"admin_user": "cloud-user",
"availability_zone": null,
"block_device_mapping": null,
"config_drive": null,
"diskConfig": null,
"flavor": "m1.small",
"flavor_update_policy": "RESIZE",
"image": "F20-cfg",
"image_update_policy": "REPLACE",
"key_name": "heat_key",
"metadata": {
"ha_stack": "None"
},
"name": "MyServer",
"networks": [
{
"fixed_ip": null,
"network": "private",
"port": null,
"uuid": null
}
],
"personality": {},
"reservation_id": null,
"scheduler_hints": null,
"security_groups": [
"None"
],
"software_config_transport": "POLL_SERVER_CFN",
"user_data": "",
"user_data_format": "HEAT_CFNTOOLS"
},
"required_by": [],
"resource_action": "INIT",
"resource_identity": {
"path": "/resources/hello_world",
"stack_id": "None",
"stack_name": "teststack",
"tenant": "6e18cc2bdbeb48a3433cad2dc499sdf32234"
},
"resource_name": "hello_world",
"resource_status": "COMPLETE",
"resource_status_reason": "",
"resource_type": "OS::Nova::Server",
"stack_identity": {
"path": "",
"stack_id": "None",
"stack_name": "teststack",
"tenant": "6e18cc2bdbeb48a3433cad2dc499sdf32234"
},
"stack_name": "teststack",
"updated_time": "2015-01-31T15:12:36Z"
}
],
"stack_name": "test_stack",
"stack_owner": null,
"tags": null,
"template_description": "HOT template for Nova Server resource.\n",
"timeout_mins": null,
"updated_time": null
}
}

View File

@ -1,33 +0,0 @@
{
"stack": {
"capabilities": [],
"creation_time": "2014-06-03T20:59:46Z",
"deletion_time": null,
"description": "sample stack",
"disable_rollback": true,
"id": "3095aefc-09fb-4bc7-b1f0-f21a304e864c",
"links": [
{
"href": "http://192.168.123.200:8004/v1/eb1c63a4f77141548385f113a28f0f52/stacks/simple_stack/3095aefc-09fb-4bc7-b1f0-f21a304e864c",
"rel": "self"
}
],
"notification_topics": [],
"outputs": [],
"parameters": {
"OS::project_id": "3ab5b02f-a01f-4f95-afa1-e254afc4a435",
"OS::stack_id": "3095aefc-09fb-4bc7-b1f0-f21a304e864c",
"OS::stack_name": "simple_stack"
},
"parent": null,
"stack_name": "simple_stack",
"stack_owner": "simple_username",
"stack_status": "CREATE_COMPLETE",
"stack_status_reason": "Stack CREATE completed successfully",
"stack_user_project_id": "65728b74-cfe7-4f17-9c15-11d4f686e591",
"tags": null,
"template_description": "sample stack",
"timeout_mins": null,
"updated_time": null
}
}

View File

@ -1,3 +0,0 @@
{
"name": "vol_snapshot"
}

View File

@ -1,8 +0,0 @@
{
"id": "13c3a4b5-0585-440e-85a4-6f96b20e7a78",
"name": "vol_snapshot",
"status": "IN_PROGRESS",
"status_reason": null,
"data": null,
"creation_time": "2015-09-01T20:57:55Z"
}

View File

@ -1,5 +0,0 @@
{
"code": "202 Accepted",
"message": "The request is accepted for processing.<br /><br />\n\n\n",
"title": "Accepted"
}

View File

@ -1,47 +0,0 @@
{
"snapshot": {
"id": "7c4e1ef4-bf1b-41ab-a0c8-ce01f4ffdfa1",
"name": "vol_snapshot",
"status": "COMPLETE",
"status_reason": "Stack SNAPSHOT completed successfully",
"creation_time": "2015-08-04T20:57:55Z",
"data": {
"status": "COMPLETE",
"name": "stack_vol1",
"stack_user_project_id": "fffa11067b1c48129ddfb78fba2bf09f",
"environment": {
"parameters": {},
"resource_registry": {
"resources": {}
}
},
"template": {
"heat_template_version": "2013-05-23",
"resources": {
"volume": {
"type": "OS::Cinder::Volume",
"properties": {
"size": 1
}
}
}
},
"action": "SNAPSHOT",
"project_id": "ecdb08032cd042179692a1b148f6565e",
"id": "656452c2-e151-40da-8704-c844e69b485c",
"resources": {
"volume": {
"status": "COMPLETE",
"name": "volume",
"resource_data": {
"backup_id": "99108cf8-398f-461b-a043-bdceb7c9f572"
},
"resource_id": "3ab8cf79-807b-4c40-b743-0655f91e072f",
"action": "SNAPSHOT",
"type": "OS::Cinder::Volume",
"metadata": {}
}
}
}
}
}

View File

@ -1,12 +0,0 @@
{
"snapshots": [
{
"id": "7c4e1ef4-bf1b-41ab-a0c8-ce01f4ffdfa1",
"name": "vol_snapshot",
"status": "IN_PROGRESS",
"status_reason": null,
"creation_time": "2015-08-04T20:57:55Z",
"data": null
}
]
}

View File

@ -1,67 +0,0 @@
{
"unchanged": [
{
"updated_time": "datetime",
"resource_name": "",
"physical_resource_id": "{resource id or ''}",
"resource_action": "CREATE",
"resource_status": "COMPLETE",
"resource_status_reason": "",
"resource_type": "restype",
"stack_identity": "{stack_id}",
"stack_name": "{stack_name}"
}
],
"updated": [
{
"updated_time": "datetime",
"resource_name": "",
"physical_resource_id": "{resource id or ''}",
"resource_action": "CREATE",
"resource_status": "COMPLETE",
"resource_status_reason": "",
"resource_type": "restype",
"stack_identity": "{stack_id}",
"stack_name": "{stack_name}"
}
],
"replaced": [
{
"updated_time": "datetime",
"resource_name": "",
"physical_resource_id": "{resource id or ''}",
"resource_action": "CREATE",
"resource_status": "COMPLETE",
"resource_status_reason": "",
"resource_type": "restype",
"stack_identity": "{stack_id}",
"stack_name": "{stack_name}"
}
],
"added": [
{
"updated_time": "datetime",
"resource_name": "",
"physical_resource_id": "{resource id or ''}",
"resource_action": "CREATE",
"resource_status": "COMPLETE",
"resource_status_reason": "",
"resource_type": "restype",
"stack_identity": "{stack_id}",
"stack_name": "{stack_name}"
}
],
"deleted": [
{
"updated_time": "datetime",
"resource_name": "",
"physical_resource_id": "{resource id or ''}",
"resource_action": "CREATE",
"resource_status": "COMPLETE",
"resource_status_reason": "",
"resource_type": "restype",
"stack_identity": "{stack_id}",
"stack_name": "{stack_name}"
}
]
}

View File

@ -1,28 +0,0 @@
{
"template": {
"heat_template_version": "2013-05-23",
"description": "Create a simple stack",
"parameters": {
"flavor": {
"default": "m1.tiny",
"type": "string"
}
},
"resources": {
"hello_world": {
"type": "OS::Nova::Server",
"properties": {
"key_name": "heat_key",
"flavor": {
"get_param": "flavor"
},
"image": "40be8d1a-3eb9-40de-8abd-43237517384f",
"user_data": "#!/bin/bash -xv\necho \"hello world\" > /root/hello-world.txt\n"
}
}
}
},
"parameters": {
"flavor": "m1.small"
}
}

View File

@ -1,5 +0,0 @@
{
"code": "202 Accepted",
"message": "The request is accepted for processing.<br /><br />\n\n\n",
"title": "Accepted"
}

View File

@ -1,24 +0,0 @@
{
"stacks": [
{
"creation_time": "2014-06-03T20:59:46Z",
"deletion_time": null,
"description": "sample stack",
"id": "3095aefc-09fb-4bc7-b1f0-f21a304e864c",
"links": [
{
"href": "http://192.168.123.200:8004/v1/eb1c63a4f77141548385f113a28f0f52/stacks/simple_stack/3095aefc-09fb-4bc7-b1f0-f21a304e864c",
"rel": "self"
}
],
"parent": null,
"stack_name": "simple_stack",
"stack_owner": null,
"stack_status": "CREATE_COMPLETE",
"stack_status_reason": "Stack CREATE completed successfully",
"stack_user_project_id": "71510cbd459a49ac989ca1055de7038b",
"tags": null,
"updated_time": null
}
]
}

View File

@ -1,44 +0,0 @@
{
"template_functions": [
{
"functions": "Fn::Select",
"description": "A function for selecting an item from a list or map."
},
{
"functions": "repeat",
"description": "A function for iterating over a list of items."
},
{
"functions": "resource_facade",
"description": "A function for retrieving data in a parent provider template."
},
{
"functions": "list_join",
"description": "A function for joining strings."
},
{
"functions": "str_replace",
"description": "A function for performing string substitutions."
},
{
"functions": "get_attr",
"description": "A function for resolving resource attributes."
},
{
"functions": "get_param",
"description": "A function for resolving parameter references."
},
{
"functions": "get_file",
"description": "A function for including a file inline."
},
{
"functions": "digest",
"description": "A function for performing digest operations."
},
{
"functions": "get_resource",
"description": "A function for resolving resource references."
}
]
}

View File

@ -1,28 +0,0 @@
{
"description": "Hello world HOT template that just defines a single server. Contains just base features to verify base HOT support.\n",
"heat_template_version": "2013-05-23",
"outputs": {
"foo": {
"description": "Show foo parameter value",
"value": {
"get_param": "foo"
}
}
},
"parameters": {
"foo": {
"default": "secret",
"description": "Name of an existing key pair to use for the server",
"hidden": true,
"type": "string"
}
},
"resources": {
"random_key_name": {
"properties": {
"length": 8
},
"type": "OS::Heat::RandomString"
}
}
}

View File

@ -1,3 +0,0 @@
{
"template_url": "/PATH_TO_HEAT_TEMPLATES/WordPress_Single_Instance.template"
}

View File

@ -1,41 +0,0 @@
{
"Description": "A template that provides a single server instance.",
"Parameters": {
"server-size": {
"default": "1GB Standard Instance",
"description": "Server size",
"type": "String",
"constraints": [
{
"allowed_values": [
"512MB Standard Instance",
"1GB Standard Instance",
"4GB Standard Instance",
"8GB Standard Instance"
],
"description": "Must be a valid server size."
}
]
},
"key_name": {
"description": "Keypair name for SSH access to the server",
"required": true,
"type": "String"
},
"server_name": {
"default": "My server",
"description": "My server",
"type": "String"
}
},
"ParameterGroups": [
{
"label": "Parameter groups",
"description": "My parameter groups",
"parameters": [
"param_name-1",
"param_name-2"
]
}
]
}

View File

@ -1,49 +0,0 @@
{
"template_versions": [
{
"aliases": [],
"version": "AWSTemplateFormatVersion.2010-09-09",
"type": "cfn"
},
{
"aliases": [],
"version": "HeatTemplateFormatVersion.2012-12-12",
"type": "cfn"
},
{
"aliases": [],
"version": "heat_template_version.2013-05-23",
"type": "hot"
},
{
"aliases": [],
"version": "heat_template_version.2014-10-16",
"type": "hot"
},
{
"aliases": [],
"version": "heat_template_version.2015-04-30",
"type": "hot"
},
{
"aliases": [],
"version": "heat_template_version.2015-10-15",
"type": "hot"
},
{
"aliases": [],
"version": "heat_template_version.2016-04-08",
"type": "hot"
},
{
"aliases": ["heat_template_version.newton"],
"version": "heat_template_version.2016-10-14",
"type": "hot"
},
{
"aliases": ["heat_template_version.ocata"],
"version": "heat_template_version.2017-02-24",
"type": "hot"
}
]
}

View File

@ -1,14 +0,0 @@
{
"versions": [
{
"status": "CURRENT",
"id": "v1.0",
"links": [
{
"href": "http://23.253.228.211:8000/v1/",
"rel": "self"
}
]
}
]
}

View File

@ -1,65 +0,0 @@
.. -*- rst -*-
==============
Manage service
==============
Show orchestration engine status
================================
.. rest_method:: GET /v1/{tenant_id}/services
Enables administrative users to view details for all orchestration engines.
Orchestration engine details include engine id, binary, topic name, host,
report interval, last updated time, health status, and host name.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 403
- 503
Troubleshooting
- A ``503`` error code indicates that the heat engines are not operational.
Run the ``heat-manage service list`` command or contact your cloud provider
to determine why the heat engines are not operational.
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- services: services
- binary: binary
- created_at: created_at
- deleted_at: deleted_at
- engine_id: engine_id
- host: host
- hostname: hostname
- id: engine_record_id
- report_interval: report_interval
- status: engine_status
- topic: topic
- updated_at: updated_at
Response Example
----------------
.. literalinclude:: samples/services-list-response.json
:language: javascript

View File

@ -1,513 +0,0 @@
.. -*- rst -*-
======================
Software configuration
======================
Create configuration
====================
.. rest_method:: POST /v1/{tenant_id}/software_configs
Creates a software configuration.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- inputs: inputs
- group: group
- name: config_name
- outputs: outputs
- config: config
- options: options
- tenant_id: tenant_id
Request Example
---------------
.. literalinclude:: samples/config-create-request.json
:language: javascript
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- id: config_id
- inputs: inputs
- group: group
- name: config_name
- outputs: outputs
- creation_time: creation_time
- updated_time: updated_time
- config: config
- options: options
- software_config: software_config
Response Example
----------------
.. literalinclude:: samples/config-create-response.json
:language: javascript
List configs
============
.. rest_method:: GET /v1/{tenant_id}/software_configs
Lists all available software configurations.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- limit: limit
- marker: marker
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- creation_time: creation_time
- group: group
- id: config_id
- name: config_name
- software_configs: software_configs
Response Example
----------------
.. literalinclude:: samples/configs-list-response.json
:language: javascript
Show configuration details
==========================
.. rest_method:: GET /v1/{tenant_id}/software_configs/{config_id}
Shows details for a software configuration.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- config_id: config_id_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- config: config
- creation_time: creation_time
- group: group
- id: config_id
- inputs: inputs
- name: config_name
- options: options
- outputs: outputs
- software_config: software_config
Response Example
----------------
.. literalinclude:: samples/config-show-response.json
:language: javascript
Delete config
=============
.. rest_method:: DELETE /v1/{tenant_id}/software_configs/{config_id}
Deletes a software configuration.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 204
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- config_id: config_id_url
Create deployment
=================
.. rest_method:: POST /v1/{tenant_id}/software_deployments
Creates a software deployment.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- action: deployment_action
- config_id: deployment_config_id
- input_values: input_values
- server_id: server_id
- stack_user_project_id: stack_user_project_id
- status: deployment_status
- status_reason: deployment_status_reason
Request Example
---------------
.. literalinclude:: samples/deployment-create-request.json
:language: javascript
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- action: deployment_action
- config_id: deployment_config_id
- creation_time: creation_time
- id: deployment_id
- input_values: input_values
- output_values: deployment_output_values
- server_id: server_id
- software_deployment: software_deployment
- status: deployment_status
- status_reason: deployment_status_reason
- updated_time: deployment_updated_time
Response Example
----------------
.. literalinclude:: samples/deployment-create-response.json
:language: javascript
List deployments
================
.. rest_method:: GET /v1/{tenant_id}/software_deployments
Lists all available software deployments.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- server_id: deployment_server_id_query
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- action: deployment_action
- config_id: deployment_config_id
- creation_time: creation_time
- id: deployment_id
- input_values: input_values
- output_values: deployment_output_values
- server_id: server_id
- software_deployments: software_deployments
- status: deployment_status
- status_reason: deployment_status_reason
- updated_time: deployment_updated_time
Response Example
----------------
.. literalinclude:: samples/deployments-list-response.json
:language: javascript
Show deployment details
=======================
.. rest_method:: GET /v1/{tenant_id}/software_deployments/{deployment_id}
Shows details for a software deployment.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- deployment_id: deployment_id_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- action: deployment_action
- config_id: deployment_config_id
- creation_time: creation_time
- id: deployment_id
- input_values: input_values
- output_values: deployment_output_values
- server_id: server_id
- software_deployment: software_deployment
- status: deployment_status
- status_reason: deployment_status_reason
- updated_time: deployment_updated_time
Response Example
----------------
.. literalinclude:: samples/deployment-show-response.json
:language: javascript
Update deployment
=================
.. rest_method:: PUT /v1/{tenant_id}/software_deployments/{deployment_id}
Updates a software deployment.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- deployment_id: deployment_id_url
- action: deployment_action
- config_id: deployment_config_id
- input_values: input_values
- output_values: deployment_output_values
- status: deployment_status
- status_reason: deployment_status_reason
Request Example
---------------
.. literalinclude:: samples/deployment-update-request.json
:language: javascript
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- action: deployment_action
- config_id: deployment_config_id
- creation_time: creation_time
- id: deployment_id
- input_values: input_values
- output_values: deployment_output_values
- server_id: server_id
- software_deployments: software_deployments
- status: deployment_status
- status_reason: deployment_status_reason
- updated_time: deployment_updated_time
Response Example
----------------
.. literalinclude:: samples/deployment-update-response.json
:language: javascript
Delete deployment
=================
.. rest_method:: DELETE /v1/{tenant_id}/software_deployments/{deployment_id}
Deletes a software deployment.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 204
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- deployment_id: deployment_id_url
- tenant_id: tenant_id
Show server configuration metadata
==================================
.. rest_method:: GET /v1/{tenant_id}/software_deployments/metadata/{server_id}
Shows the deployment configuration metadata for a server.
Use the ``group`` property to specify the configuration hook to
which the pass the metadata item.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- server_id: deployment_server_id_url
- tenant_id: tenant_id
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- config: config
- creation_time: creation_time
- group: group
- id: config_id
- inputs: inputs
- metadata: deployment_metadata
- name: config_name
- options: options
- outputs: outputs
- updated_time: updated_time
Response Example
----------------
.. literalinclude:: samples/deployment-metadata-response.json
:language: javascript

View File

@ -1,203 +0,0 @@
.. -*- rst -*-
=============
Stack actions
=============
Performs non-lifecycle operations on the stack. Specify the action in the
request body.
Suspend stack
=============
.. rest_method:: POST /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions
Suspends a stack.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- suspend: suspend
Request Example
---------------
.. literalinclude:: samples/stack-action-suspend-request.json
:language: javascript
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
Response Example
----------------
This operation does not return a response body.
Resume stack
============
.. rest_method:: POST /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions
Resumes a suspended stack.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- resume: resume
Request Example
---------------
.. literalinclude:: samples/stack-action-resume-request.json
:language: javascript
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
Response Example
----------------
This operation does not return a response body.
Cancel stack update
===================
.. rest_method:: POST /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions
Cancels a currently running update of a stack.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- cancel_update: cancel_update
Request Example
---------------
.. literalinclude:: samples/stack-action-cancel-update-request.json
:language: javascript
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
Response Example
----------------
This operation does not return a response body.
Check stack resources
=====================
.. rest_method:: POST /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions
Checks whether the resources are in expected states for a stack.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- check: check
Request Example
---------------
.. literalinclude:: samples/stack-action-check-request.json
:language: javascript
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
Response Example
----------------
This operation does not return a response body.

View File

@ -1,99 +0,0 @@
.. -*- rst -*-
=============
Stack Outputs
=============
List outputs
============
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/outputs
Lists outputs for a stack.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- outputs: stack_outputs
- output_key: output_key
- description: output_description
Response Example
----------------
.. literalinclude:: samples/stack-outputs-list-response.json
:language: javascript
Show output
===========
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/outputs/{output_key}
Shows details for a stack output.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- output_key: output_key_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Reqeuest-Id: request_id
- output: output
- output_key: output_key
- output_value: output_value
- description: output_description
- output_error: output_error
Response Example
----------------
.. literalinclude:: samples/stack-output-show-response.json
:language: javascript

View File

@ -1,253 +0,0 @@
.. -*- rst -*-
===============
Stack Snapshots
===============
Snapshot a stack
================
.. rest_method:: POST /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/snapshots
Takes a snapshot of all resources in a stack. All snapshots are deleted when
the stack is deleted.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- name: snapshot_name
Request Example
---------------
.. literalinclude:: samples/stack-snapshot-request.json
:language: javascript
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- creation_time: creation_time
- data: snapshot_data
- id: snapshot_id
- name: snapshot_name
- status: snapshot_status
- status_reason: snapshot_status_reason
Response Example
----------------
.. literalinclude:: samples/stack-snapshot-response.json
:language: javascript
List snapshots
==============
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/snapshots
Lists snapshots for a stack.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- snapshots: snapshots
- creation_time: creation_time
- data: snapshot_data
- id: snapshot_id
- name: snapshot_name
- status: snapshot_status
- status_reason: snapshot_status_reason
Response Example
----------------
.. literalinclude:: samples/stack-snapshots-list-response.json
:language: javascript
Show snapshot
=============
.. rest_method:: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/snapshots/{snapshot_id}
Shows details for a snapshot.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- snapshot_id: snapshot_id_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- snapshot: snapshot
- creation_time: creation_time
- data: snapshot_data
- id: snapshot_id
- name: snapshot_name
- status: snapshot_status
- status_reason: snapshot_status_reason
Response Example
----------------
.. literalinclude:: samples/stack-snapshot-show-response.json
:language: javascript
Restore snapshot
================
.. rest_method:: POST /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/snapshots/{snapshot_id}/restore
Restores a stack snapshot.
You can restore only active stacks from a snapshot. You must recreate deleted
stacks.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 202
.. rest_status_code:: error status.yaml
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- snapshot_id: snapshot_id_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- code: restore_code
- message: restore_message
- title: restore_title
Response Example
----------------
.. literalinclude:: samples/stack-snapshot-restore-response.json
:language: javascript
Delete a snapshot
=================
.. rest_method:: DELETE /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/snapshots/{snapshot_id}
Deletes a stack snapshot.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 204
.. rest_status_code:: error status.yaml
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- snapshot_id: snapshot_id_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
Response Example
----------------
The response to this API does not have a body.

View File

@ -1,153 +0,0 @@
.. -*- rst -*-
=========
Templates
=========
List template versions
======================
.. rest_method:: GET /v1/{tenant_id}/template_versions
Lists all available template versions.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request_id: request_id
- template_versions: template_versions
- alias: template_version_alias
- type: template_type
- version: template_version
Response Example
----------------
.. literalinclude:: samples/template-versions-response.json
:language: javascript
List template functions
=======================
.. rest_method:: GET /v1/{tenant_id}/template_versions/{template_version}/functions
Lists all available functions for a template version.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- template_version: template_version_url
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- template_functions: template_functions
- description: function_description
- functions: functions
Response Example
----------------
.. literalinclude:: samples/template-functions-list-response.json
:language: javascript
Validate template
=================
.. rest_method:: POST /v1/{tenant_id}/validate
Validates a template.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 500
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- environment: environment
- environment_files: environment_files
- files: files
- ignore_errors: ignore_errors
- show_nested: show_nested
- template: template
- template_url: template_url
Request Example
---------------
.. literalinclude:: samples/template-validate-request.json
:language: javascript
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- Description: Description
- ParameterGroups: ParameterGroups
- Parameters: Parameters
Response Example
----------------
.. literalinclude:: samples/template-validate-response.json
:language: javascript

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
#################
# Success Codes #
#################
200:
default: |
Request was successful.
201:
default: |
Resource was created and is ready to use.
202:
default: |
Request was accepted for processing, but the processing has not been
completed. A 'location' header is included in the response which contains
a link to check the progress of the request.
204:
default: |
The server has fulfilled the request by deleting the resource.
300:
default: |
There are multiple choices for resources. The request has to be more
specific to successfully retrieve one of these resources.
302:
default: |
The response is about a redirection hint. The header of the response
usually contains a 'location' value where requesters can check to track
the real location of the resource.
#################
# Error Codes #
#################
400:
default: |
Some content in the request was invalid.
resource_signal: |
The target resource doesn't support receiving a signal.
401:
default: |
User must authenticate before making a request.
403:
default: |
Policy does not allow current user to do this operation.
404:
default: |
The requested resource could not be found.
405:
default: |
Method is not valid for this endpoint.
409:
default: |
This operation conflicted with another operation on this resource.
duplicate_zone: |
There is already a zone with this name.
500:
default: |
Something went wrong inside the service. This should not happen usually.
If it does happen, it means the server has experienced some serious
problems.
503:
default: |
Service is not available. This is mostly caused by service configuration
errors which prevents the service from successful start up.

View File

@ -1,41 +0,0 @@
.. -*- rst -*-
============
API versions
============
List versions
=============
.. rest_method:: GET /
Lists all Orchestration API versions.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 300
Request Parameters
------------------
This operation does not accept a request body.
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
- versions: versions
- id: version_id
- status: version_status
- links: links
Response Example
----------------
.. literalinclude:: samples/versions-list-response.json
:language: javascript

View File

@ -1 +0,0 @@
[python: **.py]

View File

@ -1,44 +0,0 @@
#!/usr/bin/env python
#
# 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.
"""Heat API Server.
An OpenStack REST API to Heat.
"""
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
LOG.warning('DEPRECATED: `heat-api` script is deprecated. Please use the '
'system level heat binaries installed to start '
'any of the heat services.')
import os
import sys
# If ../heat/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'heat', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
from heat.cmd import api
api.main()

View File

@ -1,46 +0,0 @@
#!/usr/bin/env python
#
# 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.
"""Heat CFN API Server.
This implements an approximation of the Amazon CloudFormation API and
translates it into a native representation. It then calls the heat-engine via
AMQP RPC to implement them.
"""
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
LOG.warning('DEPRECATED: `heat-api-cfn` script is deprecated. Please use '
'the system level heat binaries installed to start '
'any of the heat services.')
import os
import sys
# If ../heat/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'heat', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
from heat.cmd import api_cfn
api_cfn.main()

View File

@ -1,46 +0,0 @@
#!/usr/bin/env python
#
# 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.
"""Heat cloudwatch API Server.
This implements an approximation of the Amazon CloudWatch API and translates it
into a native representation. It then calls the heat-engine via AMQP RPC to
implement them.
"""
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
LOG.warning('DEPRECATED: `heat-api-cloudwatch` script is deprecated. '
'Please use the system level heat binaries installed to '
'start any of the heat services.')
import os
import sys
# If ../heat/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'heat', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
from heat.cmd import api_cloudwatch
api_cloudwatch.main()

View File

@ -1,299 +0,0 @@
#!/bin/bash
#
# 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.
#
#
# Print --help output and exit.
#
usage() {
cat << EOF
Set up a local MySQL database for use with heat.
This script will create a 'heat' database that is accessible
only on localhost by user 'heat' with password 'heat'.
Usage: heat-db-setup <rpm|deb> [options]
Options:
select a distro type (rpm or debian)
--help | -h
Print usage information.
--password <pw> | -p <pw>
Specify the password for the 'heat' MySQL user that will
use to connect to the 'heat' MySQL database. By default,
the password 'heat' will be used.
--rootpw <pw> | -r <pw>
Specify the root MySQL password. If the script installs
the MySQL server, it will set the root password to this value
instead of prompting for a password. If the MySQL server is
already installed, this password will be used to connect to the
database instead of having to prompt for it.
--yes | -y
In cases where the script would normally ask for confirmation
before doing something, such as installing mysql-server,
just assume yes. This is useful if you want to run the script
non-interactively.
EOF
exit 0
}
install_mysql_server() {
if [ -z "${ASSUME_YES}" ] ; then
$PACKAGE_INSTALL $DB_SERVER
else
$PACKAGE_INSTALL -y $DB_SERVER
fi
}
start_mysql_server() {
$SERVICE_START
}
MYSQL_HEAT_PW_DEFAULT="heat"
MYSQL_HEAT_PW=${MYSQL_HEAT_PW_DEFAULT}
HEAT_CONFIG="/etc/heat/heat.conf"
ASSUME_YES=""
ELEVATE=""
# Check for root privileges
if [[ $EUID -ne 0 ]] ; then
echo "This operation requires superuser privileges, using sudo:"
if sudo -l > /dev/null ; then
ELEVATE="sudo"
else
exit 1
fi
fi
case "$1" in
rpm)
echo "Installing on an RPM system."
PACKAGE_INSTALL="$ELEVATE yum install"
PACKAGE_STATUS="rpm -q"
SERVICE_MYSQLD="mysqld"
DB_SERVER="mysql-server"
# Install mariadb-server in rhel7 and fedora
if [[ -r /etc/redhat-release ]];then
ver=`grep -E -o '[0-9]+' /etc/redhat-release| sed 1q`
if [[ $ver -ge 7 ]];then
SERVICE_MYSQLD="mariadb"
DB_SERVER="mariadb-server"
fi
fi
SERVICE_START="$ELEVATE service $SERVICE_MYSQLD start"
SERVICE_STATUS="service $SERVICE_MYSQLD status"
SERVICE_ENABLE="$ELEVATE chkconfig"
;;
deb)
echo "Installing on a Debian system."
PACKAGE_INSTALL="$ELEVATE apt-get install"
PACKAGE_STATUS="dpkg-query -s"
SERVICE_MYSQLD="mysql"
DB_SERVER="mysql-server"
SERVICE_START="$ELEVATE service $SERVICE_MYSQLD start"
SERVICE_STATUS="$ELEVATE service $SERVICE_MYSQLD status"
SERVICE_ENABLE=""
;;
*)
usage
;;
esac
while [ $# -gt 0 ]
do
case "$1" in
-h|--help)
usage
;;
-p|--password)
shift
MYSQL_HEAT_PW=${1}
;;
-r|--rootpw)
shift
MYSQL_ROOT_PW=${1}
;;
-y|--yes)
ASSUME_YES="yes"
;;
*)
# ignore
;;
esac
shift
done
# Make sure MySQL is installed.
NEW_MYSQL_INSTALL=0
if ! $PACKAGE_STATUS mysql-server && ! $PACKAGE_STATUS mariadb-server > /dev/null
then
if [ -z "${ASSUME_YES}" ] ; then
printf "mysql-server is not installed. Would you like to install it now? (y/n): "
read response
case "$response" in
y|Y)
;;
n|N)
echo "mysql-server must be installed. Please install it before proceeding."
exit 0
;;
*)
echo "Invalid response." >&2
exit 1
esac
fi
NEW_MYSQL_INSTALL=1
install_mysql_server
fi
# Make sure mysqld is running.
if ! $SERVICE_STATUS > /dev/null
then
if [ -z "${ASSUME_YES}" ] ; then
printf "$SERVICE_MYSQLD is not running. Would you like to start it now? (y/n): "
read response
case "$response" in
y|Y)
;;
n|N)
echo "$SERVICE_MYSQLD must be running. Please start it before proceeding."
exit 0
;;
*)
echo "Invalid response." >&2
exit 1
esac
fi
start_mysql_server
# If we both installed and started, ensure it starts at boot
[ $NEW_MYSQL_INSTALL -eq 1 ] && $SERVICE_ENABLE $SERVICE_MYSQLD on
fi
# Get MySQL root access.
if [ $NEW_MYSQL_INSTALL -eq 1 ]
then
if [ ! "${MYSQL_ROOT_PW+defined}" ] ; then
echo "Since this is a fresh installation of MySQL, please set a password for the 'root' mysql user."
PW_MATCH=0
while [ $PW_MATCH -eq 0 ]
do
printf "Enter new password for 'root' mysql user: "
read -s MYSQL_ROOT_PW
echo
printf "Enter new password again: "
read -s PW2
echo
if [ "${MYSQL_ROOT_PW}" = "${PW2}" ] ; then
PW_MATCH=1
else
echo "Passwords did not match." >&2
fi
done
fi
echo "UPDATE mysql.user SET password = password('${MYSQL_ROOT_PW}') WHERE user = 'root'; DELETE FROM mysql.user WHERE user = ''; flush privileges;" | mysql -u root
if ! [ $? -eq 0 ] ; then
echo "Failed to set password for 'root' MySQL user." >&2
exit 1
fi
elif [ ! "${MYSQL_ROOT_PW+defined}" ] ; then
printf "Please enter the password for the 'root' MySQL user: "
read -s MYSQL_ROOT_PW
echo
fi
# Sanity check MySQL credentials.
MYSQL_ROOT_PW_ARG=""
if [ "${MYSQL_ROOT_PW+defined}" ]
then
MYSQL_ROOT_PW_ARG="--password=${MYSQL_ROOT_PW}"
fi
echo "SELECT 1;" | mysql -u root ${MYSQL_ROOT_PW_ARG} > /dev/null
if ! [ $? -eq 0 ]
then
echo "Failed to connect to the MySQL server. Please check your root user credentials." >&2
exit 1
fi
echo "Verified connectivity to MySQL."
# Now create the db.
echo "Creating 'heat' database."
cat << EOF | mysql -u root ${MYSQL_ROOT_PW_ARG}
CREATE DATABASE IF NOT EXISTS heat DEFAULT CHARACTER SET utf8;
GRANT ALL ON heat.* TO 'heat'@'localhost' IDENTIFIED BY '${MYSQL_HEAT_PW}';
GRANT ALL ON heat.* TO 'heat'@'%' IDENTIFIED BY '${MYSQL_HEAT_PW}';
flush privileges;
EOF
# Make sure heat configuration has the right MySQL password.
if [ "${MYSQL_HEAT_PW}" != "${MYSQL_HEAT_PW_DEFAULT}" ] ; then
echo "Updating 'heat' database password in ${HEAT_CONFIG}"
sed -i -e "s/mysql:\/\/heat:\(.*\)@/mysql:\/\/heat:${MYSQL_HEAT_PW}@/" ${HEAT_CONFIG}
fi
# override the logging config in heat.conf
log_conf=$(mktemp /tmp/heat-logging.XXXXXXXXXX.conf)
cat <<EOF > $log_conf
[loggers]
keys=root
[handlers]
keys=consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=INFO
handlers=consoleHandler
[handler_consoleHandler]
class=StreamHandler
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(name)s - %(levelname)s - %(message)s
EOF
heat-manage --log-config=$log_conf db_sync
rm $log_conf
# Do a final sanity check on the database.
echo "SELECT * FROM migrate_version;" | mysql -u heat --password=${MYSQL_HEAT_PW} heat > /dev/null
if ! [ $? -eq 0 ]
then
echo "Final sanity check failed." >&2
exit 1
fi
echo "Complete!"

View File

@ -1,46 +0,0 @@
#!/usr/bin/env python
#
# 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.
"""Heat Engine Server.
This does the work of actually implementing the API calls made by the user.
Normal communications is done via the heat API which then calls into this
engine.
"""
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
LOG.warning('DEPRECATED: `heat-engine` script is deprecated. '
'Please use the system level heat binaries installed to '
'start any of the heat services.')
import os
import sys
# If ../heat/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'heat', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
from heat.cmd import engine
engine.main()

View File

@ -1,286 +0,0 @@
#!/bin/bash
echo "Warning: This script is deprecated! Please use other tool to setup keystone for heat." >&2
set +e
KEYSTONE_CONF=${KEYSTONE_CONF:-/etc/keystone/keystone.conf}
# Extract some info from Keystone's configuration file
if [[ -r "$KEYSTONE_CONF" ]]; then
CONFIG_SERVICE_TOKEN=$(sed 's/[[:space:]]//g' $KEYSTONE_CONF | grep ^admin_token= | cut -d'=' -f2)
CONFIG_ADMIN_PORT=$(sed 's/[[:space:]]//g' $KEYSTONE_CONF | grep ^admin_port= | cut -d'=' -f2)
fi
SERVICE_TOKEN=${OS_SERVICE_TOKEN:-$CONFIG_SERVICE_TOKEN}
SERVICE_ENDPOINT=${OS_SERVICE_ENDPOINT:-http://127.0.0.1:${CONFIG_ADMIN_PORT:-35357}/v2.0}
if [[ -z "$SERVICE_TOKEN" ]]; then
echo "No service token found." >&2
echo "Set SERVICE_TOKEN manually from keystone.conf admin_token." >&2
exit 1
fi
set_admin_token() {
alias openstack="openstack --os-token $SERVICE_TOKEN \
--os-endpoint $SERVICE_ENDPOINT"
}
unset_admin_token() {
unalias openstack
}
#### utilities functions merged from devstack to check required parameter is not empty
# Prints line number and "message" in error format
# err $LINENO "message"
function err() {
local exitcode=$?
errXTRACE=$(set +o | grep xtrace)
set +o xtrace
local msg="[ERROR] ${BASH_SOURCE[2]}:$1 $2"
echo $msg 1>&2;
if [[ -n ${SCREEN_LOGDIR} ]]; then
echo $msg >> "${SCREEN_LOGDIR}/error.log"
fi
$errXTRACE
return $exitcode
}
# Prints backtrace info
# filename:lineno:function
function backtrace {
local level=$1
local deep=$((${#BASH_SOURCE[@]} - 1))
echo "[Call Trace]"
while [ $level -le $deep ]; do
echo "${BASH_SOURCE[$deep]}:${BASH_LINENO[$deep-1]}:${FUNCNAME[$deep-1]}"
deep=$((deep - 1))
done
}
# Prints line number and "message" then exits
# die $LINENO "message"
function die() {
local exitcode=$?
set +o xtrace
local line=$1; shift
if [ $exitcode == 0 ]; then
exitcode=1
fi
backtrace 2
err $line "$*"
exit $exitcode
}
# Checks an environment variable is not set or has length 0 OR if the
# exit code is non-zero and prints "message" and exits
# NOTE: env-var is the variable name without a '$'
# die_if_not_set $LINENO env-var "message"
function die_if_not_set() {
local exitcode=$?
FXTRACE=$(set +o | grep xtrace)
set +o xtrace
local line=$1; shift
local evar=$1; shift
if ! is_set $evar || [ $exitcode != 0 ]; then
die $line "$*"
fi
$FXTRACE
}
# Test if the named environment variable is set and not zero length
# is_set env-var
function is_set() {
local var=\$"$1"
eval "[ -n \"$var\" ]" # For ex.: sh -c "[ -n \"$var\" ]" would be better, but several exercises depends on this
}
#######################################
get_data() {
local match_column=$(($1 + 1))
local regex="$2"
local output_column=$(($3 + 1))
shift 3
output=$("$@" | \
awk -F'|' \
"! /^\+/ && \$${match_column} ~ \"^ *${regex} *\$\" \
{ print \$${output_column} }")
echo "$output"
}
get_id () {
get_data 1 id 2 "$@"
}
get_user() {
local username=$1
local user_id=$(get_data 2 $username 1 openstack user list)
if [ -n "$user_id" ]; then
echo "Found existing $username user" >&2
echo $user_id >&2
else
echo "Creating $username user..." >&2
get_id openstack user create $username \
--password="$SERVICE_PASSWORD" \
--project $SERVICE_TENANT \
--email=$username@example.com
fi
}
add_role() {
local user_id=$1
local tenant=$2
local role_id=$3
local username=$4
user_roles=$(openstack user role list $user_id\
--project $tenant 2>/dev/null)
if [ $? == 0 ]; then
# Folsom
existing_role=$(get_data 1 $role_id 1 echo "$user_roles")
if [ -n "$existing_role" ]
then
echo "User $username already has role $role_id" >&2
return
fi
openstack role add --project $tenant \
--user $user_id \
$role_id
fi
}
create_role() {
local role_name=$1
role_id=$(get_data 2 $role_name 1 openstack role list)
if [ -n "$role_id" ]
then
echo "Role $role_name already exists : $role_id" >&2
else
openstack role create $role_name
fi
}
get_endpoint() {
local service_type=$1
unset_admin_token
openstack endpoint show $service_type
set_admin_token
}
delete_endpoint() {
local service_type=$1
local endpoints=$(get_data 4 $service_type 1 openstack endpoint list)
for endpoint in $endpoints; do
echo "Removing $service_type endpoint ${endpoint}..." >&2
openstack endpoint delete "$endpoint" >&2
done
if [ -z "$endpoints" ]; then false; fi
}
delete_all_endpoints() {
while delete_endpoint $1; do
true
done
}
delete_service() {
local service_type=$1
delete_all_endpoints $service_type
local service_ids=$(get_data 3 $service_type 1 openstack service list)
for service in $service_ids; do
local service_name=$(get_data 1 $service 2 openstack service list)
echo "Removing $service_name:$service_type service..." >&2
openstack service delete $service >&2
done
}
get_service() {
local service_name=$1
local service_type=$2
local description="$3"
delete_service $service_type
get_id openstack service create --name=$service_name \
--description="$description" \
$service_type
}
add_endpoint() {
local service_id=$1
local url="$2"
openstack endpoint create --region RegionOne --publicurl "$url" \
--adminurl "$url" --internalurl "$url" $service_id >&2
}
keystone_setup() {
unset OS_SERVICE_TOKEN
unset OS_SERVICE_ENDPOINT
TENANT_ID=$(get_data 1 project_id 2 openstack token issue)
die_if_not_set $LINENO TENANT_ID "Fail to get TENANT_ID by 'openstack token issue' "
set_admin_token
ADMIN_ROLE=$(get_data 2 admin 1 openstack role list)
die_if_not_set $LINENO ADMIN_ROLE "Fail to get ADMIN_ROLE by 'openstack role list' "
SERVICE_TENANT=$(get_data 2 service 1 openstack project list)
die_if_not_set $LINENO SERVICE_TENANT "Fail to get service tenant 'openstack project list' "
SERVICE_PASSWORD=${SERVICE_PASSWORD:-$OS_PASSWORD}
SERVICE_HOST=${SERVICE_HOST:-localhost}
if [[ "$SERVICE_PASSWORD" == "$OS_PASSWORD" ]]; then
echo "Using the OS_PASSWORD for the SERVICE_PASSWORD." >&2
fi
if [[ "$SERVICE_HOST" == "localhost" ]]; then
echo "Warning: Endpoints will be registered as localhost, but this usually won't work." >&2
echo "Set SERVICE_HOST to a publicly accessible hostname/IP instead." >&2
fi
echo ADMIN_ROLE $ADMIN_ROLE
echo SERVICE_TENANT $SERVICE_TENANT
echo SERVICE_PASSWORD $SERVICE_PASSWORD
echo SERVICE_TOKEN $SERVICE_TOKEN
echo SERVICE_HOST $SERVICE_HOST
HEAT_USERNAME="heat"
HEAT_USERID=$(get_user $HEAT_USERNAME)
die_if_not_set $LINENO HEAT_USERID "Fail to get user for $HEAT_USERNAME"
echo HEAT_USERID $HEAT_USERID
add_role $HEAT_USERID $SERVICE_TENANT $ADMIN_ROLE $HEAT_USERNAME
# Create a special role which template-defined "stack users" are
# assigned to in the engine when they are created, this allows them
# to be more easily differentiated from other users (e.g so we can
# lock down these implicitly untrusted users via RBAC policy)
STACK_USER_ROLE="heat_stack_user"
create_role $STACK_USER_ROLE
HEAT_CFN_SERVICE=$(get_service heat-cfn cloudformation \
"Heat CloudFormation API")
add_endpoint $HEAT_CFN_SERVICE "http://$SERVICE_HOST:8000/v1"
HEAT_OS_SERVICE=$(get_service heat orchestration \
"Heat API")
add_endpoint $HEAT_OS_SERVICE "http://$SERVICE_HOST:8004/v1/%(tenant_id)s"
}
if [[ ${BASH_SOURCE[0]} == ${0} ]]; then
keystone_setup
fi

View File

@ -1,164 +0,0 @@
#!/usr/bin/env python
#
# 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.
import os
import sys
import keystoneclient.exceptions as kc_exception
from keystoneclient.v3 import client
from oslo_config import cfg
from oslo_log import log as logging
from heat.common.i18n import _
from heat import version
logger = logging.getLogger(__name__)
DEBUG = False
USERNAME = os.environ.get('OS_USERNAME')
PASSWORD = os.environ.get('OS_PASSWORD')
AUTH_URL = os.environ.get('OS_AUTH_URL', '').replace('v2.0', 'v3')
TENANT_NAME = os.environ.get('OS_TENANT_NAME')
opts = [
cfg.StrOpt('stack-user-domain-name',
default="heat",
help=_("Name of domain to create for stack users.")),
cfg.StrOpt('stack-domain-admin',
default="heat_stack_admin",
help=_("Keystone username with roles sufficient to manage users"
" and projects in the stack-user-domain")),
cfg.StrOpt('stack-domain-admin-password',
secret=True,
help=_("Password to set for stack-domain-admin")),
cfg.BoolOpt('insecure',
default=False,
help=_("If set, then the server's certificate will not "
"be verified.")),
cfg.StrOpt('os-cacert',
help=_('Optional CA cert file to use in SSL connections.')),
cfg.StrOpt('os-cert',
help=_('Optional PEM-formatted certificate chain file.')),
cfg.StrOpt('os-key',
help=_('Optional PEM-formatted file that contains the '
'private key.')),
]
# Setup logging before registering additional options
logging.register_options(cfg.CONF)
extra_log_level_defaults = ['urllib3.connectionpool=WARNING']
logging.set_defaults(
logging_context_format_string="%(levelname)s (%(module)s:"
"%(lineno)d) %(message)s",
default_log_levels=(logging.get_default_log_levels() +
extra_log_level_defaults))
logging.setup(cfg.CONF, 'heat-keystone-setup-domain',
version.version_info.version_string())
# Register additional options
cfg.CONF.register_cli_opts(opts)
cfg.CONF(sys.argv[1:],
project='heat',
prog='heat-keystone-setup-domain',
version=version.version_info.version_string())
HEAT_DOMAIN_NAME = os.environ.get(
'HEAT_DOMAIN', cfg.CONF.stack_user_domain_name)
HEAT_DOMAIN_ADMIN = os.environ.get('HEAT_DOMAIN_ADMIN',
cfg.CONF.stack_domain_admin)
HEAT_DOMAIN_PASSWORD = os.environ.get('HEAT_DOMAIN_PASSWORD',
cfg.CONF.stack_domain_admin_password)
HEAT_DOMAIN_DESCRIPTION = 'Contains users and projects created by heat'
logger.debug("USERNAME=%s" % USERNAME)
logger.debug("AUTH_URL=%s" % AUTH_URL)
CACERT = os.environ.get('OS_CACERT', cfg.CONF.os_cacert)
CERT = os.environ.get('OS_CERT', cfg.CONF.os_cert)
KEY = os.environ.get('OS_KEY', cfg.CONF.os_key)
insecure = cfg.CONF.insecure
def main():
client_kwargs = {
'debug': DEBUG,
'username': USERNAME,
'password': PASSWORD,
'auth_url': AUTH_URL,
'endpoint': AUTH_URL,
'tenant_name': TENANT_NAME
}
if insecure:
client_kwargs['verify'] = False
else:
client_kwargs.update({
'cacert': CACERT,
'cert': CERT,
'key': KEY
})
c = client.Client(**client_kwargs)
c.authenticate()
# Create the heat domain
logger.info("Creating domain %s" % HEAT_DOMAIN_NAME)
try:
heat_domain = c.domains.create(name=HEAT_DOMAIN_NAME,
description=HEAT_DOMAIN_DESCRIPTION)
except kc_exception.Conflict:
logger.warning("Domain %s already exists" % HEAT_DOMAIN_NAME)
heat_domain = c.domains.list(name=HEAT_DOMAIN_NAME)[0]
if heat_domain.name != HEAT_DOMAIN_NAME:
logger.error("Unexpected filtered list response, please upgrade "
"keystoneclient to >= 0.5")
sys.exit(1)
except kc_exception.Forbidden:
logger.error("User '%s' is not authorized to perform this "
"operation, please try with other OS_USERNAME setting." %
USERNAME)
sys.exit(1)
# Create heat domain admin user
if not HEAT_DOMAIN_PASSWORD:
logger.error("Must export HEAT_DOMAIN_PASSWORD or use"
" --stack-domain-admin-password")
sys.exit(1)
try:
domain_admin = c.users.create(name=HEAT_DOMAIN_ADMIN,
password=HEAT_DOMAIN_PASSWORD,
domain=heat_domain,
description="Heat domain admin")
except kc_exception.Conflict:
logger.warning("User %s already exists" % HEAT_DOMAIN_ADMIN)
domain_admin = c.users.list(name=HEAT_DOMAIN_ADMIN,
domain=heat_domain)[0]
# Make the user a domain admin
roles_list = c.roles.list()
# FIXME(shardy): seems filtering roles by name currently doesn't work
admin_role = [r for r in roles_list
if r.name == 'admin'][0]
c.roles.grant(role=admin_role, user=domain_admin, domain=heat_domain)
print("\nPlease update your heat.conf with the following in [DEFAULT]\n")
print("stack_user_domain_id=%s" % heat_domain.id)
print("stack_domain_admin=%s" % HEAT_DOMAIN_ADMIN)
print("stack_domain_admin_password=%s" % HEAT_DOMAIN_PASSWORD)
if __name__ == "__main__":
main()

View File

@ -1,37 +0,0 @@
#!/usr/bin/env python
#
# 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.
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
LOG.warning('DEPRECATED: `heat-manage` script is deprecated. Please use '
'the system level heat-manage binary.')
import os
import sys
# If ../heat/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'heat', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
from heat.cmd import manage
manage.main()

View File

@ -1,22 +0,0 @@
[DEFAULT]
output_file = etc/heat/heat.conf.sample
wrap_width = 79
namespace = heat.common.config
namespace = heat.common.context
namespace = heat.common.crypt
namespace = heat.engine.clients.keystone.heat_keystoneclient
namespace = heat.common.wsgi
namespace = heat.engine.clients
namespace = heat.engine.notification
namespace = heat.engine.resources
namespace = heat.api.middleware.ssl
namespace = heat.api.aws.ec2token
namespace = keystonemiddleware.auth_token
namespace = oslo.messaging
namespace = oslo.middleware
namespace = oslo.db
namespace = oslo.log
namespace = oslo.policy
namespace = oslo.service.service
namespace = oslo.service.periodic_task
namespace = oslo.service.sslutils

View File

@ -1,18 +0,0 @@
Docker plugin for OpenStack Heat
================================
This plugin enable using Docker containers as resources in a Heat template.
### 1. Install the Docker plugin in Heat
NOTE: These instructions assume the value of heat.conf plugin_dirs includes the
default directory /usr/lib/heat.
To install the plugin, from this directory run:
sudo python ./setup.py install
### 2. Restart heat
Only the process "heat-engine" needs to be restarted to load the new installed
plugin.

View File

@ -1,574 +0,0 @@
#
# Copyright (c) 2013 Docker, Inc.
# 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.
import distutils
from oslo_log import log as logging
import six
from heat.common import exception
from heat.common.i18n import _
from heat.engine import attributes
from heat.engine import constraints
from heat.engine import properties
from heat.engine import resource
from heat.engine import support
LOG = logging.getLogger(__name__)
DOCKER_INSTALLED = False
MIN_API_VERSION_MAP = {'read_only': '1.17', 'cpu_shares': '1.8',
'devices': '1.14', 'cpu_set': '1.12'}
DEVICE_PATH_REGEX = r"^/dev/[/_\-a-zA-Z0-9]+$"
# conditionally import so tests can work without having the dependency
# satisfied
try:
import docker
DOCKER_INSTALLED = True
except ImportError:
docker = None
class DockerContainer(resource.Resource):
support_status = support.SupportStatus(
status=support.UNSUPPORTED,
message=_('This resource is not supported, use at your own risk.'))
PROPERTIES = (
DOCKER_ENDPOINT, HOSTNAME, USER, MEMORY, PORT_SPECS,
PRIVILEGED, TTY, OPEN_STDIN, STDIN_ONCE, ENV, CMD, DNS,
IMAGE, VOLUMES, VOLUMES_FROM, PORT_BINDINGS, LINKS, NAME,
RESTART_POLICY, CAP_ADD, CAP_DROP, READ_ONLY, CPU_SHARES,
DEVICES, CPU_SET
) = (
'docker_endpoint', 'hostname', 'user', 'memory', 'port_specs',
'privileged', 'tty', 'open_stdin', 'stdin_once', 'env', 'cmd', 'dns',
'image', 'volumes', 'volumes_from', 'port_bindings', 'links', 'name',
'restart_policy', 'cap_add', 'cap_drop', 'read_only', 'cpu_shares',
'devices', 'cpu_set'
)
ATTRIBUTES = (
INFO, NETWORK_INFO, NETWORK_IP, NETWORK_GATEWAY,
NETWORK_TCP_PORTS, NETWORK_UDP_PORTS, LOGS, LOGS_HEAD,
LOGS_TAIL,
) = (
'info', 'network_info', 'network_ip', 'network_gateway',
'network_tcp_ports', 'network_udp_ports', 'logs', 'logs_head',
'logs_tail',
)
_RESTART_POLICY_KEYS = (
POLICY_NAME, POLICY_MAXIMUM_RETRY_COUNT,
) = (
'Name', 'MaximumRetryCount',
)
_DEVICES_KEYS = (
PATH_ON_HOST, PATH_IN_CONTAINER, PERMISSIONS
) = (
'path_on_host', 'path_in_container', 'permissions'
)
_CAPABILITIES = ['SETPCAP', 'SYS_MODULE', 'SYS_RAWIO', 'SYS_PACCT',
'SYS_ADMIN', 'SYS_NICE', 'SYS_RESOURCE', 'SYS_TIME',
'SYS_TTY_CONFIG', 'MKNOD', 'AUDIT_WRITE',
'AUDIT_CONTROL', 'MAC_OVERRIDE', 'MAC_ADMIN',
'NET_ADMIN', 'SYSLOG', 'CHOWN', 'NET_RAW',
'DAC_OVERRIDE', 'FOWNER', 'DAC_READ_SEARCH', 'FSETID',
'KILL', 'SETGID', 'SETUID', 'LINUX_IMMUTABLE',
'NET_BIND_SERVICE', 'NET_BROADCAST', 'IPC_LOCK',
'IPC_OWNER', 'SYS_CHROOT', 'SYS_PTRACE', 'SYS_BOOT',
'LEASE', 'SETFCAP', 'WAKE_ALARM', 'BLOCK_SUSPEND', 'ALL']
properties_schema = {
DOCKER_ENDPOINT: properties.Schema(
properties.Schema.STRING,
_('Docker daemon endpoint (by default the local docker daemon '
'will be used).'),
default=None
),
HOSTNAME: properties.Schema(
properties.Schema.STRING,
_('Hostname of the container.'),
default=''
),
USER: properties.Schema(
properties.Schema.STRING,
_('Username or UID.'),
default=''
),
MEMORY: properties.Schema(
properties.Schema.INTEGER,
_('Memory limit (Bytes).')
),
PORT_SPECS: properties.Schema(
properties.Schema.LIST,
_('TCP/UDP ports mapping.'),
default=None
),
PORT_BINDINGS: properties.Schema(
properties.Schema.MAP,
_('TCP/UDP ports bindings.'),
),
LINKS: properties.Schema(
properties.Schema.MAP,
_('Links to other containers.'),
),
NAME: properties.Schema(
properties.Schema.STRING,
_('Name of the container.'),
),
PRIVILEGED: properties.Schema(
properties.Schema.BOOLEAN,
_('Enable extended privileges.'),
default=False
),
TTY: properties.Schema(
properties.Schema.BOOLEAN,
_('Allocate a pseudo-tty.'),
default=False
),
OPEN_STDIN: properties.Schema(
properties.Schema.BOOLEAN,
_('Open stdin.'),
default=False
),
STDIN_ONCE: properties.Schema(
properties.Schema.BOOLEAN,
_('If true, close stdin after the 1 attached client disconnects.'),
default=False
),
ENV: properties.Schema(
properties.Schema.LIST,
_('Set environment variables.'),
),
CMD: properties.Schema(
properties.Schema.LIST,
_('Command to run after spawning the container.'),
default=[]
),
DNS: properties.Schema(
properties.Schema.LIST,
_('Set custom dns servers.'),
),
IMAGE: properties.Schema(
properties.Schema.STRING,
_('Image name.')
),
VOLUMES: properties.Schema(
properties.Schema.MAP,
_('Create a bind mount.'),
default={}
),
VOLUMES_FROM: properties.Schema(
properties.Schema.LIST,
_('Mount all specified volumes.'),
default=''
),
RESTART_POLICY: properties.Schema(
properties.Schema.MAP,
_('Restart policies (only supported for API version >= 1.2.0).'),
schema={
POLICY_NAME: properties.Schema(
properties.Schema.STRING,
_('The behavior to apply when the container exits.'),
default='no',
constraints=[
constraints.AllowedValues(['no', 'on-failure',
'always']),
]
),
POLICY_MAXIMUM_RETRY_COUNT: properties.Schema(
properties.Schema.INTEGER,
_('A maximum restart count for the '
'on-failure policy.'),
default=0
)
},
default={},
support_status=support.SupportStatus(version='2015.1')
),
CAP_ADD: properties.Schema(
properties.Schema.LIST,
_('Be used to add kernel capabilities (only supported for '
'API version >= 1.2.0).'),
schema=properties.Schema(
properties.Schema.STRING,
_('The security features provided by Linux kernels.'),
constraints=[
constraints.AllowedValues(_CAPABILITIES),
]
),
default=[],
support_status=support.SupportStatus(version='2015.1')
),
CAP_DROP: properties.Schema(
properties.Schema.LIST,
_('Be used to drop kernel capabilities (only supported for '
'API version >= 1.2.0).'),
schema=properties.Schema(
properties.Schema.STRING,
_('The security features provided by Linux kernels.'),
constraints=[
constraints.AllowedValues(_CAPABILITIES),
]
),
default=[],
support_status=support.SupportStatus(version='2015.1')
),
READ_ONLY: properties.Schema(
properties.Schema.BOOLEAN,
_('If true, mount the container\'s root filesystem '
'as read only (only supported for API version >= %s).') %
MIN_API_VERSION_MAP['read_only'],
default=False,
support_status=support.SupportStatus(version='2015.1'),
),
CPU_SHARES: properties.Schema(
properties.Schema.INTEGER,
_('Relative weight which determines the allocation of the CPU '
'processing power(only supported for API version >= %s).') %
MIN_API_VERSION_MAP['cpu_shares'],
default=0,
support_status=support.SupportStatus(version='5.0.0'),
),
DEVICES: properties.Schema(
properties.Schema.LIST,
_('Device mappings (only supported for API version >= %s).') %
MIN_API_VERSION_MAP['devices'],
schema=properties.Schema(
properties.Schema.MAP,
schema={
PATH_ON_HOST: properties.Schema(
properties.Schema.STRING,
_('The device path on the host.'),
constraints=[
constraints.Length(max=255),
constraints.AllowedPattern(DEVICE_PATH_REGEX),
],
required=True
),
PATH_IN_CONTAINER: properties.Schema(
properties.Schema.STRING,
_('The device path of the container'
' mappings to the host.'),
constraints=[
constraints.Length(max=255),
constraints.AllowedPattern(DEVICE_PATH_REGEX),
],
),
PERMISSIONS: properties.Schema(
properties.Schema.STRING,
_('The permissions of the container to'
' read/write/create the devices.'),
constraints=[
constraints.AllowedValues(['r', 'w', 'm',
'rw', 'rm', 'wm',
'rwm']),
],
default='rwm'
)
}
),
default=[],
support_status=support.SupportStatus(version='5.0.0'),
),
CPU_SET: properties.Schema(
properties.Schema.STRING,
_('The CPUs in which to allow execution '
'(only supported for API version >= %s).') %
MIN_API_VERSION_MAP['cpu_set'],
support_status=support.SupportStatus(version='5.0.0'),
)
}
attributes_schema = {
INFO: attributes.Schema(
_('Container info.')
),
NETWORK_INFO: attributes.Schema(
_('Container network info.')
),
NETWORK_IP: attributes.Schema(
_('Container ip address.')
),
NETWORK_GATEWAY: attributes.Schema(
_('Container ip gateway.')
),
NETWORK_TCP_PORTS: attributes.Schema(
_('Container TCP ports.')
),
NETWORK_UDP_PORTS: attributes.Schema(
_('Container UDP ports.')
),
LOGS: attributes.Schema(
_('Container logs.')
),
LOGS_HEAD: attributes.Schema(
_('Container first logs line.')
),
LOGS_TAIL: attributes.Schema(
_('Container last logs line.')
),
}
def get_client(self):
client = None
if DOCKER_INSTALLED:
endpoint = self.properties.get(self.DOCKER_ENDPOINT)
if endpoint:
client = docker.Client(endpoint)
else:
client = docker.Client()
return client
def _parse_networkinfo_ports(self, networkinfo):
tcp = []
udp = []
for port, info in six.iteritems(networkinfo['Ports']):
p = port.split('/')
if not info or len(p) != 2 or 'HostPort' not in info[0]:
continue
port = info[0]['HostPort']
if p[1] == 'tcp':
tcp.append(port)
elif p[1] == 'udp':
udp.append(port)
return (','.join(tcp), ','.join(udp))
def _container_networkinfo(self, client, resource_id):
info = client.inspect_container(self.resource_id)
networkinfo = info['NetworkSettings']
ports = self._parse_networkinfo_ports(networkinfo)
networkinfo['TcpPorts'] = ports[0]
networkinfo['UdpPorts'] = ports[1]
return networkinfo
def _resolve_attribute(self, name):
if not self.resource_id:
return
if name == 'info':
client = self.get_client()
return client.inspect_container(self.resource_id)
if name == 'network_info':
client = self.get_client()
networkinfo = self._container_networkinfo(client, self.resource_id)
return networkinfo
if name == 'network_ip':
client = self.get_client()
networkinfo = self._container_networkinfo(client, self.resource_id)
return networkinfo['IPAddress']
if name == 'network_gateway':
client = self.get_client()
networkinfo = self._container_networkinfo(client, self.resource_id)
return networkinfo['Gateway']
if name == 'network_tcp_ports':
client = self.get_client()
networkinfo = self._container_networkinfo(client, self.resource_id)
return networkinfo['TcpPorts']
if name == 'network_udp_ports':
client = self.get_client()
networkinfo = self._container_networkinfo(client, self.resource_id)
return networkinfo['UdpPorts']
if name == 'logs':
client = self.get_client()
logs = client.logs(self.resource_id)
return logs
if name == 'logs_head':
client = self.get_client()
logs = client.logs(self.resource_id)
return logs.split('\n')[0]
if name == 'logs_tail':
client = self.get_client()
logs = client.logs(self.resource_id)
return logs.split('\n').pop()
def handle_create(self):
create_args = {
'image': self.properties[self.IMAGE],
'command': self.properties[self.CMD],
'hostname': self.properties[self.HOSTNAME],
'user': self.properties[self.USER],
'stdin_open': self.properties[self.OPEN_STDIN],
'tty': self.properties[self.TTY],
'mem_limit': self.properties[self.MEMORY],
'ports': self.properties[self.PORT_SPECS],
'environment': self.properties[self.ENV],
'dns': self.properties[self.DNS],
'volumes': self.properties[self.VOLUMES],
'name': self.properties[self.NAME],
'cpu_shares': self.properties[self.CPU_SHARES],
'cpuset': self.properties[self.CPU_SET]
}
client = self.get_client()
client.pull(self.properties[self.IMAGE])
result = client.create_container(**create_args)
container_id = result['Id']
self.resource_id_set(container_id)
start_args = {}
if self.properties[self.PRIVILEGED]:
start_args[self.PRIVILEGED] = True
if self.properties[self.VOLUMES]:
start_args['binds'] = self.properties[self.VOLUMES]
if self.properties[self.VOLUMES_FROM]:
start_args['volumes_from'] = self.properties[self.VOLUMES_FROM]
if self.properties[self.PORT_BINDINGS]:
start_args['port_bindings'] = self.properties[self.PORT_BINDINGS]
if self.properties[self.LINKS]:
start_args['links'] = self.properties[self.LINKS]
if self.properties[self.RESTART_POLICY]:
start_args['restart_policy'] = self.properties[self.RESTART_POLICY]
if self.properties[self.CAP_ADD]:
start_args['cap_add'] = self.properties[self.CAP_ADD]
if self.properties[self.CAP_DROP]:
start_args['cap_drop'] = self.properties[self.CAP_DROP]
if self.properties[self.READ_ONLY]:
start_args[self.READ_ONLY] = True
if (self.properties[self.DEVICES] and
not self.properties[self.PRIVILEGED]):
start_args['devices'] = self._get_mapping_devices(
self.properties[self.DEVICES])
client.start(container_id, **start_args)
return container_id
def _get_mapping_devices(self, devices):
actual_devices = []
for device in devices:
if device[self.PATH_IN_CONTAINER]:
actual_devices.append(':'.join(
[device[self.PATH_ON_HOST],
device[self.PATH_IN_CONTAINER],
device[self.PERMISSIONS]]))
else:
actual_devices.append(':'.join(
[device[self.PATH_ON_HOST],
device[self.PATH_ON_HOST],
device[self.PERMISSIONS]]))
return actual_devices
def _get_container_status(self, container_id):
client = self.get_client()
info = client.inspect_container(container_id)
return info['State']
def check_create_complete(self, container_id):
status = self._get_container_status(container_id)
exit_status = status.get('ExitCode')
if exit_status is not None and exit_status != 0:
logs = self.get_client().logs(self.resource_id)
raise exception.ResourceInError(resource_status=self.FAILED,
status_reason=logs)
return status['Running']
def handle_delete(self):
if self.resource_id is None:
return
client = self.get_client()
try:
client.kill(self.resource_id)
except docker.errors.APIError as ex:
if ex.response.status_code != 404:
raise
return self.resource_id
def check_delete_complete(self, container_id):
if container_id is None:
return True
try:
status = self._get_container_status(container_id)
if not status['Running']:
client = self.get_client()
client.remove_container(container_id)
except docker.errors.APIError as ex:
if ex.response.status_code == 404:
return True
raise
return False
def handle_suspend(self):
if not self.resource_id:
return
client = self.get_client()
client.stop(self.resource_id)
return self.resource_id
def check_suspend_complete(self, container_id):
status = self._get_container_status(container_id)
return (not status['Running'])
def handle_resume(self):
if not self.resource_id:
return
client = self.get_client()
client.start(self.resource_id)
return self.resource_id
def check_resume_complete(self, container_id):
status = self._get_container_status(container_id)
return status['Running']
def validate(self):
super(DockerContainer, self).validate()
self._validate_arg_for_api_version()
def _validate_arg_for_api_version(self):
version = None
for key in MIN_API_VERSION_MAP:
if self.properties[key]:
if not version:
client = self.get_client()
version = client.version()['ApiVersion']
min_version = MIN_API_VERSION_MAP[key]
if compare_version(min_version, version) < 0:
raise InvalidArgForVersion(arg=key,
min_version=min_version)
def resource_mapping():
return {
'DockerInc::Docker::Container': DockerContainer,
}
def available_resource_mapping():
if DOCKER_INSTALLED:
return resource_mapping()
else:
LOG.warning("Docker plug-in loaded, but docker lib "
"not installed.")
return {}
def compare_version(v1, v2):
s1 = distutils.version.StrictVersion(v1)
s2 = distutils.version.StrictVersion(v2)
if s1 == s2:
return 0
elif s1 > s2:
return -1
else:
return 1
class InvalidArgForVersion(exception.HeatException):
msg_fmt = _('"%(arg)s" is not supported for API version '
'< "%(min_version)s"')

View File

@ -1,120 +0,0 @@
#
# Copyright (c) 2013 Docker, Inc.
# 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.
import mock
import random
import string
class APIError(Exception):
def __init__(self, content, response):
super(APIError, self).__init__(content)
self.response = response
errors = mock.MagicMock()
errors.APIError = APIError
class FakeResponse (object):
def __init__(self, status_code=200, reason='OK'):
self.status_code = status_code
self.reason = reason
self.content = reason
class Client(object):
def __init__(self, endpoint=None):
self._endpoint = endpoint
self._containers = {}
self.pulled_images = []
self.container_create = []
self.container_start = []
self.version_info = {}
def _generate_string(self, n=32):
return ''.join(random.choice(string.ascii_lowercase) for i in range(n))
def _check_exists(self, container_id):
if container_id not in self._containers:
raise APIError(
'404 Client Error: Not Found ("No such container: '
'{0}")'.format(container_id),
FakeResponse(status_code=404,
reason='No such container'))
def _set_running(self, container_id, running):
self._check_exists(container_id)
self._containers[container_id] = running
def inspect_container(self, container_id):
self._check_exists(container_id)
info = {
'Id': container_id,
'NetworkSettings': {
'Bridge': 'docker0',
'Gateway': '172.17.42.1',
'IPAddress': '172.17.0.3',
'IPPrefixLen': 16,
'Ports': {
'80/tcp': [{'HostIp': '0.0.0.0', 'HostPort': '1080'}]
}
},
'State': {
'Running': self._containers[container_id]
}
}
return info
def logs(self, container_id):
logs = ['---logs_begin---']
for i in range(random.randint(1, 20)):
logs.append(self._generate_string(random.randint(5, 42)))
logs.append('---logs_end---')
return '\n'.join(logs)
def create_container(self, **kwargs):
self.container_create.append(kwargs)
container_id = self._generate_string()
self._containers[container_id] = None
self._set_running(container_id, False)
return self.inspect_container(container_id)
def remove_container(self, container_id, **kwargs):
self._check_exists(container_id)
del self._containers[container_id]
def start(self, container_id, **kwargs):
self.container_start.append(kwargs)
self._set_running(container_id, True)
def stop(self, container_id):
self._set_running(container_id, False)
def kill(self, container_id):
self._set_running(container_id, False)
def pull(self, image):
self.pulled_images.append(image)
def version(self, api_version=True):
if not self.version_info:
self.version_info['ApiVersion'] = '1.15'
return self.version_info
def set_api_version(self, version):
self.version_info['ApiVersion'] = version

View File

@ -1,467 +0,0 @@
#
# Copyright (c) 2013 Docker, Inc.
# 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.
import mock
import six
from heat.common import exception
from heat.common.i18n import _
from heat.common import template_format
from heat.engine import resource
from heat.engine import rsrc_defn
from heat.engine import scheduler
from heat.tests import common
from heat.tests import utils
import testtools
from heat_docker.resources import docker_container
from heat_docker.tests import fake_docker_client as docker
docker_container.docker = docker
template = '''
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Test template",
"Parameters": {},
"Resources": {
"Blog": {
"Type": "DockerInc::Docker::Container",
"Properties": {
"image": "samalba/wordpress",
"env": [
"FOO=bar"
]
}
}
}
}
'''
class DockerContainerTest(common.HeatTestCase):
def setUp(self):
super(DockerContainerTest, self).setUp()
for res_name, res_class in docker_container.resource_mapping().items():
resource._register_class(res_name, res_class)
self.addCleanup(self.m.VerifyAll)
def create_container(self, resource_name):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
resource = docker_container.DockerContainer(
resource_name,
self.stack.t.resource_definitions(self.stack)[resource_name],
self.stack)
self.m.StubOutWithMock(resource, 'get_client')
resource.get_client().MultipleTimes().AndReturn(
docker.Client())
self.assertIsNone(resource.validate())
self.m.ReplayAll()
scheduler.TaskRunner(resource.create)()
self.assertEqual((resource.CREATE, resource.COMPLETE),
resource.state)
return resource
def get_container_state(self, resource):
client = resource.get_client()
return client.inspect_container(resource.resource_id)['State']
def test_resource_create(self):
container = self.create_container('Blog')
self.assertTrue(container.resource_id)
running = self.get_container_state(container)['Running']
self.assertIs(True, running)
client = container.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertIsNone(client.container_create[0]['name'])
def test_create_with_name(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['name'] = 'super-blog'
resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
self.m.StubOutWithMock(resource, 'get_client')
resource.get_client().MultipleTimes().AndReturn(
docker.Client())
self.assertIsNone(resource.validate())
self.m.ReplayAll()
scheduler.TaskRunner(resource.create)()
self.assertEqual((resource.CREATE, resource.COMPLETE),
resource.state)
client = resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertEqual('super-blog', client.container_create[0]['name'])
@mock.patch.object(docker_container.DockerContainer, 'get_client')
def test_create_failed(self, test_client):
mock_client = mock.Mock()
mock_client.inspect_container.return_value = {
"State": {
"ExitCode": -1
}
}
mock_client.logs.return_value = "Container startup failed"
test_client.return_value = mock_client
mock_stack = mock.Mock()
mock_stack.has_cache_data.return_value = False
mock_stack.db_resource_get.return_value = None
res_def = mock.Mock(spec=rsrc_defn.ResourceDefinition)
docker_res = docker_container.DockerContainer("test", res_def,
mock_stack)
exc = self.assertRaises(exception.ResourceInError,
docker_res.check_create_complete,
'foo')
self.assertIn("Container startup failed", six.text_type(exc))
def test_start_with_bindings_and_links(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['port_bindings'] = {'80/tcp': [{'HostPort': '80'}]}
props['links'] = {'db': 'mysql'}
resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
self.m.StubOutWithMock(resource, 'get_client')
resource.get_client().MultipleTimes().AndReturn(
docker.Client())
self.assertIsNone(resource.validate())
self.m.ReplayAll()
scheduler.TaskRunner(resource.create)()
self.assertEqual((resource.CREATE, resource.COMPLETE),
resource.state)
client = resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertEqual({'db': 'mysql'}, client.container_start[0]['links'])
self.assertEqual(
{'80/tcp': [{'HostPort': '80'}]},
client.container_start[0]['port_bindings'])
def test_resource_attributes(self):
container = self.create_container('Blog')
# Test network info attributes
self.assertEqual('172.17.42.1', container.FnGetAtt('network_gateway'))
self.assertEqual('172.17.0.3', container.FnGetAtt('network_ip'))
self.assertEqual('1080', container.FnGetAtt('network_tcp_ports'))
self.assertEqual('', container.FnGetAtt('network_udp_ports'))
# Test logs attributes
self.assertEqual('---logs_begin---', container.FnGetAtt('logs_head'))
self.assertEqual('---logs_end---', container.FnGetAtt('logs_tail'))
# Test a non existing attribute
self.assertRaises(exception.InvalidTemplateAttribute,
container.FnGetAtt, 'invalid_attribute')
@testtools.skipIf(docker is None, 'docker-py not available')
def test_resource_delete(self):
container = self.create_container('Blog')
scheduler.TaskRunner(container.delete)()
self.assertEqual((container.DELETE, container.COMPLETE),
container.state)
exists = True
try:
self.get_container_state(container)['Running']
except docker.errors.APIError as error:
if error.response.status_code == 404:
exists = False
else:
raise
self.assertIs(False, exists)
self.m.VerifyAll()
@testtools.skipIf(docker is None, 'docker-py not available')
def test_resource_delete_exception(self):
response = mock.MagicMock()
response.status_code = 404
response.content = 'some content'
container = self.create_container('Blog')
self.m.StubOutWithMock(container.get_client(), 'kill')
container.get_client().kill(container.resource_id).AndRaise(
docker.errors.APIError('Not found', response))
self.m.StubOutWithMock(container, '_get_container_status')
container._get_container_status(container.resource_id).AndRaise(
docker.errors.APIError('Not found', response))
self.m.ReplayAll()
scheduler.TaskRunner(container.delete)()
self.m.VerifyAll()
def test_resource_suspend_resume(self):
container = self.create_container('Blog')
# Test suspend
scheduler.TaskRunner(container.suspend)()
self.assertEqual((container.SUSPEND, container.COMPLETE),
container.state)
running = self.get_container_state(container)['Running']
self.assertIs(False, running)
# Test resume
scheduler.TaskRunner(container.resume)()
self.assertEqual((container.RESUME, container.COMPLETE),
container.state)
running = self.get_container_state(container)['Running']
self.assertIs(True, running)
def test_start_with_restart_policy_no(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['restart_policy'] = {'Name': 'no', 'MaximumRetryCount': 0}
resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(resource, 'get_client')
get_client_mock.return_value = docker.Client()
self.assertIsNone(resource.validate())
scheduler.TaskRunner(resource.create)()
self.assertEqual((resource.CREATE, resource.COMPLETE),
resource.state)
client = resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertEqual({'Name': 'no', 'MaximumRetryCount': 0},
client.container_start[0]['restart_policy'])
def test_start_with_restart_policy_on_failure(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['restart_policy'] = {'Name': 'on-failure',
'MaximumRetryCount': 10}
resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(resource, 'get_client')
get_client_mock.return_value = docker.Client()
self.assertIsNone(resource.validate())
scheduler.TaskRunner(resource.create)()
self.assertEqual((resource.CREATE, resource.COMPLETE),
resource.state)
client = resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertEqual({'Name': 'on-failure', 'MaximumRetryCount': 10},
client.container_start[0]['restart_policy'])
def test_start_with_restart_policy_always(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['restart_policy'] = {'Name': 'always', 'MaximumRetryCount': 0}
resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(resource, 'get_client')
get_client_mock.return_value = docker.Client()
self.assertIsNone(resource.validate())
scheduler.TaskRunner(resource.create)()
self.assertEqual((resource.CREATE, resource.COMPLETE),
resource.state)
client = resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertEqual({'Name': 'always', 'MaximumRetryCount': 0},
client.container_start[0]['restart_policy'])
def test_start_with_caps(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['cap_add'] = ['NET_ADMIN']
props['cap_drop'] = ['MKNOD']
resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(resource, 'get_client')
get_client_mock.return_value = docker.Client()
self.assertIsNone(resource.validate())
scheduler.TaskRunner(resource.create)()
self.assertEqual((resource.CREATE, resource.COMPLETE),
resource.state)
client = resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertEqual(['NET_ADMIN'], client.container_start[0]['cap_add'])
self.assertEqual(['MKNOD'], client.container_start[0]['cap_drop'])
def test_start_with_read_only(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['read_only'] = True
resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(resource, 'get_client')
get_client_mock.return_value = docker.Client()
get_client_mock.return_value.set_api_version('1.17')
self.assertIsNone(resource.validate())
scheduler.TaskRunner(resource.create)()
self.assertEqual((resource.CREATE, resource.COMPLETE),
resource.state)
client = resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertIs(True, client.container_start[0]['read_only'])
def arg_for_low_api_version(self, arg, value, low_version):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props[arg] = value
my_resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(my_resource, 'get_client')
get_client_mock.return_value = docker.Client()
get_client_mock.return_value.set_api_version(low_version)
msg = self.assertRaises(docker_container.InvalidArgForVersion,
my_resource.validate)
min_version = docker_container.MIN_API_VERSION_MAP[arg]
args = dict(arg=arg, min_version=min_version)
expected = _('"%(arg)s" is not supported for API version '
'< "%(min_version)s"') % args
self.assertEqual(expected, six.text_type(msg))
def test_start_with_read_only_for_low_api_version(self):
self.arg_for_low_api_version('read_only', True, '1.16')
def test_compare_version(self):
self.assertEqual(docker_container.compare_version('1.17', '1.17'), 0)
self.assertEqual(docker_container.compare_version('1.17', '1.16'), -1)
self.assertEqual(docker_container.compare_version('1.17', '1.18'), 1)
def test_create_with_cpu_shares(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['cpu_shares'] = 512
my_resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(my_resource, 'get_client')
get_client_mock.return_value = docker.Client()
self.assertIsNone(my_resource.validate())
scheduler.TaskRunner(my_resource.create)()
self.assertEqual((my_resource.CREATE, my_resource.COMPLETE),
my_resource.state)
client = my_resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertEqual(512, client.container_create[0]['cpu_shares'])
def test_create_with_cpu_shares_for_low_api_version(self):
self.arg_for_low_api_version('cpu_shares', 512, '1.7')
def test_start_with_mapping_devices(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['devices'] = (
[{'path_on_host': '/dev/sda',
'path_in_container': '/dev/xvdc',
'permissions': 'r'},
{'path_on_host': '/dev/mapper/a_bc-d',
'path_in_container': '/dev/xvdd',
'permissions': 'rw'}])
my_resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(my_resource, 'get_client')
get_client_mock.return_value = docker.Client()
self.assertIsNone(my_resource.validate())
scheduler.TaskRunner(my_resource.create)()
self.assertEqual((my_resource.CREATE, my_resource.COMPLETE),
my_resource.state)
client = my_resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertEqual(['/dev/sda:/dev/xvdc:r',
'/dev/mapper/a_bc-d:/dev/xvdd:rw'],
client.container_start[0]['devices'])
def test_start_with_mapping_devices_also_with_privileged(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['devices'] = (
[{'path_on_host': '/dev/sdb',
'path_in_container': '/dev/xvdc',
'permissions': 'r'}])
props['privileged'] = True
my_resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(my_resource, 'get_client')
get_client_mock.return_value = docker.Client()
self.assertIsNone(my_resource.validate())
scheduler.TaskRunner(my_resource.create)()
self.assertEqual((my_resource.CREATE, my_resource.COMPLETE),
my_resource.state)
client = my_resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertNotIn('devices', client.container_start[0])
def test_start_with_mapping_devices_for_low_api_version(self):
value = ([{'path_on_host': '/dev/sda',
'path_in_container': '/dev/xvdc',
'permissions': 'rwm'}])
self.arg_for_low_api_version('devices', value, '1.13')
def test_start_with_mapping_devices_not_set_path_in_container(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['devices'] = [{'path_on_host': '/dev/sda',
'permissions': 'rwm'}]
my_resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(my_resource, 'get_client')
get_client_mock.return_value = docker.Client()
self.assertIsNone(my_resource.validate())
scheduler.TaskRunner(my_resource.create)()
self.assertEqual((my_resource.CREATE, my_resource.COMPLETE),
my_resource.state)
client = my_resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertEqual(['/dev/sda:/dev/sda:rwm'],
client.container_start[0]['devices'])
def test_create_with_cpu_set(self):
t = template_format.parse(template)
self.stack = utils.parse_stack(t)
definition = self.stack.t.resource_definitions(self.stack)['Blog']
props = t['Resources']['Blog']['Properties'].copy()
props['cpu_set'] = '0-8,16-24,28'
my_resource = docker_container.DockerContainer(
'Blog', definition.freeze(properties=props), self.stack)
get_client_mock = self.patchobject(my_resource, 'get_client')
get_client_mock.return_value = docker.Client()
self.assertIsNone(my_resource.validate())
scheduler.TaskRunner(my_resource.create)()
self.assertEqual((my_resource.CREATE, my_resource.COMPLETE),
my_resource.state)
client = my_resource.get_client()
self.assertEqual(['samalba/wordpress'], client.pulled_images)
self.assertEqual('0-8,16-24,28',
client.container_create[0]['cpuset'])
def test_create_with_cpu_set_for_low_api_version(self):
self.arg_for_low_api_version('cpu_set', '0-8,^2', '1.11')

Some files were not shown because too many files have changed in this diff Show More