Addapted flame to openstacksdk and shade.
Flame needed pemanent adjustments to mathe the changes in the python-openstackclients. We now use openstacksdk or shade which will handle themselves the compatibility. We also made flame modular so that any-one can add features by implementing there own flame managers and adding their modules to the `openstack_flame` entry point. This new flame version is also fully compatible with python 3. Change-Id: I586a165b5022031963f504874bd50e1b11fe0d27
This commit is contained in:
parent
2cc573d049
commit
e798119841
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
.venv
|
||||||
|
|
||||||
# C extensions
|
# C extensions
|
||||||
*.so
|
*.so
|
||||||
@ -23,6 +24,7 @@ pip-log.txt
|
|||||||
|
|
||||||
# Unit test / coverage reports
|
# Unit test / coverage reports
|
||||||
.coverage
|
.coverage
|
||||||
|
cover
|
||||||
.tox
|
.tox
|
||||||
nosetests.xml
|
nosetests.xml
|
||||||
.testrepository
|
.testrepository
|
||||||
@ -49,3 +51,5 @@ ChangeLog
|
|||||||
# Editors
|
# Editors
|
||||||
*~
|
*~
|
||||||
.*.swp
|
.*.swp
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
28
CONTRIBUTING.rst
Normal file
28
CONTRIBUTING.rst
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
When developping on flameclient, do not forget to check code quality with the
|
||||||
|
`./checkcode` command, and then check you did not brake anything by running
|
||||||
|
`python -m unittest discover -v`.
|
||||||
|
|
||||||
|
To create flame modules you need to create a module with a class which
|
||||||
|
inheritates from `flameclient.resources.ResourceManager`
|
||||||
|
|
||||||
|
You need to implement the `api_resources` property and the `get_hot_resources()`
|
||||||
|
method (read their docstring for more information).
|
||||||
|
If you want you can also implement the `add_arguments(parser=None)` method to
|
||||||
|
add your own module's command line arguments.
|
||||||
|
You can also implement the `post_process()`,
|
||||||
|
`post_process_hot_resources(resources)`, `post_process_heat_template(template)` and/or
|
||||||
|
`post_process_adoption_data(adoption_data)` methods to perform
|
||||||
|
post processing after the generator's `extract_data` method was called
|
||||||
|
(read their docstring for more information). This allows you to modify results
|
||||||
|
before rendering the template.
|
||||||
|
These post processing methods are not threaded and are executed in order of the
|
||||||
|
managers' `post_priority` attribute (defaults to 100).
|
||||||
|
|
||||||
|
Then, you need to add in your package's `setup.py` or `setup.cfg` an
|
||||||
|
'openstack_flame' entry point pointing to the module file where your subclass
|
||||||
|
of `flameclient.resources.ResourceManager` is defined.
|
||||||
|
|
||||||
|
Once your package installed, flame will automatically discover all
|
||||||
|
'openstack_flame' entry points to load the corresponding modules, and all
|
||||||
|
loaded modules having a `flameclient.resources.ResourceManager` subclass will
|
||||||
|
have this subclass detected and added tho the list of managers.
|
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
|||||||
This software is released under the MIT License.
|
|
||||||
|
|
||||||
Copyright (c) 2014 Cloudwatt
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
170
README.rst
170
README.rst
@ -32,64 +32,154 @@ Then just run:
|
|||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
usage: flame [-h] [--username USERNAME] [--password PASSWORD]
|
To use the CLI of flame::
|
||||||
[--project PROJECT] [--region REGION] [--auth_url AUTH_URL]
|
|
||||||
[--os-auth-token OS_AUTH_TOKEN] [--insecure]
|
usage: flame [-h] [--debug] [--generate-stack-data] [--include-constraints]
|
||||||
[--os-cert <certification>] [--os-key <key>]
|
[--no-threads] [--prefetch] [--exclude-keypairs]
|
||||||
[--endpoint_type ENDPOINT_TYPE] [--exclude-servers]
|
[--extract-ports] [--exclude-secgroups] [--exclude-servers]
|
||||||
[--exclude-volumes] [--exclude-keypairs] [--generate-stack-data]
|
[--exclude-volumes] [--os-cloud <name>] [--os-auth-type <name>]
|
||||||
[--extract-ports] [--exclude-secgroup]
|
[--os-auth-url OS_AUTH_URL] [--os-system-scope OS_SYSTEM_SCOPE]
|
||||||
|
[--os-domain-id OS_DOMAIN_ID] [--os-domain-name OS_DOMAIN_NAME]
|
||||||
|
[--os-project-id OS_PROJECT_ID]
|
||||||
|
[--os-project-name OS_PROJECT_NAME]
|
||||||
|
[--os-project-domain-id OS_PROJECT_DOMAIN_ID]
|
||||||
|
[--os-project-domain-name OS_PROJECT_DOMAIN_NAME]
|
||||||
|
[--os-trust-id OS_TRUST_ID]
|
||||||
|
[--os-default-domain-id OS_DEFAULT_DOMAIN_ID]
|
||||||
|
[--os-default-domain-name OS_DEFAULT_DOMAIN_NAME]
|
||||||
|
[--os-user-id OS_USER_ID] [--os-username OS_USERNAME]
|
||||||
|
[--os-user-domain-id OS_USER_DOMAIN_ID]
|
||||||
|
[--os-user-domain-name OS_USER_DOMAIN_NAME]
|
||||||
|
[--os-password OS_PASSWORD] [--insecure]
|
||||||
|
[--os-cacert <ca-certificate>] [--os-cert <certificate>]
|
||||||
|
[--os-key <key>] [--timeout <seconds>] [--collect-timing]
|
||||||
|
[--os-service-type <name>] [--os-service-name <name>]
|
||||||
|
[--os-interface <name>] [--os-region-name <name>]
|
||||||
|
[--os-endpoint-override <name>] [--os-api-version <name>]
|
||||||
|
|
||||||
Heat template and data file generator
|
Heat template and data file generator
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
--username USERNAME A user name with access to the project. Defaults to
|
--debug set debuging log level
|
||||||
env[OS_USERNAME]
|
|
||||||
--password PASSWORD The user's password. Defaults to env[OS_PASSWORD]
|
|
||||||
--project PROJECT Name of project. Defaults to env[OS_TENANT_NAME]
|
|
||||||
--region REGION Name of region. Defaults to env[OS_REGION_NAME]
|
|
||||||
--auth_url AUTH_URL Authentication URL. Defaults to env[OS_AUTH_URL].
|
|
||||||
--os-auth-token OS_AUTH_TOKEN
|
|
||||||
User's auth token. Defaults to env[OS_AUTH_TOKEN].
|
|
||||||
--os-cert <certificate>
|
|
||||||
Path to user's certificate needed to establish
|
|
||||||
two-way SSL connection with the identity service.
|
|
||||||
Defaults to env[OS_CERT].
|
|
||||||
--os-key <key> Path to the user's certificate private key.
|
|
||||||
Defaults to env[OS_KEY].
|
|
||||||
--insecure Explicitly allow clients to perform"insecure" SSL
|
|
||||||
(https) requests. The server's certificate will not be
|
|
||||||
verified against any certificate authorities. This
|
|
||||||
option should be used with caution.
|
|
||||||
--endpoint_type ENDPOINT_TYPE
|
|
||||||
Defaults to env[OS_ENDPOINT_TYPE] or publicURL
|
|
||||||
--exclude-servers Do not export in template server resources
|
|
||||||
--exclude-volumes Do not export in template volume resources
|
|
||||||
--exclude-keypairs Do not export in template key pair resources
|
|
||||||
--generate-stack-data
|
--generate-stack-data
|
||||||
In addition to template, generate Heat stack data
|
In addition to template, generate Heat stack data
|
||||||
file.
|
file.
|
||||||
|
--include-constraints
|
||||||
|
Export in template custom constraints
|
||||||
|
--no-threads Deactivate threads for api calls, (usefull for (i)pdb
|
||||||
|
debugging.
|
||||||
|
--prefetch Prefetch all API calls (works only without --no-
|
||||||
|
threads
|
||||||
|
--exclude-keypairs Do not export in template key pair resources
|
||||||
--extract-ports Export the tenant network ports
|
--extract-ports Export the tenant network ports
|
||||||
--exclude-secgroups Do not export in template security group resources
|
--exclude-secgroups Do not export in template security group resources
|
||||||
|
--exclude-servers Do not export in template server resources
|
||||||
|
--exclude-volumes Do not export in template volume resources
|
||||||
|
--os-cloud <name> Named cloud to connect to
|
||||||
|
--os-auth-type <name>, --os-auth-plugin <name>
|
||||||
|
Authentication type to use
|
||||||
|
|
||||||
|
Authentication Options:
|
||||||
|
Options specific to the password plugin.
|
||||||
|
|
||||||
|
--os-auth-url OS_AUTH_URL
|
||||||
|
Authentication URL
|
||||||
|
--os-system-scope OS_SYSTEM_SCOPE
|
||||||
|
Scope for system operations
|
||||||
|
--os-domain-id OS_DOMAIN_ID
|
||||||
|
Domain ID to scope to
|
||||||
|
--os-domain-name OS_DOMAIN_NAME
|
||||||
|
Domain name to scope to
|
||||||
|
--os-project-id OS_PROJECT_ID, --os-tenant-id OS_PROJECT_ID
|
||||||
|
Project ID to scope to
|
||||||
|
--os-project-name OS_PROJECT_NAME, --os-tenant-name OS_PROJECT_NAME
|
||||||
|
Project name to scope to
|
||||||
|
--os-project-domain-id OS_PROJECT_DOMAIN_ID
|
||||||
|
Domain ID containing project
|
||||||
|
--os-project-domain-name OS_PROJECT_DOMAIN_NAME
|
||||||
|
Domain name containing project
|
||||||
|
--os-trust-id OS_TRUST_ID
|
||||||
|
Trust ID
|
||||||
|
--os-default-domain-id OS_DEFAULT_DOMAIN_ID
|
||||||
|
Optional domain ID to use with v3 and v2 parameters.
|
||||||
|
It will be used for both the user and project domain
|
||||||
|
in v3 and ignored in v2 authentication.
|
||||||
|
--os-default-domain-name OS_DEFAULT_DOMAIN_NAME
|
||||||
|
Optional domain name to use with v3 API and v2
|
||||||
|
parameters. It will be used for both the user and
|
||||||
|
project domain in v3 and ignored in v2 authentication.
|
||||||
|
--os-user-id OS_USER_ID
|
||||||
|
User id
|
||||||
|
--os-username OS_USERNAME, --os-user-name OS_USERNAME
|
||||||
|
Username
|
||||||
|
--os-user-domain-id OS_USER_DOMAIN_ID
|
||||||
|
User's domain id
|
||||||
|
--os-user-domain-name OS_USER_DOMAIN_NAME
|
||||||
|
User's domain name
|
||||||
|
--os-password OS_PASSWORD
|
||||||
|
User's password
|
||||||
|
|
||||||
|
API Connection Options:
|
||||||
|
Options controlling the HTTP API Connections
|
||||||
|
|
||||||
|
--insecure Explicitly allow client to perform "insecure" TLS
|
||||||
|
(https) requests. The server's certificate will not be
|
||||||
|
verified against any certificate authorities. This
|
||||||
|
option should be used with caution.
|
||||||
|
--os-cacert <ca-certificate>
|
||||||
|
Specify a CA bundle file to use in verifying a TLS
|
||||||
|
(https) server certificate. Defaults to
|
||||||
|
env[OS_CACERT].
|
||||||
|
--os-cert <certificate>
|
||||||
|
Defaults to env[OS_CERT].
|
||||||
|
--os-key <key> Defaults to env[OS_KEY].
|
||||||
|
--timeout <seconds> Set request timeout (in seconds).
|
||||||
|
--collect-timing Collect per-API call timing information.
|
||||||
|
|
||||||
|
Service Options:
|
||||||
|
Options controlling the specialization of the API Connection from
|
||||||
|
information found in the catalog
|
||||||
|
|
||||||
|
--os-service-type <name>
|
||||||
|
Service type to request from the catalog
|
||||||
|
--os-service-name <name>
|
||||||
|
Service name to request from the catalog
|
||||||
|
--os-interface <name>
|
||||||
|
API Interface to use [public, internal, admin]
|
||||||
|
--os-region-name <name>
|
||||||
|
Region of the cloud to use
|
||||||
|
--os-endpoint-override <name>
|
||||||
|
Endpoint to use instead of the endpoint in the catalog
|
||||||
|
--os-api-version <name>
|
||||||
|
Which version of the service API to use
|
||||||
|
|
||||||
Usage example
|
Usage example
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
To use Flame you can provide yours OpenStack credentials as arguments :
|
To use Flame you can provide yours OpenStack credentials as arguments ::
|
||||||
|
|
||||||
$ flame --username user --password password --project project
|
|
||||||
--auth_url http://<Keystone_host>:5000/v2.0
|
|
||||||
|
|
||||||
|
$ flame --os-username 'user_name' \
|
||||||
|
--os-password 'password' \
|
||||||
|
--os-project-name 'project_name' \
|
||||||
|
--os-auth-url 'http://<Keystone_host>:5000/v2.0'
|
||||||
|
|
||||||
Or you can source your OpenStack RC file and use Flame without arguments.
|
Or you can source your OpenStack RC file and use Flame without arguments.
|
||||||
|
|
||||||
To establish a two-way SSL connection with the identity service :
|
To establish a two-way SSL connection with the identity service ::
|
||||||
|
|
||||||
$flame --username arezmerita --os-auth-token keystonetoken \
|
$flame --os-username 'user_name' \
|
||||||
--project project-arezmerita --auth_url http://<Keystone_host>:5000/v2.0
|
--os-password 'password' \
|
||||||
--os-cert <path/to/certificate> --os-key <path/to/key>
|
--os-project-name 'project_name' \
|
||||||
|
--os-auth_url http://<Keystone_host>:5000/v2.0 \
|
||||||
|
--os-cert <path/to/certificate> \
|
||||||
|
--os-key <path/to/key>
|
||||||
|
|
||||||
Flame can be used with either a login and password pair or a keystone
|
Flame can be used with either a login and password pair or a keystone
|
||||||
token by exporting the OS_AUTH_TOKEN variable (the token is obtained
|
token by exporting the OS_AUTH_TOKEN variable and the `--os-auth-type 'token'`
|
||||||
with keystone token-get).
|
parameter (the token is obtained with keystone token-get )::
|
||||||
|
|
||||||
|
$ flame --os-auth-type 'token' \
|
||||||
|
--os-token 'token_id' \
|
||||||
|
--os-auth-url 'http://<Keystone_host>:5000/v2.0'
|
||||||
|
|
||||||
|
12
check_code
Executable file
12
check_code
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
CURDIR=$(pwd)
|
||||||
|
SELFDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||||
|
|
||||||
|
cd $SELFDIR
|
||||||
|
python -m flake8 flameclient
|
||||||
|
if [[ $1 = '-v' ]]; then
|
||||||
|
python -m pylint --rcfile=pylintrc --reports=yes flameclient
|
||||||
|
else
|
||||||
|
python -m pylint --rcfile=pylintrc flameclient
|
||||||
|
fi
|
||||||
|
cd $CURDIR
|
4
dev-requirements.txt
Normal file
4
dev-requirements.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
bpython==0.17.1
|
||||||
|
ipython==5.8.0
|
||||||
|
ipdb==0.11
|
||||||
|
q==2.6
|
@ -10,3 +10,4 @@ Or, if you have virtualenvwrapper installed::
|
|||||||
|
|
||||||
$ mkvirtualenv python-flameclient
|
$ mkvirtualenv python-flameclient
|
||||||
$ pip install python-flameclient
|
$ pip install python-flameclient
|
||||||
|
|
||||||
|
@ -14,5 +14,3 @@ free IP addresses of a pool, for example, with a pool starting at 10.0.0.2 :
|
|||||||
When this stack is imported in Heat, the DHCP server IP is set to the lowest
|
When this stack is imported in Heat, the DHCP server IP is set to the lowest
|
||||||
free IP address of its pool. Depending on the VM creation order, the DHCP
|
free IP address of its pool. Depending on the VM creation order, the DHCP
|
||||||
address can either collide with vm1's or vm2's IP.
|
address can either collide with vm1's or vm2's IP.
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,45 +8,125 @@ To use install flame in a project::
|
|||||||
|
|
||||||
To use the CLI of flame::
|
To use the CLI of flame::
|
||||||
|
|
||||||
usage: flame [-h] [--username USERNAME] [--password PASSWORD]
|
usage: flame [-h] [--debug] [--generate-stack-data] [--include-constraints]
|
||||||
[--project PROJECT] [--region REGION] [--auth_url AUTH_URL]
|
[--no-threads] [--prefetch] [--exclude-keypairs]
|
||||||
[--os-auth-token OS_AUTH_TOKEN] [--insecure]
|
[--extract-ports] [--exclude-secgroups] [--exclude-servers]
|
||||||
[--os-cert <certification>] [--os-key <key>]
|
[--exclude-volumes] [--os-cloud <name>] [--os-auth-type <name>]
|
||||||
[--endpoint_type ENDPOINT_TYPE] [--exclude-servers]
|
[--os-auth-url OS_AUTH_URL] [--os-system-scope OS_SYSTEM_SCOPE]
|
||||||
[--exclude-volumes] [--exclude-keypairs] [--generate-stack-data]
|
[--os-domain-id OS_DOMAIN_ID] [--os-domain-name OS_DOMAIN_NAME]
|
||||||
[--extract-ports]
|
[--os-project-id OS_PROJECT_ID]
|
||||||
|
[--os-project-name OS_PROJECT_NAME]
|
||||||
|
[--os-project-domain-id OS_PROJECT_DOMAIN_ID]
|
||||||
|
[--os-project-domain-name OS_PROJECT_DOMAIN_NAME]
|
||||||
|
[--os-trust-id OS_TRUST_ID]
|
||||||
|
[--os-default-domain-id OS_DEFAULT_DOMAIN_ID]
|
||||||
|
[--os-default-domain-name OS_DEFAULT_DOMAIN_NAME]
|
||||||
|
[--os-user-id OS_USER_ID] [--os-username OS_USERNAME]
|
||||||
|
[--os-user-domain-id OS_USER_DOMAIN_ID]
|
||||||
|
[--os-user-domain-name OS_USER_DOMAIN_NAME]
|
||||||
|
[--os-password OS_PASSWORD] [--insecure]
|
||||||
|
[--os-cacert <ca-certificate>] [--os-cert <certificate>]
|
||||||
|
[--os-key <key>] [--timeout <seconds>] [--collect-timing]
|
||||||
|
[--os-service-type <name>] [--os-service-name <name>]
|
||||||
|
[--os-interface <name>] [--os-region-name <name>]
|
||||||
|
[--os-endpoint-override <name>] [--os-api-version <name>]
|
||||||
|
|
||||||
Heat template and data file generator
|
Heat template and data file generator
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
--username USERNAME A user name with access to the project. Defaults to
|
--debug set debuging log level
|
||||||
env[OS_USERNAME]
|
|
||||||
--password PASSWORD The user's password. Defaults to env[OS_PASSWORD]
|
|
||||||
--project PROJECT Name of project. Defaults to env[OS_TENANT_NAME]
|
|
||||||
--region REGION Name of region. Defaults to env[OS_REGION_NAME]
|
|
||||||
--auth_url AUTH_URL Authentication URL. Defaults to env[OS_AUTH_URL].
|
|
||||||
--os-auth-token OS_AUTH_TOKEN
|
|
||||||
User's auth token. Defaults to env[OS_AUTH_TOKEN].
|
|
||||||
--os-cert <certificate>
|
|
||||||
Path to user's certificate needed to establish
|
|
||||||
two-way SSL connection with the identity service.
|
|
||||||
Defaults to env[OS_CERT].
|
|
||||||
--os-key <key> Path to the user's certificate private key.
|
|
||||||
Defaults to env[OS_KEY].
|
|
||||||
--insecure Explicitly allow clients to perform"insecure" SSL
|
|
||||||
(https) requests. The server's certificate will not be
|
|
||||||
verified against any certificate authorities. This
|
|
||||||
option should be used with caution.
|
|
||||||
--endpoint_type ENDPOINT_TYPE
|
|
||||||
Defaults to env[OS_ENDPOINT_TYPE] or publicURL
|
|
||||||
--exclude-servers Do not export in template server resources
|
|
||||||
--exclude-volumes Do not export in template volume resources
|
|
||||||
--exclude-keypairs Do not export in template key pair resources
|
|
||||||
--generate-stack-data
|
--generate-stack-data
|
||||||
In addition to template, generate Heat stack data
|
In addition to template, generate Heat stack data
|
||||||
file.
|
file.
|
||||||
|
--include-constraints
|
||||||
|
Export in template custom constraints
|
||||||
|
--no-threads Deactivate threads for api calls, (usefull for (i)pdb
|
||||||
|
debugging.
|
||||||
|
--prefetch Prefetch all API calls (works only without --no-
|
||||||
|
threads
|
||||||
|
--exclude-keypairs Do not export in template key pair resources
|
||||||
--extract-ports Export the tenant network ports
|
--extract-ports Export the tenant network ports
|
||||||
|
--exclude-secgroups Do not export in template security group resources
|
||||||
|
--exclude-servers Do not export in template server resources
|
||||||
|
--exclude-volumes Do not export in template volume resources
|
||||||
|
--os-cloud <name> Named cloud to connect to
|
||||||
|
--os-auth-type <name>, --os-auth-plugin <name>
|
||||||
|
Authentication type to use
|
||||||
|
|
||||||
|
Authentication Options:
|
||||||
|
Options specific to the password plugin.
|
||||||
|
|
||||||
|
--os-auth-url OS_AUTH_URL
|
||||||
|
Authentication URL
|
||||||
|
--os-system-scope OS_SYSTEM_SCOPE
|
||||||
|
Scope for system operations
|
||||||
|
--os-domain-id OS_DOMAIN_ID
|
||||||
|
Domain ID to scope to
|
||||||
|
--os-domain-name OS_DOMAIN_NAME
|
||||||
|
Domain name to scope to
|
||||||
|
--os-project-id OS_PROJECT_ID, --os-tenant-id OS_PROJECT_ID
|
||||||
|
Project ID to scope to
|
||||||
|
--os-project-name OS_PROJECT_NAME, --os-tenant-name OS_PROJECT_NAME
|
||||||
|
Project name to scope to
|
||||||
|
--os-project-domain-id OS_PROJECT_DOMAIN_ID
|
||||||
|
Domain ID containing project
|
||||||
|
--os-project-domain-name OS_PROJECT_DOMAIN_NAME
|
||||||
|
Domain name containing project
|
||||||
|
--os-trust-id OS_TRUST_ID
|
||||||
|
Trust ID
|
||||||
|
--os-default-domain-id OS_DEFAULT_DOMAIN_ID
|
||||||
|
Optional domain ID to use with v3 and v2 parameters.
|
||||||
|
It will be used for both the user and project domain
|
||||||
|
in v3 and ignored in v2 authentication.
|
||||||
|
--os-default-domain-name OS_DEFAULT_DOMAIN_NAME
|
||||||
|
Optional domain name to use with v3 API and v2
|
||||||
|
parameters. It will be used for both the user and
|
||||||
|
project domain in v3 and ignored in v2 authentication.
|
||||||
|
--os-user-id OS_USER_ID
|
||||||
|
User id
|
||||||
|
--os-username OS_USERNAME, --os-user-name OS_USERNAME
|
||||||
|
Username
|
||||||
|
--os-user-domain-id OS_USER_DOMAIN_ID
|
||||||
|
User's domain id
|
||||||
|
--os-user-domain-name OS_USER_DOMAIN_NAME
|
||||||
|
User's domain name
|
||||||
|
--os-password OS_PASSWORD
|
||||||
|
User's password
|
||||||
|
|
||||||
|
API Connection Options:
|
||||||
|
Options controlling the HTTP API Connections
|
||||||
|
|
||||||
|
--insecure Explicitly allow client to perform "insecure" TLS
|
||||||
|
(https) requests. The server's certificate will not be
|
||||||
|
verified against any certificate authorities. This
|
||||||
|
option should be used with caution.
|
||||||
|
--os-cacert <ca-certificate>
|
||||||
|
Specify a CA bundle file to use in verifying a TLS
|
||||||
|
(https) server certificate. Defaults to
|
||||||
|
env[OS_CACERT].
|
||||||
|
--os-cert <certificate>
|
||||||
|
Defaults to env[OS_CERT].
|
||||||
|
--os-key <key> Defaults to env[OS_KEY].
|
||||||
|
--timeout <seconds> Set request timeout (in seconds).
|
||||||
|
--collect-timing Collect per-API call timing information.
|
||||||
|
|
||||||
|
Service Options:
|
||||||
|
Options controlling the specialization of the API Connection from
|
||||||
|
information found in the catalog
|
||||||
|
|
||||||
|
--os-service-type <name>
|
||||||
|
Service type to request from the catalog
|
||||||
|
--os-service-name <name>
|
||||||
|
Service name to request from the catalog
|
||||||
|
--os-interface <name>
|
||||||
|
API Interface to use [public, internal, admin]
|
||||||
|
--os-region-name <name>
|
||||||
|
Region of the cloud to use
|
||||||
|
--os-endpoint-override <name>
|
||||||
|
Endpoint to use instead of the endpoint in the catalog
|
||||||
|
--os-api-version <name>
|
||||||
|
Which version of the service API to use
|
||||||
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
@ -54,21 +134,28 @@ Example
|
|||||||
|
|
||||||
To use Flame you can provide yours OpenStack credentials as arguments::
|
To use Flame you can provide yours OpenStack credentials as arguments::
|
||||||
|
|
||||||
$ flame --username arezmerita --password password \
|
$ flame --os-username 'user_name' \
|
||||||
--project project-arezmerita --auth_url https://example.com/v2.0/
|
--os-password 'password' \
|
||||||
|
--os-project-name 'project_name' \
|
||||||
|
--os-auth-url 'http://<Keystone_host>:5000/v2.0'
|
||||||
|
|
||||||
Or a token and a tenant::
|
Or a token and a tenant::
|
||||||
|
|
||||||
$ flame --username arezmerita --os-auth-token keystonetoken \
|
$ flame --os-auth-type 'token' \
|
||||||
--project project-arezmerita --auth_url https://example.com/v2.0/
|
--os-token 'token_id' \
|
||||||
|
--os-auth-url 'http://<Keystone_host>:5000/v2.0'
|
||||||
|
|
||||||
To establish a two-way SSL connection with the identity service ::
|
To establish a two-way SSL connection with the identity service ::
|
||||||
|
|
||||||
$flame --username arezmerita --os-auth-token keystonetoken \
|
$flame --os-username 'user_name' \
|
||||||
--project project-arezmerita --auth_url https://example.com/v2.0/
|
--os-password 'password' \
|
||||||
--os-cert <path/to/certificate> --os-key <path/to/key>
|
--os-project-name 'project_name' \
|
||||||
|
--os-auth_url http://<Keystone_host>:5000/v2.0 \
|
||||||
|
--os-cert <path/to/certificate> \
|
||||||
|
--os-key <path/to/key>
|
||||||
|
|
||||||
Or you can source your OpenStack RC file and use Flame without arguments::
|
Or you can source your OpenStack RC file and use Flame without arguments::
|
||||||
|
|
||||||
$ source credential.rc
|
$ source credential.rc
|
||||||
$ flame
|
$ flame
|
||||||
|
|
||||||
|
21
flameclient/LICENSE.txt
Normal file
21
flameclient/LICENSE.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
This software is released under the MIT License.
|
||||||
|
|
||||||
|
Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
@ -1,20 +1,30 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# This software is released under the MIT License.
|
||||||
# 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
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# in the Software without restriction, including without limitation the rights
|
||||||
# License for the specific language governing permissions and limitations
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# under the License.
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
import pbr.version
|
import pbr.version
|
||||||
|
|
||||||
try:
|
try:
|
||||||
__version__ = pbr.version.VersionInfo('flameclient').version_string()
|
__version__ = pbr.version.VersionInfo('flameclient').version_string()
|
||||||
except Exception:
|
except Exception: # pylint: disable=W0703
|
||||||
__version__ = 'unknown'
|
__version__ = 'unknown'
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# This software is released under the MIT License.
|
|
||||||
#
|
|
||||||
# Copyright (c) 2014 Cloudwatt
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
# SOFTWARE.
|
|
||||||
|
|
||||||
from flameclient.flame import TemplateGenerator # noqa
|
|
||||||
|
|
||||||
|
|
||||||
class Client(object):
|
|
||||||
def __init__(self, username, password, tenant_name, auth_url, auth_token,
|
|
||||||
**kwargs):
|
|
||||||
self.template_generator = TemplateGenerator(username, password,
|
|
||||||
tenant_name, auth_url,
|
|
||||||
auth_token,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
def generate(self, exclude_servers, exclude_volumes, exclude_keypairs,
|
|
||||||
generate_stack_data, extract_ports=False,
|
|
||||||
exclude_secgroups=False):
|
|
||||||
self.template_generator.extract_vm_details(exclude_servers,
|
|
||||||
exclude_volumes,
|
|
||||||
exclude_keypairs,
|
|
||||||
generate_stack_data,
|
|
||||||
extract_ports,
|
|
||||||
exclude_secgroups
|
|
||||||
)
|
|
||||||
self.template_generator.extract_data()
|
|
||||||
return self.template_generator.heat_template_and_data()
|
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# This software is released under the MIT License.
|
# This software is released under the MIT License.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 Cloudwatt
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -22,95 +22,59 @@
|
|||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
|
|
||||||
from __future__ import print_function
|
from flameclient import flame
|
||||||
|
|
||||||
import argparse
|
|
||||||
import os
|
|
||||||
|
|
||||||
from flameclient import client
|
|
||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main():
|
||||||
desc = "Heat template and data file generator"
|
"""Flame heat template generation
|
||||||
parser = argparse.ArgumentParser(description=desc)
|
|
||||||
parser.add_argument("--username", type=str,
|
|
||||||
default=os.environ.get("OS_USERNAME"),
|
|
||||||
help="A user name with access to the project. "
|
|
||||||
"Defaults to env[OS_USERNAME]")
|
|
||||||
parser.add_argument("--password", type=str,
|
|
||||||
default=os.environ.get("OS_PASSWORD"),
|
|
||||||
help="The user's password. "
|
|
||||||
"Defaults to env[OS_PASSWORD]")
|
|
||||||
parser.add_argument("--project", type=str,
|
|
||||||
default=os.environ.get("OS_TENANT_NAME"),
|
|
||||||
help="Name of project. "
|
|
||||||
"Defaults to env[OS_TENANT_NAME]")
|
|
||||||
parser.add_argument("--region",
|
|
||||||
default=os.environ.get("OS_REGION_NAME"),
|
|
||||||
help="Name of region. "
|
|
||||||
"Defaults to env[OS_REGION_NAME]")
|
|
||||||
parser.add_argument("--auth_url", type=str,
|
|
||||||
default=os.environ.get("OS_AUTH_URL"),
|
|
||||||
help="Authentication URL. "
|
|
||||||
"Defaults to env[OS_AUTH_URL].")
|
|
||||||
parser.add_argument("--os-auth-token", type=str,
|
|
||||||
default=os.environ.get("OS_AUTH_TOKEN"),
|
|
||||||
help="User's auth token. "
|
|
||||||
"Defaults to env[OS_AUTH_TOKEN].")
|
|
||||||
parser.add_argument('--insecure', action='store_true', default=False,
|
|
||||||
help="Explicitly allow clients to perform"
|
|
||||||
"\"insecure\" SSL (https) requests. The "
|
|
||||||
"server's certificate will not be verified "
|
|
||||||
"against any certificate authorities. This "
|
|
||||||
"option should be used with caution.")
|
|
||||||
parser.add_argument("--endpoint_type", type=str,
|
|
||||||
default=os.environ.get("OS_ENDPOINT_TYPE",
|
|
||||||
"publicURL"),
|
|
||||||
help="Defaults to env[OS_ENDPOINT_TYPE] or publicURL")
|
|
||||||
parser.add_argument("--os-cert", type=str, metavar='<certificate>',
|
|
||||||
default=os.environ.get("OS_CERT"),
|
|
||||||
help="User's certificate. "
|
|
||||||
"Defaults to env[OS_CERT].")
|
|
||||||
parser.add_argument("--os-key", type=str, metavar='<key>',
|
|
||||||
default=os.environ.get("OS_KEY"),
|
|
||||||
help="User's key. "
|
|
||||||
"Defaults to env[OS_KEY].")
|
|
||||||
parser.add_argument('--exclude-servers', action='store_true',
|
|
||||||
default=False,
|
|
||||||
help="Do not export in template server resources")
|
|
||||||
parser.add_argument('--exclude-volumes', action='store_true',
|
|
||||||
default=False,
|
|
||||||
help="Do not export in template volume resources")
|
|
||||||
parser.add_argument('--exclude-keypairs', action='store_true',
|
|
||||||
default=False,
|
|
||||||
help="Do not export in template key pair resources")
|
|
||||||
parser.add_argument('--generate-stack-data', action='store_true',
|
|
||||||
default=False,
|
|
||||||
help="In addition to template, generate Heat "
|
|
||||||
"stack data file.")
|
|
||||||
parser.add_argument('--extract-ports', action='store_true',
|
|
||||||
default=False,
|
|
||||||
help="Export the tenant network ports")
|
|
||||||
parser.add_argument('--exclude-secgroups', action='store_true',
|
|
||||||
default=False,
|
|
||||||
help="Do not export in template "
|
|
||||||
"security group resources")
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
Flame can be used with a shade or openstack sdk instance, and options can
|
||||||
flame = client.Client(args.username, args.password,
|
be passed as option kwargs.
|
||||||
args.project, args.auth_url,
|
|
||||||
args.os_auth_token,
|
ex:
|
||||||
cert=args.os_cert, key=args.os_key,
|
|
||||||
region_name=args.region,
|
from flameclient.session import get_shade
|
||||||
endpoint_type=args.endpoint_type,
|
from flameclient import flame
|
||||||
insecure=args.insecure)
|
|
||||||
template = flame.template_generator
|
auth_kwargs = {
|
||||||
template.extract_vm_details(args.exclude_servers,
|
'auth_type': u'password',
|
||||||
args.exclude_volumes,
|
'auth_url': 'https://your_cloud_identity_url/v2.0',
|
||||||
args.exclude_keypairs,
|
'interface': 'public',
|
||||||
args.generate_stack_data,
|
'password': 'YourPassword',
|
||||||
args.extract_ports,
|
'project_id': 'YourProjectID',
|
||||||
args.exclude_secgroups)
|
'project_name': 'YourProjectName',
|
||||||
template.extract_data()
|
'region_name': 'region_one',
|
||||||
print("### Heat Template ###")
|
'username': 'YourUserName'
|
||||||
print(template.heat_template_and_data())
|
}
|
||||||
|
|
||||||
|
cloud = get_shade(**auth_kwargs)
|
||||||
|
|
||||||
|
Or instead of kwargs if you want to use environment variables:
|
||||||
|
|
||||||
|
cloud = get_shade(load_envvars=True)
|
||||||
|
|
||||||
|
Then:
|
||||||
|
|
||||||
|
generator = flame.TemplateGenerator(
|
||||||
|
connection=cloud,
|
||||||
|
options=dict(
|
||||||
|
include_constraint=True,
|
||||||
|
extract_ports=True,
|
||||||
|
generate_adoption_data=True,
|
||||||
|
no_threads=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
generator.extract_data()
|
||||||
|
print(generator.heat_template_and_data())
|
||||||
|
|
||||||
|
Passing a shade or openstack sdk instance and option kwargs allows you to
|
||||||
|
integrate shade in other projects.
|
||||||
|
|
||||||
|
"""
|
||||||
|
template_generator = flame.TemplateGenerator()
|
||||||
|
template_generator.extract_data()
|
||||||
|
template_generator.output_template_and_data()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
32
flameclient/collections_abc.py
Normal file
32
flameclient/collections_abc.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
try:
|
||||||
|
# This is not handled by six.moves yet:
|
||||||
|
# https://github.com/benjaminp/six/issues/155
|
||||||
|
from collections.abc import * # noqa pylint: disable=W0401,W0614
|
||||||
|
from collections.abc import __all__ # noqa
|
||||||
|
except ImportError:
|
||||||
|
from _abcoll import * # noqa pylint: disable=W0401,W0614
|
||||||
|
from _abcoll import __all__ # noqa
|
1032
flameclient/flame.py
1032
flameclient/flame.py
File diff suppressed because it is too large
Load Diff
98
flameclient/logs.py
Normal file
98
flameclient/logs.py
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from logging.config import dictConfig
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
COLOR_LOGS = sys.stdout.isatty()
|
||||||
|
|
||||||
|
|
||||||
|
class CWColorFormatter(logging.Formatter):
|
||||||
|
"""Special Formatter adding color to logs.
|
||||||
|
|
||||||
|
color is not added if settings.DEBUG is True to prevent syslog cluttering
|
||||||
|
when in production.
|
||||||
|
|
||||||
|
This Formatter is just Candy for developers.
|
||||||
|
"""
|
||||||
|
LEVEL_COLORS = {
|
||||||
|
logging.NOTSET: '\033[01;0m', # Reset color
|
||||||
|
logging.DEBUG: '\033[00;32m', # GREEN
|
||||||
|
logging.INFO: '\033[00;36m', # CYAN
|
||||||
|
# Where did this one go?:
|
||||||
|
# logging.AUDIT: '\033[01;36m', # BOLD CYAN
|
||||||
|
logging.WARN: '\033[01;33m', # BOLD YELLOW
|
||||||
|
logging.ERROR: '\033[01;31m', # BOLD RED
|
||||||
|
logging.CRITICAL: '\033[01;31m', # BOLD RED
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_color = '\033[01;0m'
|
||||||
|
|
||||||
|
def format(self, record):
|
||||||
|
if COLOR_LOGS:
|
||||||
|
record.reset_color = self.reset_color
|
||||||
|
record.color = self.LEVEL_COLORS[record.levelno]
|
||||||
|
else:
|
||||||
|
# We do not want colors in production because syslog does not
|
||||||
|
# handle them.
|
||||||
|
record.reset_color = ''
|
||||||
|
record.color = ''
|
||||||
|
return super(CWColorFormatter, self).format(record)
|
||||||
|
|
||||||
|
|
||||||
|
LOGGING_CONFIG = {
|
||||||
|
'version': 1,
|
||||||
|
'disable_existing_loggers': False,
|
||||||
|
'formatters': {
|
||||||
|
'standard': {
|
||||||
|
'()': CWColorFormatter,
|
||||||
|
'format': '%(color)s%(levelname)s: %(pathname)s %(funcName)s %(lineno)d:%(reset_color)s %(message)s' # noqa
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
|
'default': {
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'formatter': 'standard',
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'loggers': {
|
||||||
|
'': {
|
||||||
|
'handlers': ['default'],
|
||||||
|
'level': 'INFO',
|
||||||
|
'propagate': True
|
||||||
|
},
|
||||||
|
'flameclient': {
|
||||||
|
'handlers': ['default'],
|
||||||
|
# This can be overriden in the config's logging section
|
||||||
|
'level': 'INFO',
|
||||||
|
'propagate': False
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dictConfig(LOGGING_CONFIG)
|
@ -1,228 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# This software is released under the MIT License.
|
|
||||||
#
|
|
||||||
# Copyright (c) 2014 Cloudwatt
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
# SOFTWARE.
|
|
||||||
|
|
||||||
from cinderclient.v1 import client as cinder_client
|
|
||||||
from keystoneclient.v2_0 import client as keystone_client
|
|
||||||
from neutronclient.v2_0 import client as neutron_client
|
|
||||||
from novaclient import client as nova_client
|
|
||||||
|
|
||||||
|
|
||||||
class KeystoneManager(object):
|
|
||||||
"""Manages Keystone queries."""
|
|
||||||
_client = None
|
|
||||||
|
|
||||||
def __init__(self, username, password, project, auth_url, insecure,
|
|
||||||
endpoint_type='publicURL', cert=None, key=None,
|
|
||||||
region_name=None, auth_token=None):
|
|
||||||
self.username = username
|
|
||||||
self.password = password
|
|
||||||
self.project = project
|
|
||||||
self.auth_url = auth_url
|
|
||||||
self.cert = cert
|
|
||||||
self.key = key
|
|
||||||
self.insecure = insecure
|
|
||||||
self.region_name = region_name
|
|
||||||
self.endpoint_type = endpoint_type
|
|
||||||
self.auth_token = auth_token
|
|
||||||
|
|
||||||
def authenticate(self):
|
|
||||||
self.client().authenticate()
|
|
||||||
self.auth_token = self.client().auth_token
|
|
||||||
|
|
||||||
def client(self):
|
|
||||||
if not self._client:
|
|
||||||
self._client = keystone_client.Client(
|
|
||||||
username=self.username,
|
|
||||||
password=self.password,
|
|
||||||
tenant_name=self.project,
|
|
||||||
auth_url=self.auth_url,
|
|
||||||
cert=self.cert,
|
|
||||||
key=self.key,
|
|
||||||
region_name=self.region_name,
|
|
||||||
insecure=self.insecure,
|
|
||||||
endpoint_type=self.endpoint_type,
|
|
||||||
token=self.auth_token)
|
|
||||||
return self._client
|
|
||||||
|
|
||||||
def set_client(self, client):
|
|
||||||
self._client = client
|
|
||||||
|
|
||||||
def get_token(self):
|
|
||||||
return self.client().auth_token
|
|
||||||
|
|
||||||
def get_endpoint(self, service_type, endpoint_type="publicURL"):
|
|
||||||
catalog = self.client().service_catalog.get_endpoints()
|
|
||||||
return catalog[service_type][0][endpoint_type]
|
|
||||||
|
|
||||||
def get_project_id(self):
|
|
||||||
return self.client().project_id
|
|
||||||
|
|
||||||
|
|
||||||
class NeutronManager(object):
|
|
||||||
_client = None
|
|
||||||
_project_id = None
|
|
||||||
|
|
||||||
def __init__(self, keystone_mgr):
|
|
||||||
self.keystone_mgr = keystone_mgr
|
|
||||||
|
|
||||||
def client(self):
|
|
||||||
if not self._client:
|
|
||||||
# Create the client
|
|
||||||
self._client = neutron_client.Client(
|
|
||||||
auth_url=self.keystone_mgr.auth_url,
|
|
||||||
insecure=self.keystone_mgr.insecure,
|
|
||||||
endpoint_url=self.keystone_mgr.get_endpoint('network'),
|
|
||||||
token=self.keystone_mgr.auth_token)
|
|
||||||
if not self._project_id:
|
|
||||||
self._project_id = self.keystone_mgr.get_project_id()
|
|
||||||
return self._client
|
|
||||||
|
|
||||||
def set_client(self, client):
|
|
||||||
self._client = client
|
|
||||||
|
|
||||||
def set_project_id(self, project_id):
|
|
||||||
self._project_id = project_id
|
|
||||||
|
|
||||||
def router_list(self):
|
|
||||||
return filter(self._owned_resource,
|
|
||||||
self.client().list_routers()['routers'])
|
|
||||||
|
|
||||||
def router_interfaces_list(self, router):
|
|
||||||
return self._client.list_ports(device_id=router['id'])['ports']
|
|
||||||
|
|
||||||
def port_list(self):
|
|
||||||
return self.client().list_ports()['ports']
|
|
||||||
|
|
||||||
def network_list(self):
|
|
||||||
return filter(self._owned_resource,
|
|
||||||
self.client().list_networks()['networks'])
|
|
||||||
|
|
||||||
def secgroup_list(self):
|
|
||||||
return filter(self._owned_resource,
|
|
||||||
self.client().list_security_groups()['security_groups'])
|
|
||||||
|
|
||||||
def floatingip_list(self):
|
|
||||||
return filter(self._owned_resource,
|
|
||||||
self.client().list_floatingips()['floatingips'])
|
|
||||||
|
|
||||||
def subnet_list(self):
|
|
||||||
return filter(self._owned_resource,
|
|
||||||
self.client().list_subnets()['subnets'])
|
|
||||||
|
|
||||||
def _owned_resource(self, res):
|
|
||||||
# Only considering resources owned by project
|
|
||||||
return res['tenant_id'] == self._project_id
|
|
||||||
|
|
||||||
|
|
||||||
class NovaManager(object):
|
|
||||||
"""Manage nova resources."""
|
|
||||||
_client = None
|
|
||||||
|
|
||||||
def __init__(self, keystone_mgr):
|
|
||||||
self.keystone_mgr = keystone_mgr
|
|
||||||
|
|
||||||
def client(self):
|
|
||||||
if not self._client:
|
|
||||||
self._client = nova_client.Client(
|
|
||||||
'2',
|
|
||||||
self.keystone_mgr.username,
|
|
||||||
self.keystone_mgr.auth_token,
|
|
||||||
self.keystone_mgr.project,
|
|
||||||
self.keystone_mgr.auth_url,
|
|
||||||
region_name=self.keystone_mgr.region_name,
|
|
||||||
insecure=self.keystone_mgr.insecure,
|
|
||||||
endpoint_type=self.keystone_mgr.endpoint_type,
|
|
||||||
auth_token=self.keystone_mgr.auth_token
|
|
||||||
)
|
|
||||||
return self._client
|
|
||||||
|
|
||||||
def set_client(self, client):
|
|
||||||
self._client = client
|
|
||||||
|
|
||||||
def server_list(self):
|
|
||||||
return self.client().servers.list()
|
|
||||||
|
|
||||||
def floating_ip_list(self):
|
|
||||||
return self.client().floating_ips.list()
|
|
||||||
|
|
||||||
def flavor_list(self):
|
|
||||||
return self.client().flavors.list()
|
|
||||||
|
|
||||||
def flavor_get(self, id):
|
|
||||||
return self.client().flavors.get(id)
|
|
||||||
|
|
||||||
def keypair_list(self):
|
|
||||||
return self.client().keypairs.list()
|
|
||||||
|
|
||||||
def keypair_show(self, keypair):
|
|
||||||
return self.client().keypairs.get(keypair)
|
|
||||||
|
|
||||||
def server_security_group_list(self, server):
|
|
||||||
return self.client().servers.list_security_group(server)
|
|
||||||
|
|
||||||
def servergroup_list(self):
|
|
||||||
return self.client().server_groups.list(True)
|
|
||||||
|
|
||||||
|
|
||||||
class CinderManager(object):
|
|
||||||
"""Manage Cinder resources."""
|
|
||||||
_client = None
|
|
||||||
|
|
||||||
def __init__(self, keystone_mgr):
|
|
||||||
self.keystone_mgr = keystone_mgr
|
|
||||||
self.defined = True
|
|
||||||
|
|
||||||
def client(self):
|
|
||||||
if self.defined and not self._client:
|
|
||||||
try:
|
|
||||||
cinder_url = self.keystone_mgr.get_endpoint("volumev2")
|
|
||||||
except KeyError:
|
|
||||||
cinder_url = self.keystone_mgr.get_endpoint("volume")
|
|
||||||
client = cinder_client.Client(
|
|
||||||
self.keystone_mgr.username,
|
|
||||||
self.keystone_mgr.auth_token,
|
|
||||||
project_id=self.keystone_mgr.project,
|
|
||||||
auth_url=cinder_url,
|
|
||||||
http_log_debug=True,
|
|
||||||
insecure=self.keystone_mgr.insecure
|
|
||||||
)
|
|
||||||
client.client.auth_token = self.keystone_mgr.auth_token
|
|
||||||
client.client.management_url = cinder_url
|
|
||||||
self._client = client
|
|
||||||
return self._client
|
|
||||||
|
|
||||||
def set_client(self, client):
|
|
||||||
self._client = client
|
|
||||||
|
|
||||||
def volume_list(self):
|
|
||||||
volumes = []
|
|
||||||
client = self.client()
|
|
||||||
if client:
|
|
||||||
for vol in client.volumes.list():
|
|
||||||
volumes.append(client.volumes.get(vol.id))
|
|
||||||
return volumes
|
|
||||||
|
|
||||||
def snapshot_list(self):
|
|
||||||
client = self.client()
|
|
||||||
return client.volume_snapshots.list() if client else []
|
|
574
flameclient/resources/__init__.py
Normal file
574
flameclient/resources/__init__.py
Normal file
@ -0,0 +1,574 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import abc
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import six
|
||||||
|
from six.moves import UserDict
|
||||||
|
|
||||||
|
from flameclient.utils import camel_to_snake
|
||||||
|
from flameclient.utils import ClassProperty
|
||||||
|
from flameclient.utils import clean_dict
|
||||||
|
from flameclient.utils import load_resource_entry_points
|
||||||
|
from flameclient.utils import load_resource_modules
|
||||||
|
from flameclient.utils import munchify
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class BaseHotResource(object):
|
||||||
|
"""Describes a heat resource from parameters
|
||||||
|
|
||||||
|
:param ResourceManager manager:
|
||||||
|
A ResourceManager instance.
|
||||||
|
This instance is necessary to have access to the manager's
|
||||||
|
openstack.connection.Connection instance
|
||||||
|
|
||||||
|
:param string type: The name of the openstack resource type.
|
||||||
|
e.g.: "OS::Nova::Server" etc...
|
||||||
|
|
||||||
|
:param string id: The openstack resource id.
|
||||||
|
|
||||||
|
:param dict properties: The openstack resource properties.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
id = None
|
||||||
|
manager = None
|
||||||
|
parameters = None
|
||||||
|
properties = None
|
||||||
|
type = None
|
||||||
|
|
||||||
|
def __init__(self, manager, name, type=None, id=None, properties=None): # noqa pylint: disable=W0622
|
||||||
|
if not isinstance(manager, ResourceManager):
|
||||||
|
raise TypeError(
|
||||||
|
"manager needs to be a flameclient.resources.ResourceManager "
|
||||||
|
"instance. Received '%s' (%s) instead" % (
|
||||||
|
manager, self.__type(manager)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.manager = manager
|
||||||
|
self.name = name
|
||||||
|
if type:
|
||||||
|
self.type = type
|
||||||
|
self.id = id
|
||||||
|
self.status = 'COMPLETE'
|
||||||
|
self.properties = properties or {}
|
||||||
|
self.parameters = {}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __type(*args, **kwargs):
|
||||||
|
"""Needed to call the builtin type function when overriden"""
|
||||||
|
return type(*args, **kwargs)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def connection(self):
|
||||||
|
return self.manager.connection
|
||||||
|
|
||||||
|
@property
|
||||||
|
def conn(self):
|
||||||
|
return self.connection
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cloud(self):
|
||||||
|
return self.manager.cloud
|
||||||
|
|
||||||
|
@property
|
||||||
|
def generator(self):
|
||||||
|
return self.manager.generator
|
||||||
|
|
||||||
|
@property
|
||||||
|
def managers(self):
|
||||||
|
return self.generator.managers
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api(self):
|
||||||
|
return self.generator.api
|
||||||
|
|
||||||
|
@property
|
||||||
|
def options(self):
|
||||||
|
return self.generator.options
|
||||||
|
|
||||||
|
@property
|
||||||
|
def kwargs(self):
|
||||||
|
return self.manager.kwargs
|
||||||
|
|
||||||
|
def add_parameter(
|
||||||
|
self, name, description, parameter_type='string', constraints=None,
|
||||||
|
default=None
|
||||||
|
):
|
||||||
|
data = {
|
||||||
|
'type': parameter_type,
|
||||||
|
'description': description,
|
||||||
|
}
|
||||||
|
|
||||||
|
if constraints and self.options.include_constraints:
|
||||||
|
data['constraints'] = constraints
|
||||||
|
if default:
|
||||||
|
data['default'] = default
|
||||||
|
|
||||||
|
self.parameters[name] = data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def clean_properties(self):
|
||||||
|
return clean_dict(self.properties)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def template_resource(self):
|
||||||
|
return {
|
||||||
|
self.name: {
|
||||||
|
'type': self.type,
|
||||||
|
'properties': self.clean_properties
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def clean_parameters(self):
|
||||||
|
return clean_dict(self.parameters)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def template_parameter(self):
|
||||||
|
return self.parameters
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stack_resource(self):
|
||||||
|
if self.id is None:
|
||||||
|
return {}
|
||||||
|
return {
|
||||||
|
self.name: {
|
||||||
|
'status': self.status,
|
||||||
|
'name': self.name,
|
||||||
|
'resource_data': {},
|
||||||
|
'resource_id': self.id,
|
||||||
|
'action': 'CREATE',
|
||||||
|
'type': self.type,
|
||||||
|
'metadata': {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def generator_memoize(self, method, *args, **kwargs):
|
||||||
|
return self.manager.generator_memoize(method, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class TypedHotResource(BaseHotResource):
|
||||||
|
"""Describes a heat resource from parameters with predefined type
|
||||||
|
|
||||||
|
:param ResourceManager manager:
|
||||||
|
A ResourceManager instance.
|
||||||
|
This instance is necessary to have access to the manager's
|
||||||
|
openstack.connection.Connection instance
|
||||||
|
|
||||||
|
:param string id: The openstack resource id.
|
||||||
|
|
||||||
|
:param dict properties: The openstack resource properties.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, manager, name, id=None, properties=None): # noqa pylint: disable=W0622
|
||||||
|
super(TypedHotResource, self).__init__(
|
||||||
|
manager, name, type=None, id=id, properties=properties
|
||||||
|
)
|
||||||
|
|
||||||
|
@abc.abstractproperty
|
||||||
|
def type(self): # pylint: disable=E0202
|
||||||
|
"""The resource type
|
||||||
|
|
||||||
|
You need to set this property on subclasses.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class AdvancedHotResource(TypedHotResource, UserDict):
|
||||||
|
"""Describes a heat resource from openstack.resource.Resource instance
|
||||||
|
|
||||||
|
These advanced resources mays also have resources.
|
||||||
|
|
||||||
|
property_keys are properties to automatically extract from the resource.
|
||||||
|
|
||||||
|
:param ResourceManager manager:
|
||||||
|
A ResourceManager instance.
|
||||||
|
This instance is necessary to have access to the manager's
|
||||||
|
openstack.connection.Connection instance
|
||||||
|
|
||||||
|
:param string name: The name of the openstack resource.
|
||||||
|
e.g.: "My_server".
|
||||||
|
|
||||||
|
:param openstack.resource.Resource data:
|
||||||
|
An `openstack.resource.Resource` instance or a munch.Munch instance
|
||||||
|
representing the openstack resource returned by an openstack client or
|
||||||
|
returned by an `openstack.connection.Connection` instance's API call
|
||||||
|
method, or returned by a `shade.openstackcloud.OpenStackCloud`
|
||||||
|
instance's API call method.
|
||||||
|
|
||||||
|
:param dict properties: The openstack resource properties.
|
||||||
|
|
||||||
|
When subclassing this class, the `property_keys` tuple represents
|
||||||
|
property keys which will be automatically extracted from the resource,
|
||||||
|
allowing you to not pass any properties.
|
||||||
|
|
||||||
|
Since we inheritate from UserDict, we have a direct access to `self.data`.
|
||||||
|
More info here:
|
||||||
|
https://docs.python.org/3/library/collections.html#userdict-objects
|
||||||
|
The only difference is that we use a munch instead of dict for `self.data`
|
||||||
|
This means we can access `self.data[key]` with `self[key]` (UserDict) and
|
||||||
|
via `self.data.key` (munch).
|
||||||
|
"""
|
||||||
|
|
||||||
|
property_keys = ()
|
||||||
|
data = None
|
||||||
|
|
||||||
|
def __init__(self, manager, name, data, properties=None):
|
||||||
|
|
||||||
|
data = munchify(data)
|
||||||
|
|
||||||
|
final_properties = {}
|
||||||
|
# Automatically get properties from self.property_keys
|
||||||
|
for key in self.property_keys:
|
||||||
|
final_properties[key] = data[key]
|
||||||
|
# Override properties:
|
||||||
|
if properties:
|
||||||
|
final_properties.update(properties)
|
||||||
|
|
||||||
|
super(AdvancedHotResource, self).__init__(
|
||||||
|
manager, name, id=data.get('id'),
|
||||||
|
properties=final_properties
|
||||||
|
)
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class ResourceManager(object):
|
||||||
|
"""Resource manager to list specific openstack resources
|
||||||
|
|
||||||
|
:param flameclient.flame.TemplateGenerator generator:
|
||||||
|
A `flameclient.flame.TemplateGenerator` instance.
|
||||||
|
|
||||||
|
:param argparse.Namespace options:
|
||||||
|
argparse options.
|
||||||
|
|
||||||
|
args and kwargs are extra parameters which each resource can access in case
|
||||||
|
of developer needs.
|
||||||
|
|
||||||
|
This class needs to be subclassed. Every subclass which is imported will be
|
||||||
|
discovered by `resources.get_manager_classes()`
|
||||||
|
"""
|
||||||
|
|
||||||
|
generator = None
|
||||||
|
args = ()
|
||||||
|
kwargs = None
|
||||||
|
|
||||||
|
def __init__(self, generator, *args, **kwargs):
|
||||||
|
self.generator = generator
|
||||||
|
self.args = args
|
||||||
|
self.kwargs = kwargs or {}
|
||||||
|
|
||||||
|
@ClassProperty
|
||||||
|
def name(cls):
|
||||||
|
"""The resource manager name
|
||||||
|
|
||||||
|
You need to set this property on subclasses if the automatic naming
|
||||||
|
does not work.
|
||||||
|
|
||||||
|
ex.: If this class is calles FooBarsManager, this property will return
|
||||||
|
'foo_bars'
|
||||||
|
"""
|
||||||
|
return camel_to_snake(cls.__name__).rstrip('_manager')
|
||||||
|
|
||||||
|
@ClassProperty
|
||||||
|
def singular_name(cls):
|
||||||
|
"""The resource manager singular name
|
||||||
|
|
||||||
|
You need to set this property on subclasses if the automatic naming
|
||||||
|
does not work.
|
||||||
|
|
||||||
|
Override this if the singular of self.name does not consist in
|
||||||
|
in removing the trailing 's'.
|
||||||
|
"""
|
||||||
|
return cls.name.rstrip('s')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def options(self):
|
||||||
|
return self.generator.options
|
||||||
|
|
||||||
|
@property
|
||||||
|
def connection(self):
|
||||||
|
return self.generator.connection
|
||||||
|
|
||||||
|
@property
|
||||||
|
def conn(self):
|
||||||
|
"""Give a short name access"""
|
||||||
|
return self.connection
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cloud(self):
|
||||||
|
return self.generator.cloud
|
||||||
|
|
||||||
|
@property
|
||||||
|
def managers(self):
|
||||||
|
return self.generator.managers
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_arguments(cls, parser):
|
||||||
|
"""Add parser argparse.ArgumentParser arguments
|
||||||
|
|
||||||
|
Use this method in your subclasses if you want to add any specific
|
||||||
|
argparse arguments. These arguments will then be available on
|
||||||
|
`self.options`.
|
||||||
|
|
||||||
|
:param argparse.ArgumentParser parser: An argparse.ArgumentParser
|
||||||
|
instance
|
||||||
|
|
||||||
|
:returns: An argparse.ArgumentParser parser instance
|
||||||
|
"""
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@abc.abstractproperty
|
||||||
|
def api_resources(self):
|
||||||
|
"""Implement this property to return api resources
|
||||||
|
|
||||||
|
This property will be automatically set as an attribute on
|
||||||
|
`generator.api` and `self.api` with `self.name`.
|
||||||
|
|
||||||
|
e.g.: if this class has `self.name` set to 'routers', the
|
||||||
|
`self.generator.api.routers` attribute and `self.api.routers`
|
||||||
|
attribute will return the results of this property.
|
||||||
|
|
||||||
|
Consider using the `utils.memoized_property` decorator on the
|
||||||
|
property. This is because this property should be computed only once
|
||||||
|
It's the reason why it's a property and not a method.
|
||||||
|
Also consider using self.generator_memoize on API calls.
|
||||||
|
|
||||||
|
This property should return a Munch instance generated by
|
||||||
|
`utils.data_list_to_dict` on a list of `openstack.resource.Resource`
|
||||||
|
instances in order to be consistent with all managers
|
||||||
|
the result has to be in the following form:
|
||||||
|
|
||||||
|
Munch(
|
||||||
|
{
|
||||||
|
'some_id': Munch({}),
|
||||||
|
'other_id': Munch{},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
The `get_resource_name` expects to find a `.enum` attribute on
|
||||||
|
each munch value. You will need to override `get_resource_name` if
|
||||||
|
you have a different data format.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def get_api_resources(self):
|
||||||
|
return self.api_resources
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api(self):
|
||||||
|
"""Direct access to all managers' api resources
|
||||||
|
|
||||||
|
e.g.: if there is a FooManager (with FooManager.name = 'foo'),
|
||||||
|
`self.api.foo` will give access to `FooManager.api_resources`
|
||||||
|
if the current instance and a FooManager instance are in a ManagerList
|
||||||
|
on a TemplateGenerator.
|
||||||
|
|
||||||
|
This allows access to each manager's api resources from any other
|
||||||
|
manager.
|
||||||
|
|
||||||
|
For this to work it implies that TemplateGenerator.api is a
|
||||||
|
DirectManagerApiResourceAccess instance.
|
||||||
|
"""
|
||||||
|
return self.generator.api
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def get_hot_resources(self):
|
||||||
|
"""Implement this method to return resources
|
||||||
|
|
||||||
|
You need to take into account `self.options.no_threads` and not use
|
||||||
|
threads (e.g.: `concurrent.futures`, threading module, etc...) when it
|
||||||
|
is True.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def get_resource_num(self, resource_id):
|
||||||
|
return self.api_resources[resource_id].enum
|
||||||
|
|
||||||
|
def get_resource_name(self, resource_id):
|
||||||
|
return '%s_%d' % (
|
||||||
|
self.singular_name, self.get_resource_num(resource_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
def generator_memoize(self, method, *args, **kwargs):
|
||||||
|
return self.generator.generator_memoize(method, *args, **kwargs)
|
||||||
|
|
||||||
|
@ClassProperty
|
||||||
|
def post_priority(cls):
|
||||||
|
return 100
|
||||||
|
|
||||||
|
def post_process(self):
|
||||||
|
"""This method is called after get_hot_resources of all managers
|
||||||
|
|
||||||
|
Use this method to perform actions after processing.
|
||||||
|
|
||||||
|
This method will be called on all managers sorted by the order of
|
||||||
|
their self.post_priority number.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def post_process_hot_resources(self, resources): # pylint: disable=R0201
|
||||||
|
"""This method is called after get_hot_resources of all managers
|
||||||
|
|
||||||
|
Use this method to perform post processing resources modifications.
|
||||||
|
|
||||||
|
:param list resources: the self.generator.resources attribute after
|
||||||
|
all managers' `get_hot_resources` methods have
|
||||||
|
been called.
|
||||||
|
:returns: A modified resources list (or a new resources list).
|
||||||
|
A resources list is a list containing resources returned by
|
||||||
|
each manager's `get_hot_resources` method.
|
||||||
|
|
||||||
|
This method will be called on all managers sorted by the order of
|
||||||
|
their self.post_priority number.
|
||||||
|
This allows you to modify the list aof resources returned by managers.
|
||||||
|
"""
|
||||||
|
return resources
|
||||||
|
|
||||||
|
def post_process_heat_template(self, template): # pylint: disable=R0201
|
||||||
|
"""This method is called after get_hot_resources of all managers
|
||||||
|
|
||||||
|
Use this method to perform post processing template modifications.
|
||||||
|
|
||||||
|
:param dict template: the self.generator.template attribute after
|
||||||
|
all managers' `get_hot_resources` methods have
|
||||||
|
been called.
|
||||||
|
:returns: The template dictionary which the generator will use to
|
||||||
|
render the flame template. If ou need to create a blank
|
||||||
|
template use `self.generator.get_new_template()` to
|
||||||
|
initialise it.
|
||||||
|
|
||||||
|
|
||||||
|
You need to return a heat template (in python dictionary format)
|
||||||
|
This method will be called on all managers sorted by the order of
|
||||||
|
their self.post_priority number.
|
||||||
|
"""
|
||||||
|
return template
|
||||||
|
|
||||||
|
def post_process_adoption_data(self, adoption_data): # noqa pylint: disable=R0201
|
||||||
|
"""This method is called after get_hot_resources of all managers
|
||||||
|
|
||||||
|
Use this method to perform post processing adoption_data modifications.
|
||||||
|
|
||||||
|
:param dict adoption_data: the self.generator.adoption_data attribute
|
||||||
|
after all managers' `get_hot_resources`
|
||||||
|
methods have been called.
|
||||||
|
:returns: The adoption_data dictionary which the generator will use to
|
||||||
|
render the flame adoption data. If ou need to create a blank
|
||||||
|
template use `self.generator.get_new_adoption_data()` to
|
||||||
|
initialise it.
|
||||||
|
|
||||||
|
This method will be called on all managers sorted by the order of
|
||||||
|
their self.post_priority number.
|
||||||
|
"""
|
||||||
|
return adoption_data
|
||||||
|
|
||||||
|
|
||||||
|
class ManagerList(list):
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
for manager in self:
|
||||||
|
if manager.name == name:
|
||||||
|
return manager
|
||||||
|
raise AttributeError(
|
||||||
|
"'%s' has no '%s' manager" % (
|
||||||
|
self.__name__, name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def __setattr__(self, name, value):
|
||||||
|
if isinstance(value, ResourceManager):
|
||||||
|
if name != value.name:
|
||||||
|
raise ValueError(
|
||||||
|
"'%s'.name != '%s'" % (value, name)
|
||||||
|
)
|
||||||
|
self.append(value)
|
||||||
|
raise TypeError(
|
||||||
|
"'%s' '%s' has to be a ResourceManager instance instead of %s" % (
|
||||||
|
value, name, type(value)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def __delattr__(self, name):
|
||||||
|
for num, manager in enumerate(self):
|
||||||
|
if manager.name == name:
|
||||||
|
self.pop(num)
|
||||||
|
raise AttributeError(
|
||||||
|
"'%s' has no '%s' manager" % (
|
||||||
|
self.__name__, name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DirectManagerApiResourceAccess(object):
|
||||||
|
"""Give direct access to a manager's api_resources attribute
|
||||||
|
|
||||||
|
|
||||||
|
This needs to be set as the 'api' attribute on the TemplateGenerator
|
||||||
|
class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
instance = None
|
||||||
|
owner = None
|
||||||
|
|
||||||
|
def __get__(self, instance, owner):
|
||||||
|
if instance:
|
||||||
|
self.instance = instance
|
||||||
|
self.owner = owner
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
if self.instance:
|
||||||
|
for manager in self.instance.managers:
|
||||||
|
if manager.name == name:
|
||||||
|
return manager.api_resources
|
||||||
|
raise AttributeError(
|
||||||
|
"'%s' has no '%s' manager in self.managers" % (
|
||||||
|
self.owner.__name__, name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_manager_classes():
|
||||||
|
"""List all subclasses of ResourceManager
|
||||||
|
|
||||||
|
if any loaded python module contains a ResourceManager subclass, it will be
|
||||||
|
discovered.
|
||||||
|
Make sure to load any module containing the subclass if you want it to be
|
||||||
|
discoverable.
|
||||||
|
You can use `utils.load_resource_modules(dirname) or
|
||||||
|
`utils.load_resource_entry_points(name='openstack_flame')` to load modules
|
||||||
|
containing ResourceManager subclasses before using this method.
|
||||||
|
"""
|
||||||
|
load_resource_modules(__file__)
|
||||||
|
load_resource_entry_points()
|
||||||
|
return ResourceManager.__subclasses__()
|
54
flameclient/resources/flavors.py
Normal file
54
flameclient/resources/flavors.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class FlavorsManager(base_resources.ResourceManager):
|
||||||
|
"""Used only to provide api resources. Heat does not create flavors."""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_resource_flavor(resource):
|
||||||
|
data = resource.data
|
||||||
|
manager = resource.manager
|
||||||
|
flavor_parameter_name = "%s_flavor" % resource.name
|
||||||
|
description = "Flavor to use for %s %s" % (
|
||||||
|
manager.singular_name, resource.name
|
||||||
|
)
|
||||||
|
default = data.flavor['id']
|
||||||
|
resource.add_parameter(
|
||||||
|
flavor_parameter_name, description, default=default
|
||||||
|
)
|
||||||
|
resource.properties['flavor'] = {'get_param': flavor_parameter_name}
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.compute.flavors)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
return []
|
71
flameclient/resources/floatingips.py
Normal file
71
flameclient/resources/floatingips.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class FloatingIP(base_resources.AdvancedHotResource):
|
||||||
|
type = 'OS::Neutron::FloatingIP'
|
||||||
|
|
||||||
|
def __init__(self, manager, name, floating_ip, properties=None):
|
||||||
|
super(FloatingIP, self).__init__(
|
||||||
|
manager, name, floating_ip, properties
|
||||||
|
)
|
||||||
|
net_param_name = "external_network_for_%s" % self.name
|
||||||
|
self.properties['floating_network_id'] = {'get_param': net_param_name}
|
||||||
|
description = "Network to allocate floating IP from"
|
||||||
|
constraints = [{'custom_constraint': "neutron.network"}]
|
||||||
|
default = self.data['floating_network_id']
|
||||||
|
self.add_parameter(net_param_name, description,
|
||||||
|
constraints=constraints,
|
||||||
|
default=default)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def association(self):
|
||||||
|
return self.managers.ports.get_fip_association(self) \
|
||||||
|
or self.managers.servers.get_fip_association(self)
|
||||||
|
|
||||||
|
|
||||||
|
class FloatingIpsManager(base_resources.ResourceManager):
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.network.ips)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
floating_ips = [
|
||||||
|
FloatingIP(self, self.get_resource_name(fip_id), floating_ip)
|
||||||
|
for fip_id, floating_ip in six.iteritems(self.api.floating_ips)
|
||||||
|
]
|
||||||
|
floating_ip_associations = [
|
||||||
|
fip.association for fip in floating_ips
|
||||||
|
if fip.association
|
||||||
|
]
|
||||||
|
return floating_ips + floating_ip_associations
|
58
flameclient/resources/images.py
Normal file
58
flameclient/resources/images.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class ImagesManager(base_resources.ResourceManager):
|
||||||
|
"""Used only to provide api resources. Heat does not create images."""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_resource_image(resource):
|
||||||
|
data = resource.data
|
||||||
|
manager = resource.manager
|
||||||
|
if data.image:
|
||||||
|
image_parameter_name = "%s_image" % resource.name
|
||||||
|
description = (
|
||||||
|
"Image to use for %s %s" % (
|
||||||
|
manager.singular_name, resource.name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
constraints = [{'custom_constraint': "glance.image"}]
|
||||||
|
resource.add_parameter(image_parameter_name, description,
|
||||||
|
default=data.image['id'],
|
||||||
|
constraints=constraints)
|
||||||
|
resource.properties['image'] = {'get_param': image_parameter_name}
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
# self.conn.compute.images gives detailed images
|
||||||
|
self.generator_memoize(self.conn.image.images)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
return []
|
85
flameclient/resources/key_pairs.py
Normal file
85
flameclient/resources/key_pairs.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class KeyPair(base_resources.AdvancedHotResource):
|
||||||
|
type = 'OS::Nova::KeyPair'
|
||||||
|
property_keys = ('name', 'public_key',)
|
||||||
|
|
||||||
|
|
||||||
|
class KeypairsManager(base_resources.ResourceManager):
|
||||||
|
|
||||||
|
def add_resource_keypair(self, resource):
|
||||||
|
data = resource.data
|
||||||
|
manager = resource.manager
|
||||||
|
|
||||||
|
if data.key_name:
|
||||||
|
if (
|
||||||
|
self.options.exclude_keypairs or
|
||||||
|
data.key_name not in self.api.keypairs
|
||||||
|
):
|
||||||
|
key_parameter_name = "%s_key" % resource.name
|
||||||
|
description = (
|
||||||
|
"Key for %s %s" % (manager.singular_name, resource.name)
|
||||||
|
|
||||||
|
)
|
||||||
|
constraints = [{'custom_constraint': "nova.keypair"}]
|
||||||
|
resource.add_parameter(key_parameter_name, description,
|
||||||
|
default=data.key_name,
|
||||||
|
constraints=constraints)
|
||||||
|
resource.properties['key_name'] = {
|
||||||
|
'get_param': key_parameter_name
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
resource.properties['key_name'] = {
|
||||||
|
'get_resource': self.get_resource_name(data.key_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_arguments(cls, parser):
|
||||||
|
parser.add_argument('--exclude-keypairs', action='store_true',
|
||||||
|
default=False,
|
||||||
|
help="Do not export key pair resources."
|
||||||
|
)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.compute.keypairs)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
if not self.options.exclude_keypairs:
|
||||||
|
return [
|
||||||
|
KeyPair(self, self.get_resource_name(resource.id), resource)
|
||||||
|
for resource in six.itervalues(self.api.keypairs)
|
||||||
|
]
|
||||||
|
return []
|
90
flameclient/resources/networks.py
Normal file
90
flameclient/resources/networks.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
import netaddr
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class Network(base_resources.AdvancedHotResource):
|
||||||
|
type = 'OS::Neutron::Net'
|
||||||
|
property_keys = ('name', 'admin_state_up', 'shared')
|
||||||
|
|
||||||
|
|
||||||
|
class NetworksManager(base_resources.ResourceManager):
|
||||||
|
|
||||||
|
def add_resource_networks(self, resource):
|
||||||
|
addresses = resource.data.addresses
|
||||||
|
networks = []
|
||||||
|
for net_name in addresses:
|
||||||
|
ip = addresses[net_name][0]['addr']
|
||||||
|
for subnet in six.itervalues(self.api.subnets):
|
||||||
|
if netaddr.IPAddress(ip) in netaddr.IPNetwork(subnet['cidr']):
|
||||||
|
for network in six.itervalues(self.api.networks):
|
||||||
|
if (network['name'] == net_name and
|
||||||
|
network['id'] == subnet['network_id']):
|
||||||
|
net = self.get_resource_name(subnet['network_id'])
|
||||||
|
networks.append({'network': {'get_resource': net}})
|
||||||
|
if networks:
|
||||||
|
resource.properties['networks'] = networks
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def all_networks(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.network.networks)
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api_resources(self):
|
||||||
|
return self.all_networks
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def external_networks(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
(
|
||||||
|
network for network in six.itervalues(self.all_networks)
|
||||||
|
if network['router:external']
|
||||||
|
),
|
||||||
|
enum=False # Do not overwrite enumeration done in all_networks
|
||||||
|
)
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def internal_networks(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
(
|
||||||
|
network for network in six.itervalues(self.all_networks)
|
||||||
|
if network.id not in self.external_networks
|
||||||
|
),
|
||||||
|
enum=False # Do not overwrite enumeration done in all_networks
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
return [
|
||||||
|
Network(self, self.get_resource_name(network.id), network)
|
||||||
|
for network in six.itervalues(self.internal_networks)
|
||||||
|
]
|
137
flameclient/resources/ports.py
Normal file
137
flameclient/resources/ports.py
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class Port(base_resources.AdvancedHotResource):
|
||||||
|
type = 'OS::Neutron::Port'
|
||||||
|
property_keys = ('admin_state_up', 'mac_address', 'device_owner')
|
||||||
|
|
||||||
|
def __init__(self, manager, name, port, properties=None):
|
||||||
|
super(Port, self).__init__(manager, name, port, properties)
|
||||||
|
|
||||||
|
fixed_ips = []
|
||||||
|
|
||||||
|
for fixed_ip_dict in port['fixed_ips']:
|
||||||
|
subnet_id = fixed_ip_dict['subnet_id']
|
||||||
|
subnet_resource_name = self.managers.subnets.get_resource_name(
|
||||||
|
subnet_id
|
||||||
|
)
|
||||||
|
fixed_ip_resource = {
|
||||||
|
u'subnet_id': {'get_resource': subnet_resource_name},
|
||||||
|
u'ip_address': fixed_ip_dict['ip_address']
|
||||||
|
}
|
||||||
|
fixed_ips.append(fixed_ip_resource)
|
||||||
|
|
||||||
|
net_resource_name = self.managers.networks.get_resource_name(
|
||||||
|
port['network_id']
|
||||||
|
)
|
||||||
|
self.properties.update(
|
||||||
|
{'network_id': {'get_resource': net_resource_name},
|
||||||
|
'fixed_ips': fixed_ips}
|
||||||
|
)
|
||||||
|
if port['name'] != '':
|
||||||
|
# This port has a name
|
||||||
|
self.properties['name'] = port['name']
|
||||||
|
|
||||||
|
self.managers.security_groups.add_resource_secgrp_props_and_params(
|
||||||
|
self
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class NeutronFloatingIpAssociation(base_resources.TypedHotResource):
|
||||||
|
type = 'OS::Neutron::FloatingIPAssociation'
|
||||||
|
|
||||||
|
|
||||||
|
class PortsManager(base_resources.ResourceManager):
|
||||||
|
|
||||||
|
def get_fip_association(self, resource):
|
||||||
|
ip = resource.data
|
||||||
|
manager = resource.manager
|
||||||
|
if ip['port_id'] and self.options.extract_ports:
|
||||||
|
port_resource_name = self.get_resource_name(ip['port_id'])
|
||||||
|
properties = {
|
||||||
|
'floatingip_id': {'get_resource': resource.name},
|
||||||
|
'port_id': {'get_resource': port_resource_name}
|
||||||
|
}
|
||||||
|
resource_num = manager.get_resource_num(resource.id)
|
||||||
|
fip_assoc_id = ("%s:%s" % (ip['id'], ip['port_id']))
|
||||||
|
return NeutronFloatingIpAssociation(
|
||||||
|
manager,
|
||||||
|
"floatingip_association_%d" % resource_num,
|
||||||
|
fip_assoc_id,
|
||||||
|
properties
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_ports_for_resource(self, resource):
|
||||||
|
ports = []
|
||||||
|
for port in six.itervalues(self.api.ports):
|
||||||
|
if port['device_id'] == resource.data.id:
|
||||||
|
ports.append(self.get_resource_name(port.id))
|
||||||
|
return ports
|
||||||
|
|
||||||
|
def add_resource_ports_or_secgroups_and_networks(self, resource):
|
||||||
|
if self.options.extract_ports:
|
||||||
|
ports = [{"port": {"get_resource": port}}
|
||||||
|
for port in self.get_ports_for_resource(resource)]
|
||||||
|
if ports:
|
||||||
|
resource.properties['networks'] = ports
|
||||||
|
else:
|
||||||
|
self.managers.security_groups \
|
||||||
|
.add_resource_secgrp_props_and_params(resource)
|
||||||
|
|
||||||
|
self.managers.networks.add_resource_networks(resource)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_arguments(cls, parser):
|
||||||
|
parser.add_argument('--extract-ports', action='store_true',
|
||||||
|
default=False,
|
||||||
|
help="Export the tenant network ports.")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.network.ports)
|
||||||
|
)
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def port_resources(self):
|
||||||
|
return [
|
||||||
|
Port(self, self.get_resource_name(port.id), port)
|
||||||
|
for port in six.itervalues(self.api.ports)
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
if self.options.extract_ports:
|
||||||
|
return [
|
||||||
|
port for port in self.port_resources
|
||||||
|
if port['device_owner'].startswith('compute:')
|
||||||
|
]
|
||||||
|
return []
|
112
flameclient/resources/routers.py
Normal file
112
flameclient/resources/routers.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
from flameclient.utils import munchify
|
||||||
|
|
||||||
|
|
||||||
|
class RouterInterface(base_resources.TypedHotResource):
|
||||||
|
type = 'OS::Neutron::RouterInterface'
|
||||||
|
|
||||||
|
|
||||||
|
class RouterGateway(base_resources.TypedHotResource):
|
||||||
|
type = 'OS::Neutron::RouterGateway'
|
||||||
|
|
||||||
|
|
||||||
|
class Router(base_resources.AdvancedHotResource):
|
||||||
|
type = 'OS::Neutron::Router'
|
||||||
|
property_keys = ('name', 'admin_state_up')
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def os_ports(self):
|
||||||
|
return munchify(self.generator_memoize(
|
||||||
|
self.conn.network.ports, device_id=self['id']
|
||||||
|
))
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def router_interfaces(self):
|
||||||
|
router_interfaces = []
|
||||||
|
for n, port in enumerate(self.os_ports):
|
||||||
|
if port['device_owner'] != "network:router_interface":
|
||||||
|
continue
|
||||||
|
resource_name = "%s_interface_%d" % (self.name, n)
|
||||||
|
subnet_resource_name = self.managers.subnets.get_resource_name(
|
||||||
|
port['fixed_ips'][0]['subnet_id']
|
||||||
|
)
|
||||||
|
resource_id = ("%s:subnet_id=%s" %
|
||||||
|
(port['device_id'],
|
||||||
|
port['fixed_ips'][0]['subnet_id']))
|
||||||
|
properties = {
|
||||||
|
'subnet_id': {'get_resource': subnet_resource_name},
|
||||||
|
'router_id': {'get_resource': self.name}
|
||||||
|
}
|
||||||
|
router_interfaces.append(
|
||||||
|
RouterInterface(
|
||||||
|
self.manager, resource_name, resource_id, properties)
|
||||||
|
)
|
||||||
|
return router_interfaces
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def router_gateway(self):
|
||||||
|
if self['external_gateway_info']:
|
||||||
|
router_external_network_name = ("%s_external_network" % self.name)
|
||||||
|
external_network = self['external_gateway_info']['network_id']
|
||||||
|
properties = {
|
||||||
|
'router_id': {'get_resource': self.name},
|
||||||
|
'network_id': {'get_param': router_external_network_name}
|
||||||
|
}
|
||||||
|
gateway = RouterGateway(self.manager, "%s_gateway" % self.name,
|
||||||
|
"%s:%s" % (self['id'], external_network),
|
||||||
|
properties)
|
||||||
|
description = "Router external network"
|
||||||
|
constraints = [{'custom_constraint': "neutron.network"}]
|
||||||
|
gateway.add_parameter(router_external_network_name, description,
|
||||||
|
constraints=constraints,
|
||||||
|
default=external_network)
|
||||||
|
return gateway
|
||||||
|
|
||||||
|
|
||||||
|
class RoutersManager(base_resources.ResourceManager):
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.network.routers)
|
||||||
|
)
|
||||||
|
|
||||||
|
routers = api_resources
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
resources = []
|
||||||
|
for rid, router in six.iteritems(self.api.routers):
|
||||||
|
resource = Router(self, self.get_resource_name(rid), router)
|
||||||
|
resources.append(resource)
|
||||||
|
resources.extend(resource.router_interfaces)
|
||||||
|
if resource.router_gateway:
|
||||||
|
resources.append(resource.router_gateway)
|
||||||
|
return resources
|
175
flameclient/resources/security_groups.py
Normal file
175
flameclient/resources/security_groups.py
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
from copy import deepcopy
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient import collections_abc
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import clean_dict
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class SecurityGroup(base_resources.AdvancedHotResource):
|
||||||
|
type = 'OS::Neutron::SecurityGroup'
|
||||||
|
property_keys = ('description',)
|
||||||
|
|
||||||
|
def __init__(self, manager, name, data, properties=None):
|
||||||
|
super(SecurityGroup, self).__init__(
|
||||||
|
manager, name, data, properties
|
||||||
|
)
|
||||||
|
if data['name'] == 'default':
|
||||||
|
self.properties['name'] = '_default'
|
||||||
|
else:
|
||||||
|
self.properties['name'] = data['name']
|
||||||
|
|
||||||
|
self.properties['rules'] = self._build_rules(
|
||||||
|
data['security_group_rules']
|
||||||
|
)
|
||||||
|
|
||||||
|
def _build_rules(self, original_rules):
|
||||||
|
final_rules = []
|
||||||
|
for rule in original_rules:
|
||||||
|
new_rule = deepcopy(rule)
|
||||||
|
if new_rule['protocol'] == 'any':
|
||||||
|
del new_rule['protocol']
|
||||||
|
del new_rule['port_range_min']
|
||||||
|
del new_rule['port_range_max']
|
||||||
|
rg_id = new_rule['remote_group_id']
|
||||||
|
if rg_id is not None:
|
||||||
|
new_rule['remote_mode'] = "remote_group_id"
|
||||||
|
resource_name = self.manager.get_resource_name(rg_id)
|
||||||
|
if rg_id == new_rule['security_group_id']:
|
||||||
|
del new_rule['remote_group_id']
|
||||||
|
else:
|
||||||
|
new_rule['remote_group_id'] = {
|
||||||
|
'get_resource': resource_name
|
||||||
|
}
|
||||||
|
del new_rule['tenant_id']
|
||||||
|
del new_rule['id']
|
||||||
|
del new_rule['security_group_id']
|
||||||
|
final_rule = clean_dict(new_rule, clean_list=False)
|
||||||
|
final_rules.append(final_rule)
|
||||||
|
return final_rules
|
||||||
|
|
||||||
|
|
||||||
|
class SecurityGroupsManager(base_resources.ResourceManager):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_arguments(cls, parser):
|
||||||
|
parser.add_argument('--exclude-secgroups', action='store_true',
|
||||||
|
default=False,
|
||||||
|
help="Do not export the security group resources.")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.network.security_groups)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_security_group(self, name_or_id):
|
||||||
|
if isinstance(name_or_id, six.string_types):
|
||||||
|
try:
|
||||||
|
return self.api_resources[name_or_id]
|
||||||
|
except KeyError:
|
||||||
|
for sg in six.itervalues(self.api_resources):
|
||||||
|
if name_or_id == sg.name:
|
||||||
|
return sg
|
||||||
|
raise ValueError(
|
||||||
|
"No security group with '%s' id or name found"
|
||||||
|
)
|
||||||
|
elif isinstance(name_or_id, collections_abc.Mapping):
|
||||||
|
if 'id' in name_or_id:
|
||||||
|
return self.get_security_group(name_or_id['id'])
|
||||||
|
elif 'name' in name_or_id:
|
||||||
|
return self.get_security_group(name_or_id['name'])
|
||||||
|
else:
|
||||||
|
raise KeyError(
|
||||||
|
"%s has no 'id' or 'name' key" % name_or_id
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
"%s has to be a string or dict with 'id' or 'name' key."
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_resource_secgroups(self, resource):
|
||||||
|
return [
|
||||||
|
self.get_security_group(sg)
|
||||||
|
for sg in resource.data.security_groups
|
||||||
|
]
|
||||||
|
|
||||||
|
def add_resource_secgrp_props_and_params(self, resource):
|
||||||
|
"""Add security group properties and parameters to a resource
|
||||||
|
|
||||||
|
:param BaseHotResource resource: a BaseHotResource (or subclass)
|
||||||
|
instance
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not self.options.exclude_secgroups:
|
||||||
|
|
||||||
|
manager = resource.manager
|
||||||
|
|
||||||
|
data = resource.data
|
||||||
|
security_groups = []
|
||||||
|
|
||||||
|
secgroup_default_parameter = None
|
||||||
|
for secgr in self.get_resource_secgroups(resource):
|
||||||
|
if secgr['name'] == 'default' and \
|
||||||
|
self.options.generate_adoption_data:
|
||||||
|
if not secgroup_default_parameter:
|
||||||
|
res_name = manager.get_resource_name(data['id'])
|
||||||
|
param_name = "%s_default_security_group" % res_name
|
||||||
|
description = (
|
||||||
|
"Default security group for %s %s" % (
|
||||||
|
manager.singular_name, resource['name']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
default = secgr['id']
|
||||||
|
resource.add_parameter(
|
||||||
|
param_name, description, default=default
|
||||||
|
)
|
||||||
|
secgroup_default_parameter = {'get_param': param_name}
|
||||||
|
security_groups.append(secgroup_default_parameter)
|
||||||
|
else:
|
||||||
|
resource_name = self.get_resource_name(secgr['id'])
|
||||||
|
security_groups.append({'get_resource': resource_name})
|
||||||
|
|
||||||
|
if security_groups:
|
||||||
|
resource.properties['security_groups'] = security_groups
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
resources = []
|
||||||
|
if not self.options.exclude_secgroups:
|
||||||
|
for secgroup in six.itervalues(self.api.security_groups):
|
||||||
|
if secgroup['name'] == 'default' \
|
||||||
|
and self.options.generate_adoption_data:
|
||||||
|
continue
|
||||||
|
resources.append(
|
||||||
|
SecurityGroup(
|
||||||
|
self, self.get_resource_name(secgroup.id), secgroup
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return resources
|
61
flameclient/resources/server_groups.py
Normal file
61
flameclient/resources/server_groups.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class ServerGroup(base_resources.AdvancedHotResource):
|
||||||
|
type = 'OS::Nova::ServerGroup'
|
||||||
|
property_keys = ('name', 'policies')
|
||||||
|
|
||||||
|
|
||||||
|
class ServerGroupsManager(base_resources.ResourceManager):
|
||||||
|
|
||||||
|
def add_resource_server_groups(self, resource):
|
||||||
|
server = resource.data
|
||||||
|
for servergroup in self.api_resources.values():
|
||||||
|
if server.id in servergroup.members:
|
||||||
|
hint = {
|
||||||
|
'group': {
|
||||||
|
'get_resource':
|
||||||
|
self.get_resource_name(servergroup.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resource.properties['scheduler_hints'] = hint
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.compute.server_groups)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
return [
|
||||||
|
ServerGroup(self, self.get_resource_name(sg.id), sg)
|
||||||
|
for sg in six.itervalues(self.api_resources)
|
||||||
|
]
|
93
flameclient/resources/servers.py
Normal file
93
flameclient/resources/servers.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class Server(base_resources.AdvancedHotResource):
|
||||||
|
type = 'OS::Nova::Server'
|
||||||
|
property_keys = ('name',)
|
||||||
|
|
||||||
|
def __init__(self, manager, name, server, properties=None):
|
||||||
|
super(Server, self).__init__(manager, name, server, properties)
|
||||||
|
for property_name in ('config_drive', 'metadata'):
|
||||||
|
if server[property_name]:
|
||||||
|
self.properties[property_name] = server[property_name]
|
||||||
|
self.managers.flavors.add_resource_flavor(self)
|
||||||
|
self.managers.images.add_resource_image(self)
|
||||||
|
self.managers.keypairs.add_resource_keypair(self)
|
||||||
|
self.managers.ports.add_resource_ports_or_secgroups_and_networks(self)
|
||||||
|
self.managers.volumes.add_resource_attached_volumes(self)
|
||||||
|
self.managers.server_groups.add_resource_server_groups(self)
|
||||||
|
|
||||||
|
|
||||||
|
class NovaFloatingIpAssociation(base_resources.TypedHotResource):
|
||||||
|
type = 'OS::Nova::FloatingIPAssociation'
|
||||||
|
|
||||||
|
|
||||||
|
class ServersManager(base_resources.ResourceManager):
|
||||||
|
|
||||||
|
def get_fip_association(self, resource):
|
||||||
|
ip = resource.data
|
||||||
|
manager = resource.manager
|
||||||
|
if not self.options.exclude_servers and ip['port_id']:
|
||||||
|
server_id = self.api.ports[ip['port_id']]['device_id']
|
||||||
|
if server_id and server_id in self.api.servers:
|
||||||
|
server_resource_name = self.get_resource_name(server_id)
|
||||||
|
resource_num = manager.get_resource_num(resource.id)
|
||||||
|
properties = {
|
||||||
|
'floating_ip': {'get_resource': resource.name},
|
||||||
|
'server_id': {'get_resource': server_resource_name}
|
||||||
|
}
|
||||||
|
return NovaFloatingIpAssociation(
|
||||||
|
manager,
|
||||||
|
"floatingip_association_%d" % resource_num,
|
||||||
|
None,
|
||||||
|
properties
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_arguments(cls, parser):
|
||||||
|
parser.add_argument('--exclude-servers', action='store_true',
|
||||||
|
default=False,
|
||||||
|
help="Do not export in template server resources.")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.compute.servers)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
if not self.options.exclude_servers:
|
||||||
|
return [
|
||||||
|
Server(self, self.get_resource_name(server.id), server)
|
||||||
|
for server in six.itervalues(self.api.servers)
|
||||||
|
]
|
||||||
|
return []
|
63
flameclient/resources/subnets.py
Normal file
63
flameclient/resources/subnets.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class Subnet(base_resources.AdvancedHotResource):
|
||||||
|
type = 'OS::Neutron::Subnet'
|
||||||
|
property_keys = (
|
||||||
|
'name',
|
||||||
|
'allocation_pools',
|
||||||
|
'cidr',
|
||||||
|
'dns_nameservers',
|
||||||
|
'enable_dhcp',
|
||||||
|
'host_routes',
|
||||||
|
'ip_version',
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, manager, name, data, properties=None):
|
||||||
|
super(Subnet, self).__init__(manager, name, data, properties)
|
||||||
|
net_name = self.managers.networks.get_resource_name(self['network_id'])
|
||||||
|
self.properties['network_id'] = {'get_resource': net_name}
|
||||||
|
|
||||||
|
|
||||||
|
class SubnetsManager(base_resources.ResourceManager):
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.network.subnets)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
return [
|
||||||
|
Subnet(self, self.get_resource_name(subnet.id), subnet)
|
||||||
|
for subnet in six.itervalues(self.api.subnets)
|
||||||
|
if subnet['network_id'] in self.managers.networks.internal_networks
|
||||||
|
]
|
158
flameclient/resources/volumes.py
Normal file
158
flameclient/resources/volumes.py
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient import resources as base_resources
|
||||||
|
from flameclient.utils import data_list_to_dict
|
||||||
|
from flameclient.utils import memoized_property
|
||||||
|
|
||||||
|
|
||||||
|
class Volume(base_resources.AdvancedHotResource):
|
||||||
|
type = 'OS::Cinder::Volume'
|
||||||
|
property_keys = ('size', 'name')
|
||||||
|
|
||||||
|
def _add_source_volume(self):
|
||||||
|
volume = self.data
|
||||||
|
if volume.source_volid:
|
||||||
|
if volume.source_volid in self.api.volumes:
|
||||||
|
key = self.manager.get_resource_name(volume.source_volid)
|
||||||
|
self.properties['source_volid'] = {'get_resource': key}
|
||||||
|
else:
|
||||||
|
key = "%s_source_volid" % self.name
|
||||||
|
description = (
|
||||||
|
"Volume to create volume %s from" % self.name)
|
||||||
|
self.add_parameter(key, description)
|
||||||
|
self.properties['source_volid'] = {'get_param': key}
|
||||||
|
|
||||||
|
def _add_image(self):
|
||||||
|
volume = self.data
|
||||||
|
if volume.bootable and not volume.snapshot_id:
|
||||||
|
key = "%s_image" % self.name
|
||||||
|
description = "Image to create volume %s from" % self.name
|
||||||
|
constraints = [{'custom_constraint': "glance.image"}]
|
||||||
|
default = volume.volume_image_metadata['image_id']
|
||||||
|
self.add_parameter(key, description,
|
||||||
|
constraints=constraints,
|
||||||
|
default=default)
|
||||||
|
self.properties['image'] = {'get_param': key}
|
||||||
|
|
||||||
|
def _add_snapshot(self):
|
||||||
|
volume = self.data
|
||||||
|
if volume.snapshot_id:
|
||||||
|
key = "%s_snapshot_id" % self.name
|
||||||
|
self.properties['snapshot_id'] = {'get_param': key}
|
||||||
|
description = (
|
||||||
|
"Snapshot to create volume %s from" % self.name)
|
||||||
|
self.add_parameter(key, description,
|
||||||
|
default=volume.snapshot_id)
|
||||||
|
|
||||||
|
def _add_display_name(self):
|
||||||
|
volume = self.data
|
||||||
|
if hasattr(volume, 'display_name') and volume.display_name:
|
||||||
|
self.properties['name'] = volume.display_name
|
||||||
|
|
||||||
|
def _add_display_description(self):
|
||||||
|
volume = self.data
|
||||||
|
if (
|
||||||
|
hasattr(volume, 'display_description') and
|
||||||
|
volume.display_description
|
||||||
|
):
|
||||||
|
self.properties['description'] = volume.display_description
|
||||||
|
|
||||||
|
def _add_volume_type(self):
|
||||||
|
volume = self.data
|
||||||
|
if volume.volume_type and volume.volume_type != 'None':
|
||||||
|
key = "%s_volume_type" % self.name
|
||||||
|
description = (
|
||||||
|
"Volume type for volume %s" % self.name)
|
||||||
|
default = volume.volume_type
|
||||||
|
self.add_parameter(key, description, default=default)
|
||||||
|
self.properties['volume_type'] = {'get_param': key}
|
||||||
|
|
||||||
|
def _add_metadata(self):
|
||||||
|
volume = self.data
|
||||||
|
if volume.metadata:
|
||||||
|
self.properties['metadata'] = volume.metadata
|
||||||
|
|
||||||
|
def __init__(self, manager, name, volume, properties=None):
|
||||||
|
super(Volume, self).__init__(manager, name, volume, properties)
|
||||||
|
self._add_source_volume()
|
||||||
|
self._add_image()
|
||||||
|
self._add_display_name()
|
||||||
|
self._add_display_description()
|
||||||
|
self._add_volume_type()
|
||||||
|
self._add_metadata()
|
||||||
|
|
||||||
|
|
||||||
|
class VolumesManager(base_resources.ResourceManager):
|
||||||
|
|
||||||
|
def add_resource_attached_volumes(self, resource):
|
||||||
|
server = resource.data
|
||||||
|
manager = resource.manager
|
||||||
|
server_volumes = []
|
||||||
|
att_key = 'os-extended-volumes:volumes_attached'
|
||||||
|
for server_volume in server[att_key]:
|
||||||
|
volume = self.api.volumes[server_volume['id']]
|
||||||
|
volume_resource_name = self.get_resource_name(server_volume['id'])
|
||||||
|
device = volume.attachments[0]['device']
|
||||||
|
if not self.options.exclude_volumes:
|
||||||
|
server_volumes.append(
|
||||||
|
{'volume_id': {'get_resource': volume_resource_name},
|
||||||
|
'device_name': device})
|
||||||
|
else:
|
||||||
|
volume_parameter_name = ("volume_%s_%d" %
|
||||||
|
(server.name, volume.enum))
|
||||||
|
description = ("Volume for %s %s, device %s" %
|
||||||
|
(manager.singular_name, server.name, device))
|
||||||
|
server_volumes.append(
|
||||||
|
{'volume_id': {'get_param': volume_parameter_name},
|
||||||
|
'device_name': device})
|
||||||
|
resource.add_parameter(volume_parameter_name, description,
|
||||||
|
default=server_volume['id'])
|
||||||
|
if server_volumes:
|
||||||
|
# block_device_mapping_v2 is the new way of associating
|
||||||
|
# block devices to an instance
|
||||||
|
resource.properties['block_device_mapping_v2'] = server_volumes
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_arguments(cls, parser):
|
||||||
|
parser.add_argument('--exclude-volumes', action='store_true',
|
||||||
|
default=False,
|
||||||
|
help="Do not export volume resources.")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@memoized_property
|
||||||
|
def api_resources(self):
|
||||||
|
return data_list_to_dict(
|
||||||
|
self.generator_memoize(self.conn.volume.volumes)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_hot_resources(self):
|
||||||
|
if not self.options.exclude_volumes:
|
||||||
|
return [
|
||||||
|
Volume(self, self.get_resource_name(volume.id), volume)
|
||||||
|
for volume in six.itervalues(self.api.volumes)
|
||||||
|
]
|
||||||
|
return []
|
278
flameclient/session.py
Normal file
278
flameclient/session.py
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from keystoneauth1 import loading
|
||||||
|
from keystoneauth1 import session as keystone_session
|
||||||
|
from openstack import connection as os_connection
|
||||||
|
# We get a subclass of openstack.config.loader.OpenStackConfig which is more
|
||||||
|
# complete:
|
||||||
|
from os_client_config.config import OpenStackConfig # noqa
|
||||||
|
from shade.openstackcloud import OpenStackCloud # noqa
|
||||||
|
|
||||||
|
from flameclient import utils
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def list_auth_types():
|
||||||
|
return [loader for loader in loading.get_available_plugin_loaders()]
|
||||||
|
|
||||||
|
|
||||||
|
def get_loader(auth_type):
|
||||||
|
if auth_type not in list_auth_types():
|
||||||
|
raise ValueError(
|
||||||
|
"'auth_type' has to be one of %s (received %s)" % (
|
||||||
|
list_auth_types(), auth_type
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return loading.get_plugin_loader(auth_type)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_loader_kwargs(loader, **kwargs):
|
||||||
|
"""Get keystoneauth1.loading.get_plugin_loader's auth kwargs
|
||||||
|
|
||||||
|
Return the specific auth kwargs and remaining kwargs
|
||||||
|
"""
|
||||||
|
loader_keys = [option.dest for option in loader.get_options()]
|
||||||
|
loader_kwargs = {
|
||||||
|
key: kwargs[key] for key in loader_keys if key in kwargs
|
||||||
|
}
|
||||||
|
remaining_kwargs = {
|
||||||
|
key: kwargs[key] for key in kwargs if key not in loader_keys
|
||||||
|
}
|
||||||
|
return loader_kwargs, remaining_kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def get_openstack_config_with_envvars(
|
||||||
|
parser, config=None, load_envvars=False, load_yaml_config=False
|
||||||
|
):
|
||||||
|
"""Add openstack_options to argparse.ArgumentParser
|
||||||
|
|
||||||
|
:param argparse.ArgumentParser parser: argparse.ArgumentParser instance
|
||||||
|
or None.
|
||||||
|
|
||||||
|
:param bool load_envvars:
|
||||||
|
Whether or not to load config settings from environment variables.
|
||||||
|
Defaults to True.
|
||||||
|
|
||||||
|
:returns: OpenStackConfig instance
|
||||||
|
"""
|
||||||
|
|
||||||
|
if config is None:
|
||||||
|
# If we use `openstack.config.loader.OpenStackConfig` instead of
|
||||||
|
# `os_client_config.config.OpenStackConfig` and then instantiate a
|
||||||
|
# `shade.openstackcloud.OpenStackCloud` instance as `cloud`, when
|
||||||
|
# trying to access the `cloud.keystone_client` attribute (or any other
|
||||||
|
# `*_client attribute`), we get a
|
||||||
|
# "TypeError: 'NoneType' object is not callable" exception
|
||||||
|
# This is why we use `os_client_config.config.OpenStackConfig`: it's to
|
||||||
|
# have all `shade.openstackcloud.OpenStackCloud` attributes working
|
||||||
|
# properly. Whether we use them or not, whether these attributes are
|
||||||
|
# deprecated or not, we do not want a 'broken' shade instance in case
|
||||||
|
# third party managers would use them.
|
||||||
|
config = OpenStackConfig(
|
||||||
|
load_envvars=load_envvars, load_yaml_config=load_yaml_config
|
||||||
|
)
|
||||||
|
if parser:
|
||||||
|
if load_envvars or load_yaml_config:
|
||||||
|
config.register_argparse_arguments(parser, sys.argv)
|
||||||
|
else:
|
||||||
|
config.register_argparse_arguments(parser, [])
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def get_openstack_cli_arguments(
|
||||||
|
parser=None, load_envvars=True, load_yaml_config=True,
|
||||||
|
renamed_args=False
|
||||||
|
):
|
||||||
|
if parser is None:
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
get_openstack_config_with_envvars(
|
||||||
|
parser, load_envvars=load_envvars, load_yaml_config=load_yaml_config
|
||||||
|
)
|
||||||
|
known_args, unknown_args = parser.parse_known_args()
|
||||||
|
if renamed_args:
|
||||||
|
known_args = utils.rename_os_options(known_args, clean=False)
|
||||||
|
return known_args, unknown_args
|
||||||
|
|
||||||
|
|
||||||
|
def get_openstack_envvars_as_kwargs(
|
||||||
|
with_args=False, parser=None, load_envvars=True, load_yaml_config=True
|
||||||
|
):
|
||||||
|
"""Get openstack environment variables"""
|
||||||
|
known_args, unknown_args = get_openstack_cli_arguments(
|
||||||
|
parser=parser, load_envvars=load_envvars,
|
||||||
|
load_yaml_config=load_yaml_config
|
||||||
|
)
|
||||||
|
kwargs = utils.rename_os_kwargs(vars(known_args), clean=True)
|
||||||
|
if with_args:
|
||||||
|
return known_args, unknown_args, kwargs
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def get_keystoneauth1_session(
|
||||||
|
load_envvars=False, load_yaml_config=False, **kwargs
|
||||||
|
):
|
||||||
|
if load_envvars:
|
||||||
|
kwargs.update(
|
||||||
|
get_openstack_envvars_as_kwargs(
|
||||||
|
load_envvars=load_envvars, load_yaml_config=load_yaml_config
|
||||||
|
)
|
||||||
|
)
|
||||||
|
auth_type = kwargs.get('auth_type', 'password')
|
||||||
|
loader = get_loader(auth_type)
|
||||||
|
loader_kwargs, _ = extract_loader_kwargs(loader, **kwargs)
|
||||||
|
auth = loader.load_from_options(**loader_kwargs)
|
||||||
|
return keystone_session.Session(auth=auth)
|
||||||
|
|
||||||
|
|
||||||
|
get_keystone_session = get_keystoneauth1_session
|
||||||
|
|
||||||
|
|
||||||
|
def get_openstack_config(
|
||||||
|
parser_or_options=None, load_envvars=False, load_yaml_config=False,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
"""Same as os_client_config.get_config with less errors.
|
||||||
|
|
||||||
|
Indeed, if we source OS_* variable environments, and one calls:
|
||||||
|
|
||||||
|
os_client_config.get_config(
|
||||||
|
load_envvars=False, load_yaml_config=False, **kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
we get this kind of error:
|
||||||
|
|
||||||
|
ConfigException: Region fr1 is not a valid region name for cloud
|
||||||
|
envvars. Valid choices are fr0. Please note that region names are case
|
||||||
|
sensitive.
|
||||||
|
|
||||||
|
It seems like os_client_config.get_config fails to NOT handle envvars.
|
||||||
|
|
||||||
|
Also, os_client_config.get_config saves the config in a global variable...
|
||||||
|
This is absolutely not thread safe...
|
||||||
|
|
||||||
|
"""
|
||||||
|
parsed_options = None
|
||||||
|
parser = None
|
||||||
|
if isinstance(parser_or_options, argparse.ArgumentParser):
|
||||||
|
parser = parser_or_options
|
||||||
|
config = get_openstack_config_with_envvars(
|
||||||
|
parser=parser, load_envvars=load_envvars,
|
||||||
|
load_yaml_config=load_yaml_config
|
||||||
|
)
|
||||||
|
if parser_or_options is not None:
|
||||||
|
if isinstance(parser_or_options, argparse.Namespace):
|
||||||
|
parsed_options = parser_or_options
|
||||||
|
elif isinstance(parser_or_options, dict):
|
||||||
|
parsed_options = utils.dict_to_options(parser_or_options)
|
||||||
|
elif isinstance(parser_or_options, argparse.ArgumentParser):
|
||||||
|
if load_envvars or load_yaml_config:
|
||||||
|
parsed_options, _ = parser_or_options.parse_known_args(
|
||||||
|
sys.argv)
|
||||||
|
else:
|
||||||
|
parsed_options, _ = parser_or_options.parse_known_args([])
|
||||||
|
else:
|
||||||
|
raise AttributeError(
|
||||||
|
"'parser_options' has to be an 'argparse.ArgumentParser' or "
|
||||||
|
"'argparse.Namespace' instance or dict or None. "
|
||||||
|
"Received '%s'" % type(parser_or_options)
|
||||||
|
)
|
||||||
|
return config.get_one(
|
||||||
|
options=parsed_options,
|
||||||
|
load_yaml_config=load_yaml_config,
|
||||||
|
load_envvars=load_envvars,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_openstack_sdk_connection(
|
||||||
|
parser_or_options=None, load_envvars=False, load_yaml_config=False,
|
||||||
|
cloud_config=None, session=None,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
if session is not None:
|
||||||
|
return os_connection.Connection(session=session, **kwargs)
|
||||||
|
|
||||||
|
if cloud_config is None:
|
||||||
|
# we could return
|
||||||
|
# `openstack.connect(load_envvars=load_envvars, load_yaml_config=load_yaml_config, **kwargs)` # noqa
|
||||||
|
# but by doing so magic things are lacking in the config and we have
|
||||||
|
# random failing methods on the instance. See comments in
|
||||||
|
# get_openstack_config_with_envvars for more information.
|
||||||
|
cloud_config = get_openstack_config(
|
||||||
|
parser_or_options=parser_or_options, load_envvars=load_envvars,
|
||||||
|
load_yaml_config=load_yaml_config,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
if isinstance(parser_or_options, dict):
|
||||||
|
parser_or_options = utils.dict_to_options(parser_or_options)
|
||||||
|
return os_connection.from_config(
|
||||||
|
cloud_config=cloud_config, options=parser_or_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_shade(
|
||||||
|
parser_or_options=None, cloud_config=None, connection=None,
|
||||||
|
load_envvars=False, load_yaml_config=False,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
"""Get shade instance
|
||||||
|
|
||||||
|
You can use an `argparse.ArgumentParser` or `argparse.Namespace` instance
|
||||||
|
with `load_envvars` and/or `load_yaml_config` set to True,
|
||||||
|
Or you kan use kwargs to authenticate with `load_envvars` AND
|
||||||
|
`load_yaml_config` set to False:
|
||||||
|
|
||||||
|
cloud = get_shade(
|
||||||
|
auth_type='password',
|
||||||
|
auth_url='https://identity.fr1.cloudwatt.com/v2.0',
|
||||||
|
interface='public',
|
||||||
|
password='YourPassword',
|
||||||
|
project_id='Your ProjectID,
|
||||||
|
project_name='YourProjectName,
|
||||||
|
region_name='YourRegionName',
|
||||||
|
username='YourUserName'
|
||||||
|
)
|
||||||
|
|
||||||
|
You can also use a token instead of password with kwargs, If so, use
|
||||||
|
`auth_type='token'`.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if cloud_config is not None:
|
||||||
|
return OpenStackCloud(cloud_config=cloud_config, **kwargs)
|
||||||
|
elif connection is not None:
|
||||||
|
return OpenStackCloud(cloud_config=connection.config, **kwargs)
|
||||||
|
else:
|
||||||
|
return OpenStackCloud(
|
||||||
|
cloud_config=get_openstack_config(
|
||||||
|
parser_or_options=parser_or_options, load_envvars=load_envvars,
|
||||||
|
load_yaml_config=load_yaml_config,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
)
|
@ -0,0 +1,33 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
try:
|
||||||
|
from unittest import mock # Python 3.3+
|
||||||
|
except ImportError:
|
||||||
|
import mock # noqa: Python 2.7
|
||||||
|
|
||||||
|
try:
|
||||||
|
import unittest2 as unittest # Python 2.7
|
||||||
|
except ImportError:
|
||||||
|
import unittest # noqa
|
@ -1,53 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright 2010-2011 OpenStack Foundation
|
|
||||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
|
||||||
#
|
|
||||||
# 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 fixtures
|
|
||||||
import testtools
|
|
||||||
|
|
||||||
_TRUE_VALUES = ('True', 'true', '1', 'yes')
|
|
||||||
|
|
||||||
|
|
||||||
class TestCase(testtools.TestCase):
|
|
||||||
|
|
||||||
"""Test case base class for all unit tests."""
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
"""Run before each test method to initialize test environment."""
|
|
||||||
|
|
||||||
super(TestCase, self).setUp()
|
|
||||||
test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
|
|
||||||
try:
|
|
||||||
test_timeout = int(test_timeout)
|
|
||||||
except ValueError:
|
|
||||||
# If timeout value is invalid do not set a timeout.
|
|
||||||
test_timeout = 0
|
|
||||||
if test_timeout > 0:
|
|
||||||
self.useFixture(fixtures.Timeout(test_timeout, gentle=True))
|
|
||||||
|
|
||||||
self.useFixture(fixtures.NestedTempfile())
|
|
||||||
self.useFixture(fixtures.TempHomeDir())
|
|
||||||
|
|
||||||
if os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES:
|
|
||||||
stdout = self.useFixture(fixtures.StringStream('stdout')).stream
|
|
||||||
self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
|
|
||||||
if os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES:
|
|
||||||
stderr = self.useFixture(fixtures.StringStream('stderr')).stream
|
|
||||||
self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
|
|
||||||
|
|
||||||
self.log_fixture = self.useFixture(fixtures.FakeLogger())
|
|
30
flameclient/tests/fixtures/__init__.py
vendored
Normal file
30
flameclient/tests/fixtures/__init__.py
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
FIXTURES_DIR = os.path.realpath(
|
||||||
|
os.path.dirname(__file__)
|
||||||
|
)
|
28
flameclient/tests/fixtures/openstackcloud/__init__.py
vendored
Normal file
28
flameclient/tests/fixtures/openstackcloud/__init__.py
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
from flameclient.utils import load_resource_modules
|
||||||
|
|
||||||
|
|
||||||
|
FIXTURES = load_resource_modules(__file__)
|
432
flameclient/tests/fixtures/openstackcloud/flavors.py
vendored
Normal file
432
flameclient/tests/fixtures/openstackcloud/flavors.py
vendored
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'compute.flavors'
|
||||||
|
|
||||||
|
FIXTURES = [{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 20,
|
||||||
|
'id': '16',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/16',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/16',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 't1.cw.tiny',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 629,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 1},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '17',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/17',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/17',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 's1.cw.small-1',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 1792,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 1},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '18',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/18',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/18',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.highcpu-2',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 4000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 2},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '19',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/19',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/19',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.highcpu-4',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 8000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 4},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '20',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/20',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/20',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.highcpu-8',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 16000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 8},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '21',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/21',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/21',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.standard-1',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 4000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 1},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '22',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/22',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/22',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.standard-2',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 8000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 2},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '23',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/23',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/23',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.standard-4',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 16000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 4},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '24',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/24',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/24',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.standard-8',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 32000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 8},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '25',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/25',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/25',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.standard-12',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 48000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 12},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '26',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/26',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/26',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.standard-16',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 64000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 16},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '28',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/28',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/28',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.highmem-2',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 13312,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 2},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '29',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/29',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/29',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.highmem-4',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 26624,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 4},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '30',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/30',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/30',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.highmem-8',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 53248,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 8},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '31',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/31',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/31',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n1.cw.highmem-12',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 79872,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 12},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '38',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/38',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/38',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n2.cw.highmem-2',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 13312,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 2},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 50,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '39',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/39',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/39',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n2.cw.highmem-4',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 26624,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 4},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 100,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '40',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/40',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/40',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n2.cw.highmem-8',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 53248,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 8},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 300,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '41',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/41',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/41',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n2.cw.highmem-16',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 104000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 16},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '42',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/42',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/42',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n2.cw.standard-1',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 4000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 1},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '43',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/43',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/43',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n2.cw.standard-2',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 8000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 2},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '44',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/44',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/44',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n2.cw.standard-4',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 16000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 4},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '45',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/45',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/45',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n2.cw.standard-8',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 32000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 8},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '46',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/46',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/46',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'n2.cw.standard-16',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 64000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 16},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 400,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '53',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/53',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/53',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'i2.cw.largessd-4',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 32000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 4},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 850,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '54',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/54',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/54',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'i2.cw.largessd-8',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 64000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 8},
|
||||||
|
{'OS-FLV-DISABLED:disabled': False,
|
||||||
|
'OS-FLV-EXT-DATA:ephemeral': 1750,
|
||||||
|
'description': None,
|
||||||
|
'disk': 50,
|
||||||
|
'id': '55',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/flavors/55',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/55',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'name': 'i2.cw.largessd-16',
|
||||||
|
'os-flavor-access:is_public': True,
|
||||||
|
'ram': 128000,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'swap': '',
|
||||||
|
'vcpus': 16}]
|
46
flameclient/tests/fixtures/openstackcloud/floatingips.py
vendored
Normal file
46
flameclient/tests/fixtures/openstackcloud/floatingips.py
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'network.ips'
|
||||||
|
|
||||||
|
FIXTURES = [{'created_at': None,
|
||||||
|
'description': None,
|
||||||
|
'dns_domain': None,
|
||||||
|
'dns_name': None,
|
||||||
|
'fixed_ip_address': '192.168.0.8',
|
||||||
|
'floating_ip_address': '84.39.32.171',
|
||||||
|
'floating_network_id': '6ea98324-0f14-49f6-97c0-885d1b8dc517',
|
||||||
|
'id': 'e6f50641-6c7e-468c-9623-1fd5ee2c1ebc',
|
||||||
|
'name': '84.39.32.171',
|
||||||
|
'port_details': None,
|
||||||
|
'port_id': None,
|
||||||
|
'qos_policy_id': None,
|
||||||
|
'revision_number': None,
|
||||||
|
'router_id': None,
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'subnet_id': None,
|
||||||
|
'tags': [],
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'updated_at': None}]
|
201
flameclient/tests/fixtures/openstackcloud/images.py
vendored
Normal file
201
flameclient/tests/fixtures/openstackcloud/images.py
vendored
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'image.images'
|
||||||
|
|
||||||
|
FIXTURES = [{'architecture': None,
|
||||||
|
'auto_disk_config': None,
|
||||||
|
'checksum': '57baccdf32b77ff7939d429b842d4440',
|
||||||
|
'container_format': 'bare',
|
||||||
|
'created_at': '2017-06-20T14:53:41Z',
|
||||||
|
'direct_url': None,
|
||||||
|
'disk_format': 'qcow2',
|
||||||
|
'file': '/v2/images/8254d703-e46f-4101-88ff-6f40bf7df51a/file',
|
||||||
|
'hw_boot_menu': None,
|
||||||
|
'hw_cpu_cores': None,
|
||||||
|
'hw_cpu_sockets': None,
|
||||||
|
'hw_cpu_threads': None,
|
||||||
|
'hw_disk_bus': None,
|
||||||
|
'hw_machine_type': None,
|
||||||
|
'hw_qemu_guest_agent': None,
|
||||||
|
'hw_rng_model': 'virtio',
|
||||||
|
'hw_scsi_model': None,
|
||||||
|
'hw_serial_port_count': None,
|
||||||
|
'hw_video_model': None,
|
||||||
|
'hw_video_ram': None,
|
||||||
|
'hw_vif_model': None,
|
||||||
|
'hw_vif_multiqueue_enabled': None,
|
||||||
|
'hw_watchdog_action': None,
|
||||||
|
'hypervisor-type': None,
|
||||||
|
'id': '8254d703-e46f-4101-88ff-6f40bf7df51a',
|
||||||
|
'img_config_drive': None,
|
||||||
|
'instance_type_rxtx_factor': None,
|
||||||
|
'instance_uuid': None,
|
||||||
|
'kernel_id': None,
|
||||||
|
'locations': None,
|
||||||
|
'metadata': None,
|
||||||
|
'min_disk': 50,
|
||||||
|
'min_ram': 2048,
|
||||||
|
'name': 'Windows Server 2012 R2 Standard FR',
|
||||||
|
'os_admin_user': None,
|
||||||
|
'os_command_line': None,
|
||||||
|
'os_distro': None,
|
||||||
|
'os_require_quiesce': None,
|
||||||
|
'os_secure_boot': None,
|
||||||
|
'os_type': None,
|
||||||
|
'os_version': None,
|
||||||
|
'owner': '3ab52a7f1b824983bf418df633d9d88d',
|
||||||
|
'path': None,
|
||||||
|
'properties': None,
|
||||||
|
'protected': False,
|
||||||
|
'ramdisk_id': None,
|
||||||
|
'size': 7976386560,
|
||||||
|
'status': 'active',
|
||||||
|
'store': None,
|
||||||
|
'tags': [],
|
||||||
|
'updated_at': '2017-06-20T14:56:43Z',
|
||||||
|
'url': None,
|
||||||
|
'value': None,
|
||||||
|
'virtual_size': None,
|
||||||
|
'visibility': 'public',
|
||||||
|
'vm_mode': None,
|
||||||
|
'vmware_adaptertype': None,
|
||||||
|
'vmware_ostype': None},
|
||||||
|
{'architecture': None,
|
||||||
|
'auto_disk_config': None,
|
||||||
|
'checksum': '8ec802fe753dfe8e226645a2e0106bf7',
|
||||||
|
'container_format': 'bare',
|
||||||
|
'created_at': '2017-03-23T15:46:41Z',
|
||||||
|
'direct_url': None,
|
||||||
|
'disk_format': 'qcow2',
|
||||||
|
'file': '/v2/images/70a9c910-dd99-4065-bce9-11e89bc479fe/file',
|
||||||
|
'hw_boot_menu': None,
|
||||||
|
'hw_cpu_cores': None,
|
||||||
|
'hw_cpu_sockets': None,
|
||||||
|
'hw_cpu_threads': None,
|
||||||
|
'hw_disk_bus': None,
|
||||||
|
'hw_machine_type': None,
|
||||||
|
'hw_qemu_guest_agent': None,
|
||||||
|
'hw_rng_model': 'virtio',
|
||||||
|
'hw_scsi_model': None,
|
||||||
|
'hw_serial_port_count': None,
|
||||||
|
'hw_video_model': None,
|
||||||
|
'hw_video_ram': None,
|
||||||
|
'hw_vif_model': None,
|
||||||
|
'hw_vif_multiqueue_enabled': None,
|
||||||
|
'hw_watchdog_action': None,
|
||||||
|
'hypervisor-type': None,
|
||||||
|
'id': '70a9c910-dd99-4065-bce9-11e89bc479fe',
|
||||||
|
'img_config_drive': None,
|
||||||
|
'instance_type_rxtx_factor': None,
|
||||||
|
'instance_uuid': None,
|
||||||
|
'kernel_id': None,
|
||||||
|
'locations': None,
|
||||||
|
'metadata': None,
|
||||||
|
'min_disk': 20,
|
||||||
|
'min_ram': 0,
|
||||||
|
'name': 'Ubuntu 14.04',
|
||||||
|
'os_admin_user': None,
|
||||||
|
'os_command_line': None,
|
||||||
|
'os_distro': None,
|
||||||
|
'os_require_quiesce': None,
|
||||||
|
'os_secure_boot': None,
|
||||||
|
'os_type': None,
|
||||||
|
'os_version': None,
|
||||||
|
'owner': '3ab52a7f1b824983bf418df633d9d88d',
|
||||||
|
'path': None,
|
||||||
|
'properties': None,
|
||||||
|
'protected': False,
|
||||||
|
'ramdisk_id': None,
|
||||||
|
'size': 1009057792,
|
||||||
|
'status': 'active',
|
||||||
|
'store': None,
|
||||||
|
'tags': [],
|
||||||
|
'updated_at': '2017-12-26T10:33:50Z',
|
||||||
|
'url': None,
|
||||||
|
'value': None,
|
||||||
|
'virtual_size': None,
|
||||||
|
'visibility': 'public',
|
||||||
|
'vm_mode': None,
|
||||||
|
'vmware_adaptertype': None,
|
||||||
|
'vmware_ostype': None},
|
||||||
|
{'architecture': None,
|
||||||
|
'auto_disk_config': None,
|
||||||
|
'checksum': '12872d8897d2eabfceac8b4627ff88f0',
|
||||||
|
'container_format': 'bare',
|
||||||
|
'created_at': '2016-06-07T07:36:26Z',
|
||||||
|
'direct_url': None,
|
||||||
|
'disk_format': 'qcow2',
|
||||||
|
'file': '/v2/images/dd7d4b21-79b8-42f0-8464-0d1a5274c638/file',
|
||||||
|
'hw_boot_menu': None,
|
||||||
|
'hw_cpu_cores': None,
|
||||||
|
'hw_cpu_sockets': None,
|
||||||
|
'hw_cpu_threads': None,
|
||||||
|
'hw_disk_bus': None,
|
||||||
|
'hw_machine_type': None,
|
||||||
|
'hw_qemu_guest_agent': None,
|
||||||
|
'hw_rng_model': None,
|
||||||
|
'hw_scsi_model': None,
|
||||||
|
'hw_serial_port_count': None,
|
||||||
|
'hw_video_model': None,
|
||||||
|
'hw_video_ram': None,
|
||||||
|
'hw_vif_model': None,
|
||||||
|
'hw_vif_multiqueue_enabled': None,
|
||||||
|
'hw_watchdog_action': None,
|
||||||
|
'hypervisor-type': None,
|
||||||
|
'id': 'dd7d4b21-79b8-42f0-8464-0d1a5274c638',
|
||||||
|
'img_config_drive': None,
|
||||||
|
'instance_type_rxtx_factor': None,
|
||||||
|
'instance_uuid': None,
|
||||||
|
'kernel_id': None,
|
||||||
|
'locations': None,
|
||||||
|
'metadata': None,
|
||||||
|
'min_disk': 0,
|
||||||
|
'min_ram': 0,
|
||||||
|
'name': 'tempest-ubuntu-do-not-erase',
|
||||||
|
'os_admin_user': None,
|
||||||
|
'os_command_line': None,
|
||||||
|
'os_distro': None,
|
||||||
|
'os_require_quiesce': None,
|
||||||
|
'os_secure_boot': None,
|
||||||
|
'os_type': None,
|
||||||
|
'os_version': None,
|
||||||
|
'owner': '3ab52a7f1b824983bf418df633d9d88d',
|
||||||
|
'path': None,
|
||||||
|
'properties': None,
|
||||||
|
'protected': False,
|
||||||
|
'ramdisk_id': None,
|
||||||
|
'size': 261488640,
|
||||||
|
'status': 'active',
|
||||||
|
'store': None,
|
||||||
|
'tags': [],
|
||||||
|
'updated_at': '2016-06-07T07:36:31Z',
|
||||||
|
'url': None,
|
||||||
|
'value': None,
|
||||||
|
'virtual_size': None,
|
||||||
|
'visibility': 'private',
|
||||||
|
'vm_mode': None,
|
||||||
|
'vmware_adaptertype': None,
|
||||||
|
'vmware_ostype': None}]
|
41
flameclient/tests/fixtures/openstackcloud/key_pairs.py
vendored
Normal file
41
flameclient/tests/fixtures/openstackcloud/key_pairs.py
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'compute.keypairs'
|
||||||
|
|
||||||
|
FIXTURES = [{'fingerprint': '01:99:63:d2:96:d4:23:25:2f:d5:c9:e4:2f:30:d2:3f',
|
||||||
|
'id': 'tellurium-key',
|
||||||
|
'name': 'tellurium-key',
|
||||||
|
'private_key': None,
|
||||||
|
'public_key': 'ssh-rsa '
|
||||||
|
'AAAAB3NzaC1yc2EAAAADAQABAAABAQCwp5kVZ+3baPZllNXZDG2mivd5nJ5wWY6Jj/WV6NlO6cUiaH5om6itU3lyJxtAbLgbbvY2FjMg1PI2JI3EHx0OSPEbDdeNsQGi31qyuiB1S5p6TreI0Dfy0tywJ9G2CURjkuJnC8SvnMfVYLMFBvx7p8RzxSdDm/zrmc4KY3ktdfYQDNtEiH2jucUUiY0ipVkDNhhv03+5C9cnpaIcVDBkddE/KEME8NIIh7s6aYCXJEWJx85nOVVRD5qK7ouV6FcGVn6zqWRD3jn0iSxcFwiKx7p6M77PmJAY4gBIpWQmutok6T4ZrXxa7jE4dybwo5e8dyvGyc7WWGqXcmcinUWr '
|
||||||
|
'Generated-by-Nova'},
|
||||||
|
{'fingerprint': '76:e2:94:d2:13:c0:72:49:43:a7:58:f5:92:2f:e9:62',
|
||||||
|
'id': 'tellurium-key-phrase',
|
||||||
|
'name': 'tellurium-key-phrase',
|
||||||
|
'private_key': None,
|
||||||
|
'public_key': 'ssh-rsa '
|
||||||
|
'AAAAB3NzaC1yc2EAAAADAQABAAABAQCaYaTC6KCC2GURFMpRQiRq8Og10PcBbVnrQqluzi2E5vAqTHAegzivmGB8h2xrjXUfbKV2bE8kz2ZE66sq1yLO/jZ+rkOA+zLnOxNwkk3gQq57b26ZegPL2tTgottJTPGyPz6v2+LLtDf/+xTJMjkPKcMWylu12Js0XKVkdY35fwN7fRvA4xghtGu1GcmS2XFDMmeLDrG1KNPbBLj5cGoD723Ho7ZhAjLThoY/xMN2OYsSNzrg3S00QngZMzQvJf0ETrB3GtITk5FUs54qMRfiyUC72lw0gLTIJK8rs7fX/yeO+467afRt2xwHN50rEWJPeTVYWdlH/msh7NQ3LZ8/ '
|
||||||
|
'root@9b638ff21113'}]
|
103
flameclient/tests/fixtures/openstackcloud/networks.py
vendored
Normal file
103
flameclient/tests/fixtures/openstackcloud/networks.py
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'network.networks'
|
||||||
|
|
||||||
|
FIXTURES = [{'admin_state_up': True,
|
||||||
|
'availability_zone_hints': None,
|
||||||
|
'availability_zones': None,
|
||||||
|
'created_at': None,
|
||||||
|
'description': None,
|
||||||
|
'dns_domain': None,
|
||||||
|
'id': '6ea98324-0f14-49f6-97c0-885d1b8dc517',
|
||||||
|
'ipv4_address_scope': None,
|
||||||
|
'ipv6_address_scope': None,
|
||||||
|
'is_default': None,
|
||||||
|
'mtu': None,
|
||||||
|
'name': 'public',
|
||||||
|
'port_security_enabled': False,
|
||||||
|
'project_id': None,
|
||||||
|
'provider:network_type': None,
|
||||||
|
'provider:physical_network': None,
|
||||||
|
'provider:segmentation_id': None,
|
||||||
|
'qos_policy_id': None,
|
||||||
|
'revision_number': None,
|
||||||
|
'router:external': True,
|
||||||
|
'segments': None,
|
||||||
|
'shared': False,
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'subnets': ['7ce9190e-397e-4523-bb9a-942a338555c8',
|
||||||
|
'16af2b37-a739-474a-b64d-ad5b515b24d7',
|
||||||
|
'85bc9804-bde9-4fc3-ac28-138bbed0be47',
|
||||||
|
'12469c2c-6902-460a-ad54-9252ca791d55',
|
||||||
|
'84095c22-48af-4cf5-b03d-0c745bfa1586',
|
||||||
|
'12f473cc-a01e-4f70-86d7-c1ae05058545',
|
||||||
|
'02efcad7-4744-41c4-8429-332828309d4f',
|
||||||
|
'aa8fc58b-5db8-45ba-a354-180e5e2ae84b',
|
||||||
|
'6ac09891-9788-46b7-8165-9d2c9cefa483',
|
||||||
|
'38d8fc45-2698-4ffc-9beb-59331e3ef68d',
|
||||||
|
'aded311e-5766-4adc-b6d8-64dd5c93a8c3',
|
||||||
|
'b7f41f14-35a2-4bf4-a2b3-60c2200c0fb5',
|
||||||
|
'65d8722e-09f6-4b39-a693-e61018867377',
|
||||||
|
'c5387c58-542c-4cfd-8338-afcbd37e4546',
|
||||||
|
'baa6798a-0eba-417e-b294-31fbf1c4a7c5',
|
||||||
|
'3c8fde67-c209-4716-a515-5777667a4835',
|
||||||
|
'bf806833-7f33-4254-865f-8a874d36d17c',
|
||||||
|
'6736cae7-7501-4e10-af94-bb06acaf5de6',
|
||||||
|
'7b2e3c57-e8cc-47ac-a008-e0ee2db5e567',
|
||||||
|
'85342bf1-7e69-4468-b269-8435c4991773',
|
||||||
|
'6e289f4e-ec6a-4fd7-9bbc-94c3f17e57a8',
|
||||||
|
'de042fd3-acf3-487f-819f-7b18617728ec',
|
||||||
|
'da35a785-99ea-4d54-b056-0c20feca1125'],
|
||||||
|
'tags': [],
|
||||||
|
'updated_at': None,
|
||||||
|
'vlan_transparent': None},
|
||||||
|
{'admin_state_up': True,
|
||||||
|
'availability_zone_hints': None,
|
||||||
|
'availability_zones': None,
|
||||||
|
'created_at': None,
|
||||||
|
'description': None,
|
||||||
|
'dns_domain': None,
|
||||||
|
'id': 'f054013d-7052-4708-9c72-2948a329fac3',
|
||||||
|
'ipv4_address_scope': None,
|
||||||
|
'ipv6_address_scope': None,
|
||||||
|
'is_default': None,
|
||||||
|
'mtu': None,
|
||||||
|
'name': 'tellurium_net',
|
||||||
|
'port_security_enabled': False,
|
||||||
|
'project_id': None,
|
||||||
|
'provider:network_type': None,
|
||||||
|
'provider:physical_network': None,
|
||||||
|
'provider:segmentation_id': None,
|
||||||
|
'qos_policy_id': None,
|
||||||
|
'revision_number': None,
|
||||||
|
'router:external': False,
|
||||||
|
'segments': None,
|
||||||
|
'shared': False,
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'subnets': ['541f0782-587f-428b-bd79-ca227a66973b'],
|
||||||
|
'tags': [],
|
||||||
|
'updated_at': None,
|
||||||
|
'vlan_transparent': None}]
|
183
flameclient/tests/fixtures/openstackcloud/ports.py
vendored
Normal file
183
flameclient/tests/fixtures/openstackcloud/ports.py
vendored
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'network.ports'
|
||||||
|
|
||||||
|
FIXTURES = [{'admin_state_up': True,
|
||||||
|
'allowed_address_pairs': None,
|
||||||
|
'binding:host_id': None,
|
||||||
|
'binding:profile': None,
|
||||||
|
'binding:vif_details': None,
|
||||||
|
'binding:vif_type': None,
|
||||||
|
'binding:vnic_type': 'normal',
|
||||||
|
'created_at': None,
|
||||||
|
'data_plane_status': None,
|
||||||
|
'description': None,
|
||||||
|
'device_id': '2cf8db13-312a-4307-ba38-43b727ebcce6',
|
||||||
|
'device_owner': 'compute:None',
|
||||||
|
'dns_assignment': None,
|
||||||
|
'dns_domain': None,
|
||||||
|
'dns_name': None,
|
||||||
|
'extra_dhcp_opts': None,
|
||||||
|
'fixed_ips': [{'ip_address': '192.168.0.3',
|
||||||
|
'subnet_id': '541f0782-587f-428b-bd79-ca227a66973b'}],
|
||||||
|
'id': '3decf6f8-2591-4ab0-af19-00f6ce6a0cf5',
|
||||||
|
'mac_address': '02:3d:ec:f6:f8:25',
|
||||||
|
'name': 'Tellurium_Fixtures-windows_port-hxvnswbzi56x',
|
||||||
|
'network_id': 'f054013d-7052-4708-9c72-2948a329fac3',
|
||||||
|
'port_security_enabled': False,
|
||||||
|
'qos_policy_id': None,
|
||||||
|
'revision_number': None,
|
||||||
|
'security_groups': ['9ffd2654-7ca6-48ae-852d-6503d5ce4a60'],
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'tags': [],
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'trunk_details': None,
|
||||||
|
'updated_at': None},
|
||||||
|
{'admin_state_up': True,
|
||||||
|
'allowed_address_pairs': None,
|
||||||
|
'binding:host_id': None,
|
||||||
|
'binding:profile': None,
|
||||||
|
'binding:vif_details': None,
|
||||||
|
'binding:vif_type': None,
|
||||||
|
'binding:vnic_type': 'normal',
|
||||||
|
'created_at': None,
|
||||||
|
'data_plane_status': None,
|
||||||
|
'description': None,
|
||||||
|
'device_id': '4add78fa-93df-4550-aaf7-aba2239ba00a',
|
||||||
|
'device_owner': 'compute:None',
|
||||||
|
'dns_assignment': None,
|
||||||
|
'dns_domain': None,
|
||||||
|
'dns_name': None,
|
||||||
|
'extra_dhcp_opts': None,
|
||||||
|
'fixed_ips': [{'ip_address': '192.168.0.4',
|
||||||
|
'subnet_id': '541f0782-587f-428b-bd79-ca227a66973b'}],
|
||||||
|
'id': '206df716-da1a-4a50-ba1a-74f42a007dd0',
|
||||||
|
'mac_address': '02:20:6d:f7:16:da',
|
||||||
|
'name': 'Tellurium_Fixtures-instance_port-fmln6fjl4yvo',
|
||||||
|
'network_id': 'f054013d-7052-4708-9c72-2948a329fac3',
|
||||||
|
'port_security_enabled': False,
|
||||||
|
'qos_policy_id': None,
|
||||||
|
'revision_number': None,
|
||||||
|
'security_groups': ['9ffd2654-7ca6-48ae-852d-6503d5ce4a60'],
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'tags': [],
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'trunk_details': None,
|
||||||
|
'updated_at': None},
|
||||||
|
{'admin_state_up': True,
|
||||||
|
'allowed_address_pairs': None,
|
||||||
|
'binding:host_id': None,
|
||||||
|
'binding:profile': None,
|
||||||
|
'binding:vif_details': None,
|
||||||
|
'binding:vif_type': None,
|
||||||
|
'binding:vnic_type': 'normal',
|
||||||
|
'created_at': None,
|
||||||
|
'data_plane_status': None,
|
||||||
|
'description': None,
|
||||||
|
'device_id': 'b6316031-e629-48b8-aac5-3f1b21ffe0f3',
|
||||||
|
'device_owner': 'compute:None',
|
||||||
|
'dns_assignment': None,
|
||||||
|
'dns_domain': None,
|
||||||
|
'dns_name': None,
|
||||||
|
'extra_dhcp_opts': None,
|
||||||
|
'fixed_ips': [{'ip_address': '192.168.0.5',
|
||||||
|
'subnet_id': '541f0782-587f-428b-bd79-ca227a66973b'}],
|
||||||
|
'id': 'cb336b60-f298-4a51-9443-89880e3cdb51',
|
||||||
|
'mac_address': '02:cb:33:6b:60:f2',
|
||||||
|
'name': 'Tellurium_Fixtures-windows_ssh_pass_port-4zlwanbetsg2',
|
||||||
|
'network_id': 'f054013d-7052-4708-9c72-2948a329fac3',
|
||||||
|
'port_security_enabled': False,
|
||||||
|
'qos_policy_id': None,
|
||||||
|
'revision_number': None,
|
||||||
|
'security_groups': ['9ffd2654-7ca6-48ae-852d-6503d5ce4a60'],
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'tags': [],
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'trunk_details': None,
|
||||||
|
'updated_at': None},
|
||||||
|
{'admin_state_up': True,
|
||||||
|
'allowed_address_pairs': None,
|
||||||
|
'binding:host_id': None,
|
||||||
|
'binding:profile': None,
|
||||||
|
'binding:vif_details': None,
|
||||||
|
'binding:vif_type': None,
|
||||||
|
'binding:vnic_type': 'normal',
|
||||||
|
'created_at': None,
|
||||||
|
'data_plane_status': None,
|
||||||
|
'description': None,
|
||||||
|
'device_id': 'ebc6dd0c-a276-4368-8084-bd37c587cc24',
|
||||||
|
'device_owner': 'network:router_interface',
|
||||||
|
'dns_assignment': None,
|
||||||
|
'dns_domain': None,
|
||||||
|
'dns_name': None,
|
||||||
|
'extra_dhcp_opts': None,
|
||||||
|
'fixed_ips': [{'ip_address': '192.168.0.1',
|
||||||
|
'subnet_id': '541f0782-587f-428b-bd79-ca227a66973b'}],
|
||||||
|
'id': 'e3b88764-3c46-44aa-ae26-fa6ec2df93bd',
|
||||||
|
'mac_address': '02:e3:b8:87:64:3c',
|
||||||
|
'name': 'e3b88764-3c46-44aa-ae26-fa6ec2df93bd',
|
||||||
|
'network_id': 'f054013d-7052-4708-9c72-2948a329fac3',
|
||||||
|
'port_security_enabled': False,
|
||||||
|
'qos_policy_id': None,
|
||||||
|
'revision_number': None,
|
||||||
|
'security_groups': ['9ffd2654-7ca6-48ae-852d-6503d5ce4a60'],
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'tags': [],
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'trunk_details': None,
|
||||||
|
'updated_at': None},
|
||||||
|
{'admin_state_up': True,
|
||||||
|
'allowed_address_pairs': None,
|
||||||
|
'binding:host_id': None,
|
||||||
|
'binding:profile': None,
|
||||||
|
'binding:vif_details': None,
|
||||||
|
'binding:vif_type': None,
|
||||||
|
'binding:vnic_type': 'normal',
|
||||||
|
'created_at': None,
|
||||||
|
'data_plane_status': None,
|
||||||
|
'description': None,
|
||||||
|
'device_id': '99c42e21-5099-4903-9121-063925aad299',
|
||||||
|
'device_owner': 'compute:nova',
|
||||||
|
'dns_assignment': None,
|
||||||
|
'dns_domain': None,
|
||||||
|
'dns_name': None,
|
||||||
|
'extra_dhcp_opts': None,
|
||||||
|
'fixed_ips': [{'ip_address': '192.168.0.6',
|
||||||
|
'subnet_id': '541f0782-587f-428b-bd79-ca227a66973b'}],
|
||||||
|
'id': '4f413432-b499-4fcc-a81a-1ee0d8bc16b7',
|
||||||
|
'mac_address': '02:4f:41:34:32:b4',
|
||||||
|
'name': '4f413432-b499-4fcc-a81a-1ee0d8bc16b7',
|
||||||
|
'network_id': 'f054013d-7052-4708-9c72-2948a329fac3',
|
||||||
|
'port_security_enabled': False,
|
||||||
|
'qos_policy_id': None,
|
||||||
|
'revision_number': None,
|
||||||
|
'security_groups': ['156799a3-565e-48b3-938c-f95f09093c66',
|
||||||
|
'9ffd2654-7ca6-48ae-852d-6503d5ce4a60'],
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'tags': [],
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'trunk_details': None,
|
||||||
|
'updated_at': None}]
|
45
flameclient/tests/fixtures/openstackcloud/routers.py
vendored
Normal file
45
flameclient/tests/fixtures/openstackcloud/routers.py
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'network.routers'
|
||||||
|
|
||||||
|
FIXTURES = [{'admin_state_up': True,
|
||||||
|
'availability_zone_hints': None,
|
||||||
|
'availability_zones': None,
|
||||||
|
'created_at': None,
|
||||||
|
'description': None,
|
||||||
|
'distributed': None,
|
||||||
|
'external_gateway_info': {'enable_snat': True,
|
||||||
|
'network_id': '6ea98324-0f14-49f6-97c0-885d1b8dc517'},
|
||||||
|
'flavor_id': None,
|
||||||
|
'ha': None,
|
||||||
|
'id': 'ebc6dd0c-a276-4368-8084-bd37c587cc24',
|
||||||
|
'name': 'tellurium_router',
|
||||||
|
'revision': None,
|
||||||
|
'routes': None,
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'tags': [],
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'updated_at': None}]
|
113
flameclient/tests/fixtures/openstackcloud/security_groups.py
vendored
Normal file
113
flameclient/tests/fixtures/openstackcloud/security_groups.py
vendored
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'network.security_groups'
|
||||||
|
|
||||||
|
FIXTURES = [{'created_at': None,
|
||||||
|
'description': None,
|
||||||
|
'id': '9ffd2654-7ca6-48ae-852d-6503d5ce4a60',
|
||||||
|
'name': 'default',
|
||||||
|
'revision_number': None,
|
||||||
|
'security_group_rules': [{'direction': 'ingress',
|
||||||
|
'ethertype': 'IPv4',
|
||||||
|
'id': 'ec72eaca-22e2-47b6-b1a5-2fe6f8129e47',
|
||||||
|
'port_range_max': None,
|
||||||
|
'port_range_min': None,
|
||||||
|
'protocol': None,
|
||||||
|
'remote_group_id': '9ffd2654-7ca6-48ae-852d-6503d5ce4a60',
|
||||||
|
'remote_ip_prefix': None,
|
||||||
|
'security_group_id': '9ffd2654-7ca6-48ae-852d-6503d5ce4a60',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce'},
|
||||||
|
{'direction': 'ingress',
|
||||||
|
'ethertype': 'IPv6',
|
||||||
|
'id': 'd5720f56-e7ce-4c7f-982d-a70d76c37b11',
|
||||||
|
'port_range_max': None,
|
||||||
|
'port_range_min': None,
|
||||||
|
'protocol': None,
|
||||||
|
'remote_group_id': '9ffd2654-7ca6-48ae-852d-6503d5ce4a60',
|
||||||
|
'remote_ip_prefix': None,
|
||||||
|
'security_group_id': '9ffd2654-7ca6-48ae-852d-6503d5ce4a60',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce'},
|
||||||
|
{'direction': 'egress',
|
||||||
|
'ethertype': 'IPv4',
|
||||||
|
'id': 'd05bc784-b34c-4e0c-a2ea-7b10992caa1e',
|
||||||
|
'port_range_max': None,
|
||||||
|
'port_range_min': None,
|
||||||
|
'protocol': None,
|
||||||
|
'remote_group_id': None,
|
||||||
|
'remote_ip_prefix': '0.0.0.0/0',
|
||||||
|
'security_group_id': '9ffd2654-7ca6-48ae-852d-6503d5ce4a60',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce'},
|
||||||
|
{'direction': 'egress',
|
||||||
|
'ethertype': 'IPv6',
|
||||||
|
'id': 'a6abbc8e-92c2-42f6-9ac9-a04544588739',
|
||||||
|
'port_range_max': None,
|
||||||
|
'port_range_min': None,
|
||||||
|
'protocol': None,
|
||||||
|
'remote_group_id': None,
|
||||||
|
'remote_ip_prefix': '::/0',
|
||||||
|
'security_group_id': '9ffd2654-7ca6-48ae-852d-6503d5ce4a60',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce'}],
|
||||||
|
'tags': [],
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'updated_at': None},
|
||||||
|
{'created_at': None,
|
||||||
|
'description': '',
|
||||||
|
'id': '156799a3-565e-48b3-938c-f95f09093c66',
|
||||||
|
'name': 'http',
|
||||||
|
'revision_number': None,
|
||||||
|
'security_group_rules': [{'direction': 'egress',
|
||||||
|
'ethertype': 'IPv4',
|
||||||
|
'id': '80508f7d-b893-4bcb-bddc-51a946634492',
|
||||||
|
'port_range_max': None,
|
||||||
|
'port_range_min': None,
|
||||||
|
'protocol': None,
|
||||||
|
'remote_group_id': None,
|
||||||
|
'remote_ip_prefix': '0.0.0.0/0',
|
||||||
|
'security_group_id': '156799a3-565e-48b3-938c-f95f09093c66',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce'},
|
||||||
|
{'direction': 'egress',
|
||||||
|
'ethertype': 'IPv6',
|
||||||
|
'id': 'eab50b80-bc3c-484c-a3c8-fd6cf5ee9c50',
|
||||||
|
'port_range_max': None,
|
||||||
|
'port_range_min': None,
|
||||||
|
'protocol': None,
|
||||||
|
'remote_group_id': None,
|
||||||
|
'remote_ip_prefix': None,
|
||||||
|
'security_group_id': '156799a3-565e-48b3-938c-f95f09093c66',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce'},
|
||||||
|
{'direction': 'ingress',
|
||||||
|
'ethertype': 'IPv4',
|
||||||
|
'id': 'a6ed0dc8-ee29-462e-84a0-961675e08c4a',
|
||||||
|
'port_range_max': 80,
|
||||||
|
'port_range_min': 80,
|
||||||
|
'protocol': 'tcp',
|
||||||
|
'remote_group_id': None,
|
||||||
|
'remote_ip_prefix': '0.0.0.0/0',
|
||||||
|
'security_group_id': '156799a3-565e-48b3-938c-f95f09093c66',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce'}],
|
||||||
|
'tags': [],
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'updated_at': None}]
|
28
flameclient/tests/fixtures/openstackcloud/server_groups.py
vendored
Normal file
28
flameclient/tests/fixtures/openstackcloud/server_groups.py
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'compute.server_groups'
|
||||||
|
|
||||||
|
FIXTURES = []
|
213
flameclient/tests/fixtures/openstackcloud/servers.py
vendored
Normal file
213
flameclient/tests/fixtures/openstackcloud/servers.py
vendored
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'compute.servers'
|
||||||
|
|
||||||
|
FIXTURES = [{'OS-DCF:diskConfig': 'AUTO',
|
||||||
|
'OS-EXT-AZ:availability_zone': 'nova',
|
||||||
|
'OS-EXT-SRV-ATTR:hypervisor_hostname': None,
|
||||||
|
'OS-EXT-SRV-ATTR:instance_name': None,
|
||||||
|
'OS-EXT-SRV-ATTR:user_data': None,
|
||||||
|
'OS-EXT-STS:power_state': 1,
|
||||||
|
'OS-EXT-STS:task_state': None,
|
||||||
|
'OS-EXT-STS:vm_state': 'active',
|
||||||
|
'OS-SCH-HNT:scheduler_hints': None,
|
||||||
|
'OS-SRV-USG:launched_at': '2018-11-09T13:39:42.000000',
|
||||||
|
'OS-SRV-USG:terminated_at': None,
|
||||||
|
'accessIPv4': '',
|
||||||
|
'accessIPv6': '',
|
||||||
|
'addresses': {'tellurium_net': [{'OS-EXT-IPS-MAC:mac_addr': '02:4f:41:34:32:b4',
|
||||||
|
'OS-EXT-IPS:type': 'fixed',
|
||||||
|
'addr': '192.168.0.6',
|
||||||
|
'version': 4}]},
|
||||||
|
'adminPass': None,
|
||||||
|
'block_device_mapping_v2': None,
|
||||||
|
'config_drive': '',
|
||||||
|
'created': '2018-11-09T13:39:38Z',
|
||||||
|
'flavor': {'id': '17',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/17',
|
||||||
|
'rel': 'bookmark'}]},
|
||||||
|
'flavorRef': None,
|
||||||
|
'hostId': '84246cf2f8ac920628901e7a84a054b45f246f2d77f6df3f6c30cc43',
|
||||||
|
'id': '99c42e21-5099-4903-9121-063925aad299',
|
||||||
|
'image': {},
|
||||||
|
'imageRef': None,
|
||||||
|
'key_name': 'tellurium-key',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/servers/99c42e21-5099-4903-9121-063925aad299',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/servers/99c42e21-5099-4903-9121-063925aad299',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'metadata': {},
|
||||||
|
'name': 'Ubuntu 14.04',
|
||||||
|
'networks': None,
|
||||||
|
'os-extended-volumes:volumes_attached': [{'id': '8ca10346-fe4c-4e68-9a18-98df875d1ecc'}],
|
||||||
|
'personality': None,
|
||||||
|
'progress': 0,
|
||||||
|
'security_groups': [{'name': 'http'}, {'name': 'default'}],
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'updated': '2018-11-09T13:39:42Z',
|
||||||
|
'user_id': '7f71ea7b8abd41e5a1f303f4a1bc16b9'},
|
||||||
|
{'OS-DCF:diskConfig': 'MANUAL',
|
||||||
|
'OS-EXT-AZ:availability_zone': 'nova',
|
||||||
|
'OS-EXT-SRV-ATTR:hypervisor_hostname': None,
|
||||||
|
'OS-EXT-SRV-ATTR:instance_name': None,
|
||||||
|
'OS-EXT-SRV-ATTR:user_data': None,
|
||||||
|
'OS-EXT-STS:power_state': 1,
|
||||||
|
'OS-EXT-STS:task_state': None,
|
||||||
|
'OS-EXT-STS:vm_state': 'active',
|
||||||
|
'OS-SCH-HNT:scheduler_hints': None,
|
||||||
|
'OS-SRV-USG:launched_at': '2018-11-09T04:54:35.000000',
|
||||||
|
'OS-SRV-USG:terminated_at': None,
|
||||||
|
'accessIPv4': '',
|
||||||
|
'accessIPv6': '',
|
||||||
|
'addresses': {'tellurium_net': [{'OS-EXT-IPS-MAC:mac_addr': '02:3d:ec:f6:f8:25',
|
||||||
|
'OS-EXT-IPS:type': 'fixed',
|
||||||
|
'addr': '192.168.0.3',
|
||||||
|
'version': 4}]},
|
||||||
|
'adminPass': None,
|
||||||
|
'block_device_mapping_v2': None,
|
||||||
|
'config_drive': '',
|
||||||
|
'created': '2018-11-09T04:54:32Z',
|
||||||
|
'flavor': {'id': '42',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/42',
|
||||||
|
'rel': 'bookmark'}]},
|
||||||
|
'flavorRef': None,
|
||||||
|
'hostId': 'dd853263647ff603cfe0726dc78e34e0b9b2fc092bead501af233bcf',
|
||||||
|
'id': '2cf8db13-312a-4307-ba38-43b727ebcce6',
|
||||||
|
'image': {'id': '8254d703-e46f-4101-88ff-6f40bf7df51a',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/images/8254d703-e46f-4101-88ff-6f40bf7df51a',
|
||||||
|
'rel': 'bookmark'}]},
|
||||||
|
'imageRef': None,
|
||||||
|
'key_name': 'tellurium-key',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/servers/2cf8db13-312a-4307-ba38-43b727ebcce6',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/servers/2cf8db13-312a-4307-ba38-43b727ebcce6',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'metadata': {},
|
||||||
|
'name': 'tellurium_win_instance',
|
||||||
|
'networks': None,
|
||||||
|
'os-extended-volumes:volumes_attached': [],
|
||||||
|
'personality': None,
|
||||||
|
'progress': 0,
|
||||||
|
'security_groups': [{'name': 'default'}],
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'updated': '2018-11-09T04:55:58Z',
|
||||||
|
'user_id': '7f71ea7b8abd41e5a1f303f4a1bc16b9'},
|
||||||
|
{'OS-DCF:diskConfig': 'MANUAL',
|
||||||
|
'OS-EXT-AZ:availability_zone': 'nova',
|
||||||
|
'OS-EXT-SRV-ATTR:hypervisor_hostname': None,
|
||||||
|
'OS-EXT-SRV-ATTR:instance_name': None,
|
||||||
|
'OS-EXT-SRV-ATTR:user_data': None,
|
||||||
|
'OS-EXT-STS:power_state': 1,
|
||||||
|
'OS-EXT-STS:task_state': None,
|
||||||
|
'OS-EXT-STS:vm_state': 'active',
|
||||||
|
'OS-SCH-HNT:scheduler_hints': None,
|
||||||
|
'OS-SRV-USG:launched_at': '2018-11-09T04:57:15.000000',
|
||||||
|
'OS-SRV-USG:terminated_at': None,
|
||||||
|
'accessIPv4': '',
|
||||||
|
'accessIPv6': '',
|
||||||
|
'addresses': {'tellurium_net': [{'OS-EXT-IPS-MAC:mac_addr': '02:cb:33:6b:60:f2',
|
||||||
|
'OS-EXT-IPS:type': 'fixed',
|
||||||
|
'addr': '192.168.0.5',
|
||||||
|
'version': 4}]},
|
||||||
|
'adminPass': None,
|
||||||
|
'block_device_mapping_v2': None,
|
||||||
|
'config_drive': '',
|
||||||
|
'created': '2018-11-09T04:54:32Z',
|
||||||
|
'flavor': {'id': '42',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/42',
|
||||||
|
'rel': 'bookmark'}]},
|
||||||
|
'flavorRef': None,
|
||||||
|
'hostId': 'b357f8b6b7368a07bb2aed776c6579d132c90f7dcb2f28a2a34c98e8',
|
||||||
|
'id': 'b6316031-e629-48b8-aac5-3f1b21ffe0f3',
|
||||||
|
'image': {'id': '8254d703-e46f-4101-88ff-6f40bf7df51a',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/images/8254d703-e46f-4101-88ff-6f40bf7df51a',
|
||||||
|
'rel': 'bookmark'}]},
|
||||||
|
'imageRef': None,
|
||||||
|
'key_name': 'tellurium-key-phrase',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/servers/b6316031-e629-48b8-aac5-3f1b21ffe0f3',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/servers/b6316031-e629-48b8-aac5-3f1b21ffe0f3',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'metadata': {},
|
||||||
|
'name': 'tellurium_win_instance_ssh_pass',
|
||||||
|
'networks': None,
|
||||||
|
'os-extended-volumes:volumes_attached': [],
|
||||||
|
'personality': None,
|
||||||
|
'progress': 0,
|
||||||
|
'security_groups': [{'name': 'default'}],
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'updated': '2018-11-09T04:59:08Z',
|
||||||
|
'user_id': '7f71ea7b8abd41e5a1f303f4a1bc16b9'},
|
||||||
|
{'OS-DCF:diskConfig': 'MANUAL',
|
||||||
|
'OS-EXT-AZ:availability_zone': 'nova',
|
||||||
|
'OS-EXT-SRV-ATTR:hypervisor_hostname': None,
|
||||||
|
'OS-EXT-SRV-ATTR:instance_name': None,
|
||||||
|
'OS-EXT-SRV-ATTR:user_data': None,
|
||||||
|
'OS-EXT-STS:power_state': 1,
|
||||||
|
'OS-EXT-STS:task_state': None,
|
||||||
|
'OS-EXT-STS:vm_state': 'active',
|
||||||
|
'OS-SCH-HNT:scheduler_hints': None,
|
||||||
|
'OS-SRV-USG:launched_at': '2018-11-09T04:54:36.000000',
|
||||||
|
'OS-SRV-USG:terminated_at': None,
|
||||||
|
'accessIPv4': '',
|
||||||
|
'accessIPv6': '',
|
||||||
|
'addresses': {'tellurium_net': [{'OS-EXT-IPS-MAC:mac_addr': '02:20:6d:f7:16:da',
|
||||||
|
'OS-EXT-IPS:type': 'fixed',
|
||||||
|
'addr': '192.168.0.4',
|
||||||
|
'version': 4}]},
|
||||||
|
'adminPass': None,
|
||||||
|
'block_device_mapping_v2': None,
|
||||||
|
'config_drive': '',
|
||||||
|
'created': '2018-11-09T04:54:32Z',
|
||||||
|
'flavor': {'id': '16',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/flavors/16',
|
||||||
|
'rel': 'bookmark'}]},
|
||||||
|
'flavorRef': None,
|
||||||
|
'hostId': 'a5586828459ec792613bc24c0807801ce4341a562d47ff3203d41722',
|
||||||
|
'id': '4add78fa-93df-4550-aaf7-aba2239ba00a',
|
||||||
|
'image': {'id': 'dd7d4b21-79b8-42f0-8464-0d1a5274c638',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/images/dd7d4b21-79b8-42f0-8464-0d1a5274c638',
|
||||||
|
'rel': 'bookmark'}]},
|
||||||
|
'imageRef': None,
|
||||||
|
'key_name': 'tellurium-key',
|
||||||
|
'links': [{'href': 'https://compute.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/servers/4add78fa-93df-4550-aaf7-aba2239ba00a',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://compute.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/servers/4add78fa-93df-4550-aaf7-aba2239ba00a',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'metadata': {},
|
||||||
|
'name': 'tellurium_instance',
|
||||||
|
'networks': None,
|
||||||
|
'os-extended-volumes:volumes_attached': [],
|
||||||
|
'personality': None,
|
||||||
|
'progress': 0,
|
||||||
|
'security_groups': [{'name': 'default'}],
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'updated': '2018-11-09T05:22:45Z',
|
||||||
|
'user_id': '7f71ea7b8abd41e5a1f303f4a1bc16b9'}]
|
49
flameclient/tests/fixtures/openstackcloud/subnets.py
vendored
Normal file
49
flameclient/tests/fixtures/openstackcloud/subnets.py
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'network.subnets'
|
||||||
|
|
||||||
|
FIXTURES = [{'allocation_pools': [{'end': '192.168.0.254', 'start': '192.168.0.2'}],
|
||||||
|
'cidr': '192.168.0.0/24',
|
||||||
|
'created_at': None,
|
||||||
|
'description': None,
|
||||||
|
'dns_nameservers': ['8.8.8.8'],
|
||||||
|
'enable_dhcp': True,
|
||||||
|
'gateway_ip': '192.168.0.1',
|
||||||
|
'host_routes': [],
|
||||||
|
'id': '541f0782-587f-428b-bd79-ca227a66973b',
|
||||||
|
'ip_version': 4,
|
||||||
|
'ipv6_address_mode': None,
|
||||||
|
'ipv6_ra_mode': None,
|
||||||
|
'name': 'tellurium_net_subnet',
|
||||||
|
'network_id': 'f054013d-7052-4708-9c72-2948a329fac3',
|
||||||
|
'revision_number': None,
|
||||||
|
'segment_id': None,
|
||||||
|
'service_types': None,
|
||||||
|
'subnetpool_id': None,
|
||||||
|
'tags': [],
|
||||||
|
'tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'updated_at': None,
|
||||||
|
'use_default_subnetpool': None}]
|
102
flameclient/tests/fixtures/openstackcloud/volumes.py
vendored
Normal file
102
flameclient/tests/fixtures/openstackcloud/volumes.py
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
NAME = 'volume.volumes'
|
||||||
|
|
||||||
|
FIXTURES = [{'attachments': [{'attached_at': '2018-11-09T13:39:41.000000',
|
||||||
|
'attachment_id': '7edd34f8-5c1b-4c46-afac-916db0e10726',
|
||||||
|
'device': '/dev/vda',
|
||||||
|
'host_name': None,
|
||||||
|
'id': '8ca10346-fe4c-4e68-9a18-98df875d1ecc',
|
||||||
|
'server_id': '99c42e21-5099-4903-9121-063925aad299',
|
||||||
|
'volume_id': '8ca10346-fe4c-4e68-9a18-98df875d1ecc'}],
|
||||||
|
'availability_zone': 'prd1',
|
||||||
|
'bootable': True,
|
||||||
|
'consistencygroup_id': None,
|
||||||
|
'created_at': '2018-11-09T13:34:08.000000',
|
||||||
|
'description': '',
|
||||||
|
'encrypted': False,
|
||||||
|
'id': '8ca10346-fe4c-4e68-9a18-98df875d1ecc',
|
||||||
|
'imageRef': None,
|
||||||
|
'links': [{'href': 'https://volume.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/volumes/8ca10346-fe4c-4e68-9a18-98df875d1ecc',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://volume.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/volumes/8ca10346-fe4c-4e68-9a18-98df875d1ecc',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'metadata': {'attached_mode': 'rw', 'readonly': 'False'},
|
||||||
|
'name': 'Ubuntu 14.04',
|
||||||
|
'os-vol-host-attr:host': None,
|
||||||
|
'os-vol-mig-status-attr:migstat': None,
|
||||||
|
'os-vol-mig-status-attr:name_id': None,
|
||||||
|
'os-vol-tenant-attr:tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'os-volume-replication:driver_data': None,
|
||||||
|
'os-volume-replication:extended_status': None,
|
||||||
|
'replication_status': 'disabled',
|
||||||
|
'size': 20,
|
||||||
|
'snapshot_id': None,
|
||||||
|
'source_volid': None,
|
||||||
|
'status': 'in-use',
|
||||||
|
'volume_image_metadata': {'checksum': '8ec802fe753dfe8e226645a2e0106bf7',
|
||||||
|
'container_format': 'bare',
|
||||||
|
'cw_cat': 'open_source',
|
||||||
|
'cw_logo': 'lin-ubuntu.png',
|
||||||
|
'cw_origin': 'Cloudwatt',
|
||||||
|
'cw_os': 'Ubuntu',
|
||||||
|
'disk_format': 'qcow2',
|
||||||
|
'hw_cpu_max_sockets': '1',
|
||||||
|
'hw_rng_model': 'virtio',
|
||||||
|
'image_id': '70a9c910-dd99-4065-bce9-11e89bc479fe',
|
||||||
|
'image_name': 'Ubuntu 14.04',
|
||||||
|
'min_disk': '20',
|
||||||
|
'min_ram': '0',
|
||||||
|
'size': '1009057792'},
|
||||||
|
'volume_type': 'standard'},
|
||||||
|
{'attachments': [],
|
||||||
|
'availability_zone': 'prd1',
|
||||||
|
'bootable': False,
|
||||||
|
'consistencygroup_id': None,
|
||||||
|
'created_at': '2018-11-09T04:54:29.000000',
|
||||||
|
'description': None,
|
||||||
|
'encrypted': False,
|
||||||
|
'id': '34ce951a-f2d9-4bdd-904d-9f70269c680b',
|
||||||
|
'imageRef': None,
|
||||||
|
'links': [{'href': 'https://volume.fr1.cloudwatt.com/v2/9824a7403a1b411d8d207d26218597ce/volumes/34ce951a-f2d9-4bdd-904d-9f70269c680b',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'https://volume.fr1.cloudwatt.com/9824a7403a1b411d8d207d26218597ce/volumes/34ce951a-f2d9-4bdd-904d-9f70269c680b',
|
||||||
|
'rel': 'bookmark'}],
|
||||||
|
'metadata': {},
|
||||||
|
'name': 'tellurium_volume',
|
||||||
|
'os-vol-host-attr:host': None,
|
||||||
|
'os-vol-mig-status-attr:migstat': None,
|
||||||
|
'os-vol-mig-status-attr:name_id': None,
|
||||||
|
'os-vol-tenant-attr:tenant_id': '9824a7403a1b411d8d207d26218597ce',
|
||||||
|
'os-volume-replication:driver_data': None,
|
||||||
|
'os-volume-replication:extended_status': None,
|
||||||
|
'replication_status': 'disabled',
|
||||||
|
'size': 5,
|
||||||
|
'snapshot_id': None,
|
||||||
|
'source_volid': None,
|
||||||
|
'status': 'available',
|
||||||
|
'volume_image_metadata': {},
|
||||||
|
'volume_type': 'standard'}]
|
0
flameclient/tests/fixtures/results/__init__.py
vendored
Normal file
0
flameclient/tests/fixtures/results/__init__.py
vendored
Normal file
225
flameclient/tests/fixtures/results/flame.yaml
vendored
Normal file
225
flameclient/tests/fixtures/results/flame.yaml
vendored
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
description: Generated template
|
||||||
|
heat_template_version: 2013-05-23
|
||||||
|
parameters:
|
||||||
|
external_network_for_floating_ip_0:
|
||||||
|
default: 6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
description: Network to allocate floating IP from
|
||||||
|
type: string
|
||||||
|
router_0_external_network:
|
||||||
|
default: 6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
description: Router external network
|
||||||
|
type: string
|
||||||
|
server_0_flavor:
|
||||||
|
default: '17'
|
||||||
|
description: Flavor to use for server server_0
|
||||||
|
type: string
|
||||||
|
server_1_flavor:
|
||||||
|
default: '42'
|
||||||
|
description: Flavor to use for server server_1
|
||||||
|
type: string
|
||||||
|
server_1_image:
|
||||||
|
default: 8254d703-e46f-4101-88ff-6f40bf7df51a
|
||||||
|
description: Image to use for server server_1
|
||||||
|
type: string
|
||||||
|
server_2_flavor:
|
||||||
|
default: '42'
|
||||||
|
description: Flavor to use for server server_2
|
||||||
|
type: string
|
||||||
|
server_2_image:
|
||||||
|
default: 8254d703-e46f-4101-88ff-6f40bf7df51a
|
||||||
|
description: Image to use for server server_2
|
||||||
|
type: string
|
||||||
|
server_3_flavor:
|
||||||
|
default: '16'
|
||||||
|
description: Flavor to use for server server_3
|
||||||
|
type: string
|
||||||
|
server_3_image:
|
||||||
|
default: dd7d4b21-79b8-42f0-8464-0d1a5274c638
|
||||||
|
description: Image to use for server server_3
|
||||||
|
type: string
|
||||||
|
volume_0_image:
|
||||||
|
default: 70a9c910-dd99-4065-bce9-11e89bc479fe
|
||||||
|
description: Image to create volume volume_0 from
|
||||||
|
type: string
|
||||||
|
volume_0_volume_type:
|
||||||
|
default: standard
|
||||||
|
description: Volume type for volume volume_0
|
||||||
|
type: string
|
||||||
|
volume_1_volume_type:
|
||||||
|
default: standard
|
||||||
|
description: Volume type for volume volume_1
|
||||||
|
type: string
|
||||||
|
resources:
|
||||||
|
floating_ip_0:
|
||||||
|
properties:
|
||||||
|
floating_network_id:
|
||||||
|
get_param: external_network_for_floating_ip_0
|
||||||
|
type: OS::Neutron::FloatingIP
|
||||||
|
keypair_0:
|
||||||
|
properties:
|
||||||
|
name: tellurium-key
|
||||||
|
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwp5kVZ+3baPZllNXZDG2mivd5nJ5wWY6Jj/WV6NlO6cUiaH5om6itU3lyJxtAbLgbbvY2FjMg1PI2JI3EHx0OSPEbDdeNsQGi31qyuiB1S5p6TreI0Dfy0tywJ9G2CURjkuJnC8SvnMfVYLMFBvx7p8RzxSdDm/zrmc4KY3ktdfYQDNtEiH2jucUUiY0ipVkDNhhv03+5C9cnpaIcVDBkddE/KEME8NIIh7s6aYCXJEWJx85nOVVRD5qK7ouV6FcGVn6zqWRD3jn0iSxcFwiKx7p6M77PmJAY4gBIpWQmutok6T4ZrXxa7jE4dybwo5e8dyvGyc7WWGqXcmcinUWr
|
||||||
|
Generated-by-Nova
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
keypair_1:
|
||||||
|
properties:
|
||||||
|
name: tellurium-key-phrase
|
||||||
|
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaYaTC6KCC2GURFMpRQiRq8Og10PcBbVnrQqluzi2E5vAqTHAegzivmGB8h2xrjXUfbKV2bE8kz2ZE66sq1yLO/jZ+rkOA+zLnOxNwkk3gQq57b26ZegPL2tTgottJTPGyPz6v2+LLtDf/+xTJMjkPKcMWylu12Js0XKVkdY35fwN7fRvA4xghtGu1GcmS2XFDMmeLDrG1KNPbBLj5cGoD723Ho7ZhAjLThoY/xMN2OYsSNzrg3S00QngZMzQvJf0ETrB3GtITk5FUs54qMRfiyUC72lw0gLTIJK8rs7fX/yeO+467afRt2xwHN50rEWJPeTVYWdlH/msh7NQ3LZ8/
|
||||||
|
root@9b638ff21113
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
network_1:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
name: tellurium_net
|
||||||
|
shared: false
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
router_0:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
name: tellurium_router
|
||||||
|
type: OS::Neutron::Router
|
||||||
|
router_0_gateway:
|
||||||
|
properties:
|
||||||
|
network_id:
|
||||||
|
get_param: router_0_external_network
|
||||||
|
router_id:
|
||||||
|
get_resource: router_0
|
||||||
|
type: OS::Neutron::RouterGateway
|
||||||
|
router_0_interface_3:
|
||||||
|
properties:
|
||||||
|
router_id:
|
||||||
|
get_resource: router_0
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
type: OS::Neutron::RouterInterface
|
||||||
|
security_group_0:
|
||||||
|
properties:
|
||||||
|
name: _default
|
||||||
|
rules:
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_mode: remote_group_id
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv6
|
||||||
|
remote_mode: remote_group_id
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv6
|
||||||
|
remote_ip_prefix: ::/0
|
||||||
|
type: OS::Neutron::SecurityGroup
|
||||||
|
security_group_1:
|
||||||
|
properties:
|
||||||
|
description: ''
|
||||||
|
name: http
|
||||||
|
rules:
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv6
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv4
|
||||||
|
port_range_max: 80
|
||||||
|
port_range_min: 80
|
||||||
|
protocol: tcp
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
type: OS::Neutron::SecurityGroup
|
||||||
|
server_0:
|
||||||
|
properties:
|
||||||
|
block_device_mapping_v2:
|
||||||
|
- device_name: /dev/vda
|
||||||
|
volume_id:
|
||||||
|
get_resource: volume_0
|
||||||
|
flavor:
|
||||||
|
get_param: server_0_flavor
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: Ubuntu 14.04
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_1
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_1:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_1_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_1_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: tellurium_win_instance
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_2:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_2_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_2_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_1
|
||||||
|
name: tellurium_win_instance_ssh_pass
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_3:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_3_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_3_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: tellurium_instance
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Nova::Server
|
||||||
|
subnet_0:
|
||||||
|
properties:
|
||||||
|
allocation_pools:
|
||||||
|
- end: 192.168.0.254
|
||||||
|
start: 192.168.0.2
|
||||||
|
cidr: 192.168.0.0/24
|
||||||
|
dns_nameservers:
|
||||||
|
- 8.8.8.8
|
||||||
|
enable_dhcp: true
|
||||||
|
host_routes: []
|
||||||
|
ip_version: 4
|
||||||
|
name: tellurium_net_subnet
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
volume_0:
|
||||||
|
properties:
|
||||||
|
image:
|
||||||
|
get_param: volume_0_image
|
||||||
|
metadata:
|
||||||
|
attached_mode: rw
|
||||||
|
readonly: 'False'
|
||||||
|
name: Ubuntu 14.04
|
||||||
|
size: 20
|
||||||
|
volume_type:
|
||||||
|
get_param: volume_0_volume_type
|
||||||
|
type: OS::Cinder::Volume
|
||||||
|
volume_1:
|
||||||
|
properties:
|
||||||
|
name: tellurium_volume
|
||||||
|
size: 5
|
||||||
|
volume_type:
|
||||||
|
get_param: volume_1_volume_type
|
||||||
|
type: OS::Cinder::Volume
|
351
flameclient/tests/fixtures/results/flame_adoption_data.yaml
vendored
Normal file
351
flameclient/tests/fixtures/results/flame_adoption_data.yaml
vendored
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
action: CREATE
|
||||||
|
environment:
|
||||||
|
parameter_defaults: {}
|
||||||
|
parameters: {}
|
||||||
|
resources:
|
||||||
|
floating_ip_0:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: floating_ip_0
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: e6f50641-6c7e-468c-9623-1fd5ee2c1ebc
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Neutron::FloatingIP
|
||||||
|
keypair_0:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: keypair_0
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: tellurium-key
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
keypair_1:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: keypair_1
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: tellurium-key-phrase
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
network_1:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: network_1
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: f054013d-7052-4708-9c72-2948a329fac3
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
router_0:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: router_0
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: ebc6dd0c-a276-4368-8084-bd37c587cc24
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Neutron::Router
|
||||||
|
router_0_gateway:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: router_0_gateway
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: ebc6dd0c-a276-4368-8084-bd37c587cc24:6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Neutron::RouterGateway
|
||||||
|
router_0_interface_3:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: router_0_interface_3
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: ebc6dd0c-a276-4368-8084-bd37c587cc24:subnet_id=541f0782-587f-428b-bd79-ca227a66973b
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Neutron::RouterInterface
|
||||||
|
security_group_1:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: security_group_1
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: 156799a3-565e-48b3-938c-f95f09093c66
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Neutron::SecurityGroup
|
||||||
|
server_0:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: server_0
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: 99c42e21-5099-4903-9121-063925aad299
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_1:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: server_1
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: 2cf8db13-312a-4307-ba38-43b727ebcce6
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_2:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: server_2
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: b6316031-e629-48b8-aac5-3f1b21ffe0f3
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_3:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: server_3
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: 4add78fa-93df-4550-aaf7-aba2239ba00a
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Nova::Server
|
||||||
|
subnet_0:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: subnet_0
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: 541f0782-587f-428b-bd79-ca227a66973b
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
volume_0:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: volume_0
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: 8ca10346-fe4c-4e68-9a18-98df875d1ecc
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Cinder::Volume
|
||||||
|
volume_1:
|
||||||
|
action: CREATE
|
||||||
|
metadata: {}
|
||||||
|
name: volume_1
|
||||||
|
resource_data: {}
|
||||||
|
resource_id: 34ce951a-f2d9-4bdd-904d-9f70269c680b
|
||||||
|
status: COMPLETE
|
||||||
|
type: OS::Cinder::Volume
|
||||||
|
status: COMPLETE
|
||||||
|
template:
|
||||||
|
description: Generated template
|
||||||
|
heat_template_version: 2013-05-23
|
||||||
|
parameters:
|
||||||
|
external_network_for_floating_ip_0:
|
||||||
|
default: 6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
description: Network to allocate floating IP from
|
||||||
|
type: string
|
||||||
|
router_0_external_network:
|
||||||
|
default: 6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
description: Router external network
|
||||||
|
type: string
|
||||||
|
server_0_default_security_group:
|
||||||
|
default: 9ffd2654-7ca6-48ae-852d-6503d5ce4a60
|
||||||
|
description: Default security group for server Ubuntu 14.04
|
||||||
|
type: string
|
||||||
|
server_0_flavor:
|
||||||
|
default: '17'
|
||||||
|
description: Flavor to use for server server_0
|
||||||
|
type: string
|
||||||
|
server_1_default_security_group:
|
||||||
|
default: 9ffd2654-7ca6-48ae-852d-6503d5ce4a60
|
||||||
|
description: Default security group for server tellurium_win_instance
|
||||||
|
type: string
|
||||||
|
server_1_flavor:
|
||||||
|
default: '42'
|
||||||
|
description: Flavor to use for server server_1
|
||||||
|
type: string
|
||||||
|
server_1_image:
|
||||||
|
default: 8254d703-e46f-4101-88ff-6f40bf7df51a
|
||||||
|
description: Image to use for server server_1
|
||||||
|
type: string
|
||||||
|
server_2_default_security_group:
|
||||||
|
default: 9ffd2654-7ca6-48ae-852d-6503d5ce4a60
|
||||||
|
description: Default security group for server tellurium_win_instance_ssh_pass
|
||||||
|
type: string
|
||||||
|
server_2_flavor:
|
||||||
|
default: '42'
|
||||||
|
description: Flavor to use for server server_2
|
||||||
|
type: string
|
||||||
|
server_2_image:
|
||||||
|
default: 8254d703-e46f-4101-88ff-6f40bf7df51a
|
||||||
|
description: Image to use for server server_2
|
||||||
|
type: string
|
||||||
|
server_3_default_security_group:
|
||||||
|
default: 9ffd2654-7ca6-48ae-852d-6503d5ce4a60
|
||||||
|
description: Default security group for server tellurium_instance
|
||||||
|
type: string
|
||||||
|
server_3_flavor:
|
||||||
|
default: '16'
|
||||||
|
description: Flavor to use for server server_3
|
||||||
|
type: string
|
||||||
|
server_3_image:
|
||||||
|
default: dd7d4b21-79b8-42f0-8464-0d1a5274c638
|
||||||
|
description: Image to use for server server_3
|
||||||
|
type: string
|
||||||
|
volume_0_image:
|
||||||
|
default: 70a9c910-dd99-4065-bce9-11e89bc479fe
|
||||||
|
description: Image to create volume volume_0 from
|
||||||
|
type: string
|
||||||
|
volume_0_volume_type:
|
||||||
|
default: standard
|
||||||
|
description: Volume type for volume volume_0
|
||||||
|
type: string
|
||||||
|
volume_1_volume_type:
|
||||||
|
default: standard
|
||||||
|
description: Volume type for volume volume_1
|
||||||
|
type: string
|
||||||
|
resources:
|
||||||
|
floating_ip_0:
|
||||||
|
properties:
|
||||||
|
floating_network_id:
|
||||||
|
get_param: external_network_for_floating_ip_0
|
||||||
|
type: OS::Neutron::FloatingIP
|
||||||
|
keypair_0:
|
||||||
|
properties:
|
||||||
|
name: tellurium-key
|
||||||
|
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwp5kVZ+3baPZllNXZDG2mivd5nJ5wWY6Jj/WV6NlO6cUiaH5om6itU3lyJxtAbLgbbvY2FjMg1PI2JI3EHx0OSPEbDdeNsQGi31qyuiB1S5p6TreI0Dfy0tywJ9G2CURjkuJnC8SvnMfVYLMFBvx7p8RzxSdDm/zrmc4KY3ktdfYQDNtEiH2jucUUiY0ipVkDNhhv03+5C9cnpaIcVDBkddE/KEME8NIIh7s6aYCXJEWJx85nOVVRD5qK7ouV6FcGVn6zqWRD3jn0iSxcFwiKx7p6M77PmJAY4gBIpWQmutok6T4ZrXxa7jE4dybwo5e8dyvGyc7WWGqXcmcinUWr
|
||||||
|
Generated-by-Nova
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
keypair_1:
|
||||||
|
properties:
|
||||||
|
name: tellurium-key-phrase
|
||||||
|
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaYaTC6KCC2GURFMpRQiRq8Og10PcBbVnrQqluzi2E5vAqTHAegzivmGB8h2xrjXUfbKV2bE8kz2ZE66sq1yLO/jZ+rkOA+zLnOxNwkk3gQq57b26ZegPL2tTgottJTPGyPz6v2+LLtDf/+xTJMjkPKcMWylu12Js0XKVkdY35fwN7fRvA4xghtGu1GcmS2XFDMmeLDrG1KNPbBLj5cGoD723Ho7ZhAjLThoY/xMN2OYsSNzrg3S00QngZMzQvJf0ETrB3GtITk5FUs54qMRfiyUC72lw0gLTIJK8rs7fX/yeO+467afRt2xwHN50rEWJPeTVYWdlH/msh7NQ3LZ8/
|
||||||
|
root@9b638ff21113
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
network_1:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
name: tellurium_net
|
||||||
|
shared: false
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
router_0:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
name: tellurium_router
|
||||||
|
type: OS::Neutron::Router
|
||||||
|
router_0_gateway:
|
||||||
|
properties:
|
||||||
|
network_id:
|
||||||
|
get_param: router_0_external_network
|
||||||
|
router_id:
|
||||||
|
get_resource: router_0
|
||||||
|
type: OS::Neutron::RouterGateway
|
||||||
|
router_0_interface_3:
|
||||||
|
properties:
|
||||||
|
router_id:
|
||||||
|
get_resource: router_0
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
type: OS::Neutron::RouterInterface
|
||||||
|
security_group_1:
|
||||||
|
properties:
|
||||||
|
description: ''
|
||||||
|
name: http
|
||||||
|
rules:
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv6
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv4
|
||||||
|
port_range_max: 80
|
||||||
|
port_range_min: 80
|
||||||
|
protocol: tcp
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
type: OS::Neutron::SecurityGroup
|
||||||
|
server_0:
|
||||||
|
properties:
|
||||||
|
block_device_mapping_v2:
|
||||||
|
- device_name: /dev/vda
|
||||||
|
volume_id:
|
||||||
|
get_resource: volume_0
|
||||||
|
flavor:
|
||||||
|
get_param: server_0_flavor
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: Ubuntu 14.04
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_1
|
||||||
|
- get_param: server_0_default_security_group
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_1:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_1_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_1_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: tellurium_win_instance
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_param: server_1_default_security_group
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_2:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_2_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_2_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_1
|
||||||
|
name: tellurium_win_instance_ssh_pass
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_param: server_2_default_security_group
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_3:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_3_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_3_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: tellurium_instance
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_param: server_3_default_security_group
|
||||||
|
type: OS::Nova::Server
|
||||||
|
subnet_0:
|
||||||
|
properties:
|
||||||
|
allocation_pools:
|
||||||
|
- end: 192.168.0.254
|
||||||
|
start: 192.168.0.2
|
||||||
|
cidr: 192.168.0.0/24
|
||||||
|
dns_nameservers:
|
||||||
|
- 8.8.8.8
|
||||||
|
enable_dhcp: true
|
||||||
|
host_routes: []
|
||||||
|
ip_version: 4
|
||||||
|
name: tellurium_net_subnet
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
volume_0:
|
||||||
|
properties:
|
||||||
|
image:
|
||||||
|
get_param: volume_0_image
|
||||||
|
metadata:
|
||||||
|
attached_mode: rw
|
||||||
|
readonly: 'False'
|
||||||
|
name: Ubuntu 14.04
|
||||||
|
size: 20
|
||||||
|
volume_type:
|
||||||
|
get_param: volume_0_volume_type
|
||||||
|
type: OS::Cinder::Volume
|
||||||
|
volume_1:
|
||||||
|
properties:
|
||||||
|
name: tellurium_volume
|
||||||
|
size: 5
|
||||||
|
volume_type:
|
||||||
|
get_param: volume_1_volume_type
|
||||||
|
type: OS::Cinder::Volume
|
237
flameclient/tests/fixtures/results/flame_constraints.yaml
vendored
Normal file
237
flameclient/tests/fixtures/results/flame_constraints.yaml
vendored
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
description: Generated template
|
||||||
|
heat_template_version: 2013-05-23
|
||||||
|
parameters:
|
||||||
|
external_network_for_floating_ip_0:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: neutron.network
|
||||||
|
default: 6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
description: Network to allocate floating IP from
|
||||||
|
type: string
|
||||||
|
router_0_external_network:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: neutron.network
|
||||||
|
default: 6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
description: Router external network
|
||||||
|
type: string
|
||||||
|
server_0_flavor:
|
||||||
|
default: '17'
|
||||||
|
description: Flavor to use for server server_0
|
||||||
|
type: string
|
||||||
|
server_1_flavor:
|
||||||
|
default: '42'
|
||||||
|
description: Flavor to use for server server_1
|
||||||
|
type: string
|
||||||
|
server_1_image:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: glance.image
|
||||||
|
default: 8254d703-e46f-4101-88ff-6f40bf7df51a
|
||||||
|
description: Image to use for server server_1
|
||||||
|
type: string
|
||||||
|
server_2_flavor:
|
||||||
|
default: '42'
|
||||||
|
description: Flavor to use for server server_2
|
||||||
|
type: string
|
||||||
|
server_2_image:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: glance.image
|
||||||
|
default: 8254d703-e46f-4101-88ff-6f40bf7df51a
|
||||||
|
description: Image to use for server server_2
|
||||||
|
type: string
|
||||||
|
server_3_flavor:
|
||||||
|
default: '16'
|
||||||
|
description: Flavor to use for server server_3
|
||||||
|
type: string
|
||||||
|
server_3_image:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: glance.image
|
||||||
|
default: dd7d4b21-79b8-42f0-8464-0d1a5274c638
|
||||||
|
description: Image to use for server server_3
|
||||||
|
type: string
|
||||||
|
volume_0_image:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: glance.image
|
||||||
|
default: 70a9c910-dd99-4065-bce9-11e89bc479fe
|
||||||
|
description: Image to create volume volume_0 from
|
||||||
|
type: string
|
||||||
|
volume_0_volume_type:
|
||||||
|
default: standard
|
||||||
|
description: Volume type for volume volume_0
|
||||||
|
type: string
|
||||||
|
volume_1_volume_type:
|
||||||
|
default: standard
|
||||||
|
description: Volume type for volume volume_1
|
||||||
|
type: string
|
||||||
|
resources:
|
||||||
|
floating_ip_0:
|
||||||
|
properties:
|
||||||
|
floating_network_id:
|
||||||
|
get_param: external_network_for_floating_ip_0
|
||||||
|
type: OS::Neutron::FloatingIP
|
||||||
|
keypair_0:
|
||||||
|
properties:
|
||||||
|
name: tellurium-key
|
||||||
|
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwp5kVZ+3baPZllNXZDG2mivd5nJ5wWY6Jj/WV6NlO6cUiaH5om6itU3lyJxtAbLgbbvY2FjMg1PI2JI3EHx0OSPEbDdeNsQGi31qyuiB1S5p6TreI0Dfy0tywJ9G2CURjkuJnC8SvnMfVYLMFBvx7p8RzxSdDm/zrmc4KY3ktdfYQDNtEiH2jucUUiY0ipVkDNhhv03+5C9cnpaIcVDBkddE/KEME8NIIh7s6aYCXJEWJx85nOVVRD5qK7ouV6FcGVn6zqWRD3jn0iSxcFwiKx7p6M77PmJAY4gBIpWQmutok6T4ZrXxa7jE4dybwo5e8dyvGyc7WWGqXcmcinUWr
|
||||||
|
Generated-by-Nova
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
keypair_1:
|
||||||
|
properties:
|
||||||
|
name: tellurium-key-phrase
|
||||||
|
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaYaTC6KCC2GURFMpRQiRq8Og10PcBbVnrQqluzi2E5vAqTHAegzivmGB8h2xrjXUfbKV2bE8kz2ZE66sq1yLO/jZ+rkOA+zLnOxNwkk3gQq57b26ZegPL2tTgottJTPGyPz6v2+LLtDf/+xTJMjkPKcMWylu12Js0XKVkdY35fwN7fRvA4xghtGu1GcmS2XFDMmeLDrG1KNPbBLj5cGoD723Ho7ZhAjLThoY/xMN2OYsSNzrg3S00QngZMzQvJf0ETrB3GtITk5FUs54qMRfiyUC72lw0gLTIJK8rs7fX/yeO+467afRt2xwHN50rEWJPeTVYWdlH/msh7NQ3LZ8/
|
||||||
|
root@9b638ff21113
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
network_1:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
name: tellurium_net
|
||||||
|
shared: false
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
router_0:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
name: tellurium_router
|
||||||
|
type: OS::Neutron::Router
|
||||||
|
router_0_gateway:
|
||||||
|
properties:
|
||||||
|
network_id:
|
||||||
|
get_param: router_0_external_network
|
||||||
|
router_id:
|
||||||
|
get_resource: router_0
|
||||||
|
type: OS::Neutron::RouterGateway
|
||||||
|
router_0_interface_3:
|
||||||
|
properties:
|
||||||
|
router_id:
|
||||||
|
get_resource: router_0
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
type: OS::Neutron::RouterInterface
|
||||||
|
security_group_0:
|
||||||
|
properties:
|
||||||
|
name: _default
|
||||||
|
rules:
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_mode: remote_group_id
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv6
|
||||||
|
remote_mode: remote_group_id
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv6
|
||||||
|
remote_ip_prefix: ::/0
|
||||||
|
type: OS::Neutron::SecurityGroup
|
||||||
|
security_group_1:
|
||||||
|
properties:
|
||||||
|
description: ''
|
||||||
|
name: http
|
||||||
|
rules:
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv6
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv4
|
||||||
|
port_range_max: 80
|
||||||
|
port_range_min: 80
|
||||||
|
protocol: tcp
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
type: OS::Neutron::SecurityGroup
|
||||||
|
server_0:
|
||||||
|
properties:
|
||||||
|
block_device_mapping_v2:
|
||||||
|
- device_name: /dev/vda
|
||||||
|
volume_id:
|
||||||
|
get_resource: volume_0
|
||||||
|
flavor:
|
||||||
|
get_param: server_0_flavor
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: Ubuntu 14.04
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_1
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_1:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_1_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_1_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: tellurium_win_instance
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_2:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_2_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_2_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_1
|
||||||
|
name: tellurium_win_instance_ssh_pass
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_3:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_3_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_3_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: tellurium_instance
|
||||||
|
networks:
|
||||||
|
- network:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Nova::Server
|
||||||
|
subnet_0:
|
||||||
|
properties:
|
||||||
|
allocation_pools:
|
||||||
|
- end: 192.168.0.254
|
||||||
|
start: 192.168.0.2
|
||||||
|
cidr: 192.168.0.0/24
|
||||||
|
dns_nameservers:
|
||||||
|
- 8.8.8.8
|
||||||
|
enable_dhcp: true
|
||||||
|
host_routes: []
|
||||||
|
ip_version: 4
|
||||||
|
name: tellurium_net_subnet
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
volume_0:
|
||||||
|
properties:
|
||||||
|
image:
|
||||||
|
get_param: volume_0_image
|
||||||
|
metadata:
|
||||||
|
attached_mode: rw
|
||||||
|
readonly: 'False'
|
||||||
|
name: Ubuntu 14.04
|
||||||
|
size: 20
|
||||||
|
volume_type:
|
||||||
|
get_param: volume_0_volume_type
|
||||||
|
type: OS::Cinder::Volume
|
||||||
|
volume_1:
|
||||||
|
properties:
|
||||||
|
name: tellurium_volume
|
||||||
|
size: 5
|
||||||
|
volume_type:
|
||||||
|
get_param: volume_1_volume_type
|
||||||
|
type: OS::Cinder::Volume
|
289
flameclient/tests/fixtures/results/flame_constraints_extract_ports.yaml
vendored
Normal file
289
flameclient/tests/fixtures/results/flame_constraints_extract_ports.yaml
vendored
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
description: Generated template
|
||||||
|
heat_template_version: 2013-05-23
|
||||||
|
parameters:
|
||||||
|
external_network_for_floating_ip_0:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: neutron.network
|
||||||
|
default: 6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
description: Network to allocate floating IP from
|
||||||
|
type: string
|
||||||
|
router_0_external_network:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: neutron.network
|
||||||
|
default: 6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
description: Router external network
|
||||||
|
type: string
|
||||||
|
server_0_flavor:
|
||||||
|
default: '17'
|
||||||
|
description: Flavor to use for server server_0
|
||||||
|
type: string
|
||||||
|
server_1_flavor:
|
||||||
|
default: '42'
|
||||||
|
description: Flavor to use for server server_1
|
||||||
|
type: string
|
||||||
|
server_1_image:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: glance.image
|
||||||
|
default: 8254d703-e46f-4101-88ff-6f40bf7df51a
|
||||||
|
description: Image to use for server server_1
|
||||||
|
type: string
|
||||||
|
server_2_flavor:
|
||||||
|
default: '42'
|
||||||
|
description: Flavor to use for server server_2
|
||||||
|
type: string
|
||||||
|
server_2_image:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: glance.image
|
||||||
|
default: 8254d703-e46f-4101-88ff-6f40bf7df51a
|
||||||
|
description: Image to use for server server_2
|
||||||
|
type: string
|
||||||
|
server_3_flavor:
|
||||||
|
default: '16'
|
||||||
|
description: Flavor to use for server server_3
|
||||||
|
type: string
|
||||||
|
server_3_image:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: glance.image
|
||||||
|
default: dd7d4b21-79b8-42f0-8464-0d1a5274c638
|
||||||
|
description: Image to use for server server_3
|
||||||
|
type: string
|
||||||
|
volume_0_image:
|
||||||
|
constraints:
|
||||||
|
- custom_constraint: glance.image
|
||||||
|
default: 70a9c910-dd99-4065-bce9-11e89bc479fe
|
||||||
|
description: Image to create volume volume_0 from
|
||||||
|
type: string
|
||||||
|
volume_0_volume_type:
|
||||||
|
default: standard
|
||||||
|
description: Volume type for volume volume_0
|
||||||
|
type: string
|
||||||
|
volume_1_volume_type:
|
||||||
|
default: standard
|
||||||
|
description: Volume type for volume volume_1
|
||||||
|
type: string
|
||||||
|
resources:
|
||||||
|
floating_ip_0:
|
||||||
|
properties:
|
||||||
|
floating_network_id:
|
||||||
|
get_param: external_network_for_floating_ip_0
|
||||||
|
type: OS::Neutron::FloatingIP
|
||||||
|
keypair_0:
|
||||||
|
properties:
|
||||||
|
name: tellurium-key
|
||||||
|
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwp5kVZ+3baPZllNXZDG2mivd5nJ5wWY6Jj/WV6NlO6cUiaH5om6itU3lyJxtAbLgbbvY2FjMg1PI2JI3EHx0OSPEbDdeNsQGi31qyuiB1S5p6TreI0Dfy0tywJ9G2CURjkuJnC8SvnMfVYLMFBvx7p8RzxSdDm/zrmc4KY3ktdfYQDNtEiH2jucUUiY0ipVkDNhhv03+5C9cnpaIcVDBkddE/KEME8NIIh7s6aYCXJEWJx85nOVVRD5qK7ouV6FcGVn6zqWRD3jn0iSxcFwiKx7p6M77PmJAY4gBIpWQmutok6T4ZrXxa7jE4dybwo5e8dyvGyc7WWGqXcmcinUWr
|
||||||
|
Generated-by-Nova
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
keypair_1:
|
||||||
|
properties:
|
||||||
|
name: tellurium-key-phrase
|
||||||
|
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaYaTC6KCC2GURFMpRQiRq8Og10PcBbVnrQqluzi2E5vAqTHAegzivmGB8h2xrjXUfbKV2bE8kz2ZE66sq1yLO/jZ+rkOA+zLnOxNwkk3gQq57b26ZegPL2tTgottJTPGyPz6v2+LLtDf/+xTJMjkPKcMWylu12Js0XKVkdY35fwN7fRvA4xghtGu1GcmS2XFDMmeLDrG1KNPbBLj5cGoD723Ho7ZhAjLThoY/xMN2OYsSNzrg3S00QngZMzQvJf0ETrB3GtITk5FUs54qMRfiyUC72lw0gLTIJK8rs7fX/yeO+467afRt2xwHN50rEWJPeTVYWdlH/msh7NQ3LZ8/
|
||||||
|
root@9b638ff21113
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
network_1:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
name: tellurium_net
|
||||||
|
shared: false
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
port_0:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
device_owner: compute:None
|
||||||
|
fixed_ips:
|
||||||
|
- ip_address: 192.168.0.3
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
mac_address: 02:3d:ec:f6:f8:25
|
||||||
|
name: Tellurium_Fixtures-windows_port-hxvnswbzi56x
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
port_1:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
device_owner: compute:None
|
||||||
|
fixed_ips:
|
||||||
|
- ip_address: 192.168.0.4
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
mac_address: 02:20:6d:f7:16:da
|
||||||
|
name: Tellurium_Fixtures-instance_port-fmln6fjl4yvo
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
port_2:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
device_owner: compute:None
|
||||||
|
fixed_ips:
|
||||||
|
- ip_address: 192.168.0.5
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
mac_address: 02:cb:33:6b:60:f2
|
||||||
|
name: Tellurium_Fixtures-windows_ssh_pass_port-4zlwanbetsg2
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
port_4:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
device_owner: compute:nova
|
||||||
|
fixed_ips:
|
||||||
|
- ip_address: 192.168.0.6
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
mac_address: 02:4f:41:34:32:b4
|
||||||
|
name: 4f413432-b499-4fcc-a81a-1ee0d8bc16b7
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_1
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
router_0:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
name: tellurium_router
|
||||||
|
type: OS::Neutron::Router
|
||||||
|
router_0_gateway:
|
||||||
|
properties:
|
||||||
|
network_id:
|
||||||
|
get_param: router_0_external_network
|
||||||
|
router_id:
|
||||||
|
get_resource: router_0
|
||||||
|
type: OS::Neutron::RouterGateway
|
||||||
|
router_0_interface_3:
|
||||||
|
properties:
|
||||||
|
router_id:
|
||||||
|
get_resource: router_0
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
type: OS::Neutron::RouterInterface
|
||||||
|
security_group_0:
|
||||||
|
properties:
|
||||||
|
name: _default
|
||||||
|
rules:
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_mode: remote_group_id
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv6
|
||||||
|
remote_mode: remote_group_id
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv6
|
||||||
|
remote_ip_prefix: ::/0
|
||||||
|
type: OS::Neutron::SecurityGroup
|
||||||
|
security_group_1:
|
||||||
|
properties:
|
||||||
|
description: ''
|
||||||
|
name: http
|
||||||
|
rules:
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv6
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv4
|
||||||
|
port_range_max: 80
|
||||||
|
port_range_min: 80
|
||||||
|
protocol: tcp
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
type: OS::Neutron::SecurityGroup
|
||||||
|
server_0:
|
||||||
|
properties:
|
||||||
|
block_device_mapping_v2:
|
||||||
|
- device_name: /dev/vda
|
||||||
|
volume_id:
|
||||||
|
get_resource: volume_0
|
||||||
|
flavor:
|
||||||
|
get_param: server_0_flavor
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: Ubuntu 14.04
|
||||||
|
networks:
|
||||||
|
- port:
|
||||||
|
get_resource: port_4
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_1:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_1_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_1_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: tellurium_win_instance
|
||||||
|
networks:
|
||||||
|
- port:
|
||||||
|
get_resource: port_0
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_2:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_2_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_2_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_1
|
||||||
|
name: tellurium_win_instance_ssh_pass
|
||||||
|
networks:
|
||||||
|
- port:
|
||||||
|
get_resource: port_2
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_3:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_3_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_3_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: tellurium_instance
|
||||||
|
networks:
|
||||||
|
- port:
|
||||||
|
get_resource: port_1
|
||||||
|
type: OS::Nova::Server
|
||||||
|
subnet_0:
|
||||||
|
properties:
|
||||||
|
allocation_pools:
|
||||||
|
- end: 192.168.0.254
|
||||||
|
start: 192.168.0.2
|
||||||
|
cidr: 192.168.0.0/24
|
||||||
|
dns_nameservers:
|
||||||
|
- 8.8.8.8
|
||||||
|
enable_dhcp: true
|
||||||
|
host_routes: []
|
||||||
|
ip_version: 4
|
||||||
|
name: tellurium_net_subnet
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
volume_0:
|
||||||
|
properties:
|
||||||
|
image:
|
||||||
|
get_param: volume_0_image
|
||||||
|
metadata:
|
||||||
|
attached_mode: rw
|
||||||
|
readonly: 'False'
|
||||||
|
name: Ubuntu 14.04
|
||||||
|
size: 20
|
||||||
|
volume_type:
|
||||||
|
get_param: volume_0_volume_type
|
||||||
|
type: OS::Cinder::Volume
|
||||||
|
volume_1:
|
||||||
|
properties:
|
||||||
|
name: tellurium_volume
|
||||||
|
size: 5
|
||||||
|
volume_type:
|
||||||
|
get_param: volume_1_volume_type
|
||||||
|
type: OS::Cinder::Volume
|
277
flameclient/tests/fixtures/results/flame_extract_ports.yaml
vendored
Normal file
277
flameclient/tests/fixtures/results/flame_extract_ports.yaml
vendored
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
description: Generated template
|
||||||
|
heat_template_version: 2013-05-23
|
||||||
|
parameters:
|
||||||
|
external_network_for_floating_ip_0:
|
||||||
|
default: 6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
description: Network to allocate floating IP from
|
||||||
|
type: string
|
||||||
|
router_0_external_network:
|
||||||
|
default: 6ea98324-0f14-49f6-97c0-885d1b8dc517
|
||||||
|
description: Router external network
|
||||||
|
type: string
|
||||||
|
server_0_flavor:
|
||||||
|
default: '17'
|
||||||
|
description: Flavor to use for server server_0
|
||||||
|
type: string
|
||||||
|
server_1_flavor:
|
||||||
|
default: '42'
|
||||||
|
description: Flavor to use for server server_1
|
||||||
|
type: string
|
||||||
|
server_1_image:
|
||||||
|
default: 8254d703-e46f-4101-88ff-6f40bf7df51a
|
||||||
|
description: Image to use for server server_1
|
||||||
|
type: string
|
||||||
|
server_2_flavor:
|
||||||
|
default: '42'
|
||||||
|
description: Flavor to use for server server_2
|
||||||
|
type: string
|
||||||
|
server_2_image:
|
||||||
|
default: 8254d703-e46f-4101-88ff-6f40bf7df51a
|
||||||
|
description: Image to use for server server_2
|
||||||
|
type: string
|
||||||
|
server_3_flavor:
|
||||||
|
default: '16'
|
||||||
|
description: Flavor to use for server server_3
|
||||||
|
type: string
|
||||||
|
server_3_image:
|
||||||
|
default: dd7d4b21-79b8-42f0-8464-0d1a5274c638
|
||||||
|
description: Image to use for server server_3
|
||||||
|
type: string
|
||||||
|
volume_0_image:
|
||||||
|
default: 70a9c910-dd99-4065-bce9-11e89bc479fe
|
||||||
|
description: Image to create volume volume_0 from
|
||||||
|
type: string
|
||||||
|
volume_0_volume_type:
|
||||||
|
default: standard
|
||||||
|
description: Volume type for volume volume_0
|
||||||
|
type: string
|
||||||
|
volume_1_volume_type:
|
||||||
|
default: standard
|
||||||
|
description: Volume type for volume volume_1
|
||||||
|
type: string
|
||||||
|
resources:
|
||||||
|
floating_ip_0:
|
||||||
|
properties:
|
||||||
|
floating_network_id:
|
||||||
|
get_param: external_network_for_floating_ip_0
|
||||||
|
type: OS::Neutron::FloatingIP
|
||||||
|
keypair_0:
|
||||||
|
properties:
|
||||||
|
name: tellurium-key
|
||||||
|
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwp5kVZ+3baPZllNXZDG2mivd5nJ5wWY6Jj/WV6NlO6cUiaH5om6itU3lyJxtAbLgbbvY2FjMg1PI2JI3EHx0OSPEbDdeNsQGi31qyuiB1S5p6TreI0Dfy0tywJ9G2CURjkuJnC8SvnMfVYLMFBvx7p8RzxSdDm/zrmc4KY3ktdfYQDNtEiH2jucUUiY0ipVkDNhhv03+5C9cnpaIcVDBkddE/KEME8NIIh7s6aYCXJEWJx85nOVVRD5qK7ouV6FcGVn6zqWRD3jn0iSxcFwiKx7p6M77PmJAY4gBIpWQmutok6T4ZrXxa7jE4dybwo5e8dyvGyc7WWGqXcmcinUWr
|
||||||
|
Generated-by-Nova
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
keypair_1:
|
||||||
|
properties:
|
||||||
|
name: tellurium-key-phrase
|
||||||
|
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaYaTC6KCC2GURFMpRQiRq8Og10PcBbVnrQqluzi2E5vAqTHAegzivmGB8h2xrjXUfbKV2bE8kz2ZE66sq1yLO/jZ+rkOA+zLnOxNwkk3gQq57b26ZegPL2tTgottJTPGyPz6v2+LLtDf/+xTJMjkPKcMWylu12Js0XKVkdY35fwN7fRvA4xghtGu1GcmS2XFDMmeLDrG1KNPbBLj5cGoD723Ho7ZhAjLThoY/xMN2OYsSNzrg3S00QngZMzQvJf0ETrB3GtITk5FUs54qMRfiyUC72lw0gLTIJK8rs7fX/yeO+467afRt2xwHN50rEWJPeTVYWdlH/msh7NQ3LZ8/
|
||||||
|
root@9b638ff21113
|
||||||
|
type: OS::Nova::KeyPair
|
||||||
|
network_1:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
name: tellurium_net
|
||||||
|
shared: false
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
port_0:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
device_owner: compute:None
|
||||||
|
fixed_ips:
|
||||||
|
- ip_address: 192.168.0.3
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
mac_address: 02:3d:ec:f6:f8:25
|
||||||
|
name: Tellurium_Fixtures-windows_port-hxvnswbzi56x
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
port_1:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
device_owner: compute:None
|
||||||
|
fixed_ips:
|
||||||
|
- ip_address: 192.168.0.4
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
mac_address: 02:20:6d:f7:16:da
|
||||||
|
name: Tellurium_Fixtures-instance_port-fmln6fjl4yvo
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
port_2:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
device_owner: compute:None
|
||||||
|
fixed_ips:
|
||||||
|
- ip_address: 192.168.0.5
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
mac_address: 02:cb:33:6b:60:f2
|
||||||
|
name: Tellurium_Fixtures-windows_ssh_pass_port-4zlwanbetsg2
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
port_4:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
device_owner: compute:nova
|
||||||
|
fixed_ips:
|
||||||
|
- ip_address: 192.168.0.6
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
mac_address: 02:4f:41:34:32:b4
|
||||||
|
name: 4f413432-b499-4fcc-a81a-1ee0d8bc16b7
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
security_groups:
|
||||||
|
- get_resource: security_group_1
|
||||||
|
- get_resource: security_group_0
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
router_0:
|
||||||
|
properties:
|
||||||
|
admin_state_up: true
|
||||||
|
name: tellurium_router
|
||||||
|
type: OS::Neutron::Router
|
||||||
|
router_0_gateway:
|
||||||
|
properties:
|
||||||
|
network_id:
|
||||||
|
get_param: router_0_external_network
|
||||||
|
router_id:
|
||||||
|
get_resource: router_0
|
||||||
|
type: OS::Neutron::RouterGateway
|
||||||
|
router_0_interface_3:
|
||||||
|
properties:
|
||||||
|
router_id:
|
||||||
|
get_resource: router_0
|
||||||
|
subnet_id:
|
||||||
|
get_resource: subnet_0
|
||||||
|
type: OS::Neutron::RouterInterface
|
||||||
|
security_group_0:
|
||||||
|
properties:
|
||||||
|
name: _default
|
||||||
|
rules:
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_mode: remote_group_id
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv6
|
||||||
|
remote_mode: remote_group_id
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv6
|
||||||
|
remote_ip_prefix: ::/0
|
||||||
|
type: OS::Neutron::SecurityGroup
|
||||||
|
security_group_1:
|
||||||
|
properties:
|
||||||
|
description: ''
|
||||||
|
name: http
|
||||||
|
rules:
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv4
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
- direction: egress
|
||||||
|
ethertype: IPv6
|
||||||
|
- direction: ingress
|
||||||
|
ethertype: IPv4
|
||||||
|
port_range_max: 80
|
||||||
|
port_range_min: 80
|
||||||
|
protocol: tcp
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
type: OS::Neutron::SecurityGroup
|
||||||
|
server_0:
|
||||||
|
properties:
|
||||||
|
block_device_mapping_v2:
|
||||||
|
- device_name: /dev/vda
|
||||||
|
volume_id:
|
||||||
|
get_resource: volume_0
|
||||||
|
flavor:
|
||||||
|
get_param: server_0_flavor
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: Ubuntu 14.04
|
||||||
|
networks:
|
||||||
|
- port:
|
||||||
|
get_resource: port_4
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_1:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_1_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_1_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: tellurium_win_instance
|
||||||
|
networks:
|
||||||
|
- port:
|
||||||
|
get_resource: port_0
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_2:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_2_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_2_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_1
|
||||||
|
name: tellurium_win_instance_ssh_pass
|
||||||
|
networks:
|
||||||
|
- port:
|
||||||
|
get_resource: port_2
|
||||||
|
type: OS::Nova::Server
|
||||||
|
server_3:
|
||||||
|
properties:
|
||||||
|
flavor:
|
||||||
|
get_param: server_3_flavor
|
||||||
|
image:
|
||||||
|
get_param: server_3_image
|
||||||
|
key_name:
|
||||||
|
get_resource: keypair_0
|
||||||
|
name: tellurium_instance
|
||||||
|
networks:
|
||||||
|
- port:
|
||||||
|
get_resource: port_1
|
||||||
|
type: OS::Nova::Server
|
||||||
|
subnet_0:
|
||||||
|
properties:
|
||||||
|
allocation_pools:
|
||||||
|
- end: 192.168.0.254
|
||||||
|
start: 192.168.0.2
|
||||||
|
cidr: 192.168.0.0/24
|
||||||
|
dns_nameservers:
|
||||||
|
- 8.8.8.8
|
||||||
|
enable_dhcp: true
|
||||||
|
host_routes: []
|
||||||
|
ip_version: 4
|
||||||
|
name: tellurium_net_subnet
|
||||||
|
network_id:
|
||||||
|
get_resource: network_1
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
volume_0:
|
||||||
|
properties:
|
||||||
|
image:
|
||||||
|
get_param: volume_0_image
|
||||||
|
metadata:
|
||||||
|
attached_mode: rw
|
||||||
|
readonly: 'False'
|
||||||
|
name: Ubuntu 14.04
|
||||||
|
size: 20
|
||||||
|
volume_type:
|
||||||
|
get_param: volume_0_volume_type
|
||||||
|
type: OS::Cinder::Volume
|
||||||
|
volume_1:
|
||||||
|
properties:
|
||||||
|
name: tellurium_volume
|
||||||
|
size: 5
|
||||||
|
volume_type:
|
||||||
|
get_param: volume_1_volume_type
|
||||||
|
type: OS::Cinder::Volume
|
124
flameclient/tests/fixtures/utils.py
vendored
Normal file
124
flameclient/tests/fixtures/utils.py
vendored
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pprint import pformat
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient.utils import get_deep_attr
|
||||||
|
from flameclient.utils import munchify
|
||||||
|
|
||||||
|
|
||||||
|
def get_licence():
|
||||||
|
import flameclient
|
||||||
|
licence_filename = os.path.join(
|
||||||
|
os.path.realpath(os.path.dirname(flameclient.__file__)),
|
||||||
|
'LICENSE.txt'
|
||||||
|
)
|
||||||
|
with open(licence_filename) as fp:
|
||||||
|
return fp.read()
|
||||||
|
|
||||||
|
|
||||||
|
def get_python_header():
|
||||||
|
top = '# -*- coding: utf-8 -*-'
|
||||||
|
lines = get_licence().strip().split('\n')
|
||||||
|
commented_lines = ['# %s' % line.strip() for line in lines]
|
||||||
|
commented_lines = [line.strip() for line in commented_lines]
|
||||||
|
commented_licence = '\n'.join(commented_lines)
|
||||||
|
return '%s\n\n%s\n' % (top, commented_licence)
|
||||||
|
|
||||||
|
|
||||||
|
def write_openstackcloud_fixture_data(filename, attr_name, data):
|
||||||
|
"""Write a fixtures file with given data
|
||||||
|
|
||||||
|
:param str filename: filename holding the fixtures.
|
||||||
|
:param str attr_name: attribute name of the `connection` parameter.
|
||||||
|
|
||||||
|
:param list data: a python list of data which needs to be returned
|
||||||
|
|
||||||
|
"""
|
||||||
|
fixtures = [vars(munchify(element)) for element in data]
|
||||||
|
|
||||||
|
openstackcloud_dir = os.path.join(
|
||||||
|
os.path.realpath(os.path.dirname(__file__)),
|
||||||
|
'openstackcloud'
|
||||||
|
)
|
||||||
|
|
||||||
|
if not filename.startswith('/'):
|
||||||
|
filename = os.path.join(openstackcloud_dir, filename)
|
||||||
|
|
||||||
|
head = get_python_header()
|
||||||
|
|
||||||
|
file_str = "%s\n\nNAME = '%s'\n\nFIXTURES = %s\n" % (
|
||||||
|
head, attr_name, pformat(fixtures, indent=1)
|
||||||
|
)
|
||||||
|
with open(filename, 'w') as fp:
|
||||||
|
fp.write(file_str)
|
||||||
|
|
||||||
|
|
||||||
|
def write_openstackcloud_fixture(filename, attr_name, connection):
|
||||||
|
"""Write a fixtures API call file
|
||||||
|
|
||||||
|
:param str filename: filename holding the fixtures.
|
||||||
|
:param str attr_name: attribute name of the `connection` parameter.
|
||||||
|
|
||||||
|
:param openstack.connection.Connection connection:
|
||||||
|
An `openstack.connection.Connection` instance (`openstacksdk`).
|
||||||
|
Since `shade.openstackcloud.OpenStackCloud` (`shade`) is a subclass
|
||||||
|
you can also use shade instances.
|
||||||
|
|
||||||
|
ex. to write connection.network.security_groups to a fixtures file:
|
||||||
|
|
||||||
|
write_openstackcloud_fixture(
|
||||||
|
'flameclient/tests/fixtures/openstackcloud/security_groups.py',
|
||||||
|
'network.security_groups',
|
||||||
|
connection
|
||||||
|
)
|
||||||
|
|
||||||
|
"""
|
||||||
|
method = get_deep_attr(connection, attr_name)
|
||||||
|
write_openstackcloud_fixture_data(filename, attr_name, method())
|
||||||
|
|
||||||
|
|
||||||
|
def rewrite_all_openstackcloud_fixtures(connection):
|
||||||
|
"""Rewrite all fixtures in flameclient.tests.fixtures
|
||||||
|
|
||||||
|
This function rewrites all fixture files present in
|
||||||
|
flameclient.tests.fixtures from an existing openstack session.
|
||||||
|
|
||||||
|
:param openstack.connection.Connection connection:
|
||||||
|
An `openstack.connection.Connection` instance (`openstacksdk`).
|
||||||
|
Since `shade.openstackcloud.OpenStackCloud` (`shade`) is a subclass
|
||||||
|
you can also use shade instances.
|
||||||
|
|
||||||
|
DANGEROUS! You can break everything!!!
|
||||||
|
"""
|
||||||
|
from flameclient.tests.fixtures import openstackcloud
|
||||||
|
for fixture_module in six.itervalues(openstackcloud.FIXTURES):
|
||||||
|
write_openstackcloud_fixture(
|
||||||
|
fixture_module.__file__,
|
||||||
|
fixture_module.NAME,
|
||||||
|
connection
|
||||||
|
)
|
File diff suppressed because it is too large
Load Diff
@ -1,640 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright (c) 2014 Cloudwatt
|
|
||||||
|
|
||||||
# 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 re
|
|
||||||
|
|
||||||
import mock
|
|
||||||
|
|
||||||
from flameclient import flame
|
|
||||||
from flameclient.tests import base
|
|
||||||
|
|
||||||
|
|
||||||
class FakeBase(object):
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
for key, value in kwargs.items():
|
|
||||||
setattr(self, key, value)
|
|
||||||
|
|
||||||
|
|
||||||
class FakeVolume(FakeBase):
|
|
||||||
id = 1234
|
|
||||||
size = 1
|
|
||||||
source_volid = None
|
|
||||||
bootable = 'false'
|
|
||||||
snapshot_id = None
|
|
||||||
display_name = 'vol1'
|
|
||||||
display_description = 'Description'
|
|
||||||
volume_type = 'fast'
|
|
||||||
metadata = None
|
|
||||||
|
|
||||||
|
|
||||||
class FakeServer(FakeBase):
|
|
||||||
id = '1234'
|
|
||||||
name = 'server1'
|
|
||||||
config_drive = None
|
|
||||||
flavor = {'id': '2'}
|
|
||||||
image = {'id': '3333',
|
|
||||||
'links': [{'href': 'http://p/7777/images/3333',
|
|
||||||
'rel': 'bookmark'}]}
|
|
||||||
key_name = 'testkey'
|
|
||||||
addresses = []
|
|
||||||
metadata = None
|
|
||||||
|
|
||||||
def __init__(self, server_id, **kwargs):
|
|
||||||
self.id = server_id
|
|
||||||
kwargs.setdefault('OS-DCF:diskConfig', 'MANUAL')
|
|
||||||
kwargs.setdefault('os-extended-volumes:volumes_attached', [])
|
|
||||||
super(FakeServer, self).__init__(**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class FakeFlavor(FakeBase):
|
|
||||||
name = 'm1.tiny'
|
|
||||||
id = '1'
|
|
||||||
|
|
||||||
|
|
||||||
class FakeKeypair(FakeBase):
|
|
||||||
name = 'key'
|
|
||||||
id = 'key'
|
|
||||||
public_key = 'ssh-rsa AAAAB3NzaC'
|
|
||||||
|
|
||||||
|
|
||||||
class FakeSecurityGroup(FakeBase):
|
|
||||||
id = '1'
|
|
||||||
name = 'name'
|
|
||||||
|
|
||||||
|
|
||||||
class FakeNeutronManager(object):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.groups = [{u'description': u'default',
|
|
||||||
u'id': u'secgorup1',
|
|
||||||
u'name': u'default',
|
|
||||||
u'security_group_rules': [
|
|
||||||
{u'direction': u'ingress',
|
|
||||||
u'ethertype': u'IPv4',
|
|
||||||
u'id': u'secgroup-rule1',
|
|
||||||
u'port_range_max': 65535,
|
|
||||||
u'port_range_min': 1,
|
|
||||||
u'protocol': u'tcp',
|
|
||||||
u'remote_group_id': None,
|
|
||||||
u'remote_ip_prefix': u'0.0.0.0/0',
|
|
||||||
u'security_group_id': u'secgorup1',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
],
|
|
||||||
u'tenant_id': u'tenant1'}]
|
|
||||||
|
|
||||||
self.routers = [
|
|
||||||
{u'admin_state_up': True,
|
|
||||||
u'external_gateway_info': {u'enable_snat': True,
|
|
||||||
u'network_id': u'network3'},
|
|
||||||
u'id': u'router1',
|
|
||||||
u'name': u'gw-internal-a',
|
|
||||||
u'routes': [],
|
|
||||||
u'status': u'ACTIVE',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
]
|
|
||||||
|
|
||||||
self.ports = [{u'admin_state_up': True,
|
|
||||||
u'allowed_address_pairs': [],
|
|
||||||
u'binding:vnic_type': u'normal',
|
|
||||||
u'device_id': u'router1',
|
|
||||||
u'device_owner': u'network:router_interface',
|
|
||||||
u'extra_dhcp_opts': [],
|
|
||||||
u'fixed_ips': [{u'ip_address': u'192.168.203.1',
|
|
||||||
u'subnet_id': u'subnet3'}],
|
|
||||||
u'id': u'port1',
|
|
||||||
u'mac_address': u'fa:16:3e:fe:c1:b3',
|
|
||||||
u'name': u'',
|
|
||||||
u'network_id': u'network1',
|
|
||||||
u'security_groups': [],
|
|
||||||
u'status': u'ACTIVE',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'admin_state_up': True,
|
|
||||||
u'allowed_address_pairs': [],
|
|
||||||
u'binding:vnic_type': u'normal',
|
|
||||||
u'device_id': u'server3',
|
|
||||||
u'device_owner': u'compute:nova',
|
|
||||||
u'extra_dhcp_opts': [],
|
|
||||||
u'fixed_ips': [{u'ip_address': u'192.168.203.5',
|
|
||||||
u'subnet_id': u'subnet3'}],
|
|
||||||
u'id': u'port2',
|
|
||||||
u'mac_address': u'fa:16:3e:e4:44:7b',
|
|
||||||
u'name': u'',
|
|
||||||
u'network_id': u'network1',
|
|
||||||
u'security_groups': [u'secgorup1'],
|
|
||||||
u'status': u'ACTIVE',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'admin_state_up': True,
|
|
||||||
u'allowed_address_pairs': [],
|
|
||||||
u'binding:vnic_type': u'normal',
|
|
||||||
u'device_id': u'server2',
|
|
||||||
u'device_owner': u'compute:nova',
|
|
||||||
u'extra_dhcp_opts': [],
|
|
||||||
u'fixed_ips': [{u'ip_address': u'192.168.203.4',
|
|
||||||
u'subnet_id': u'subnet3'}],
|
|
||||||
u'id': u'port3',
|
|
||||||
u'mac_address': u'fa:16:3e:e8:e4:e2',
|
|
||||||
u'name': u'',
|
|
||||||
u'network_id': u'network1',
|
|
||||||
u'security_groups': [u'secgorup1'],
|
|
||||||
u'status': u'ACTIVE',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'admin_state_up': True,
|
|
||||||
u'allowed_address_pairs': [],
|
|
||||||
u'binding:vnic_type': u'normal',
|
|
||||||
u'device_id': u'dhcp1-network1',
|
|
||||||
u'device_owner': u'network:dhcp',
|
|
||||||
u'extra_dhcp_opts': [],
|
|
||||||
u'fixed_ips': [{u'ip_address': u'192.168.203.3',
|
|
||||||
u'subnet_id': u'subnet3'},
|
|
||||||
{u'ip_address': u'192.168.204.2',
|
|
||||||
u'subnet_id': u'subnet4'}],
|
|
||||||
u'id': u'port4',
|
|
||||||
u'mac_address': u'fa:16:3e:af:86:30',
|
|
||||||
u'name': u'',
|
|
||||||
u'network_id': u'network1',
|
|
||||||
u'security_groups': [],
|
|
||||||
u'status': u'ACTIVE',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'admin_state_up': True,
|
|
||||||
u'allowed_address_pairs': [],
|
|
||||||
u'binding:vnic_type': u'normal',
|
|
||||||
u'device_id': u'server1',
|
|
||||||
u'device_owner': u'compute:nova',
|
|
||||||
u'extra_dhcp_opts': [],
|
|
||||||
u'fixed_ips': [{u'ip_address': u'192.168.203.2',
|
|
||||||
u'subnet_id': u'subnet3'}],
|
|
||||||
u'id': u'port6',
|
|
||||||
u'mac_address': u'fa:16:3e:b0:9a:e2',
|
|
||||||
u'name': u'',
|
|
||||||
u'network_id': u'network1',
|
|
||||||
u'security_groups': [u'secgorup1'],
|
|
||||||
u'status': u'ACTIVE',
|
|
||||||
u'tenant_id': u'tenant1'}
|
|
||||||
]
|
|
||||||
self.subnets = [{u'allocation_pools': [
|
|
||||||
{u'end': u'172.19.0.254', u'start': u'172.19.0.2'}],
|
|
||||||
u'cidr': u'172.19.0.0/24',
|
|
||||||
u'dns_nameservers': [],
|
|
||||||
u'enable_dhcp': True,
|
|
||||||
u'gateway_ip': u'172.19.0.1',
|
|
||||||
u'host_routes': [],
|
|
||||||
u'id': u'subnet1',
|
|
||||||
u'ip_version': 4,
|
|
||||||
u'name': u'storage',
|
|
||||||
u'network_id': u'network2',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'allocation_pools': [
|
|
||||||
{u'end': u'10.8.8.200',
|
|
||||||
u'start': u'10.8.8.100'}],
|
|
||||||
u'cidr': u'10.8.8.0/24',
|
|
||||||
u'dns_nameservers': [],
|
|
||||||
u'enable_dhcp': False,
|
|
||||||
u'gateway_ip': u'10.8.8.254',
|
|
||||||
u'host_routes': [],
|
|
||||||
u'id': u'subnet2',
|
|
||||||
u'ip_version': 4,
|
|
||||||
u'name': u'ext-subnet',
|
|
||||||
u'network_id': u'network3',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'allocation_pools': [{u'end': u'192.168.203.254',
|
|
||||||
u'start': u'192.168.203.2'}],
|
|
||||||
u'cidr': u'192.168.203.0/24',
|
|
||||||
u'dns_nameservers': [],
|
|
||||||
u'enable_dhcp': True,
|
|
||||||
u'gateway_ip': u'192.168.203.1',
|
|
||||||
u'host_routes': [],
|
|
||||||
u'id': u'subnet3',
|
|
||||||
u'ip_version': 4,
|
|
||||||
u'name': u'int-a-1',
|
|
||||||
u'network_id': u'network1',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'allocation_pools': [{u'end': u'192.168.204.254',
|
|
||||||
u'start': u'192.168.204.2'}],
|
|
||||||
u'cidr': u'192.168.204.0/24',
|
|
||||||
u'dns_nameservers': [],
|
|
||||||
u'enable_dhcp': True,
|
|
||||||
u'gateway_ip': u'192.168.204.1',
|
|
||||||
u'host_routes': [],
|
|
||||||
u'id': u'subnet4',
|
|
||||||
u'ip_version': 4,
|
|
||||||
u'name': u'int-a-2',
|
|
||||||
u'network_id': u'network1',
|
|
||||||
u'tenant_id': u'tenant1'}]
|
|
||||||
self.networks = [{u'admin_state_up': True,
|
|
||||||
u'id': u'network1',
|
|
||||||
u'name': u'internal',
|
|
||||||
u'router:external': False,
|
|
||||||
u'shared': False,
|
|
||||||
u'status': u'ACTIVE',
|
|
||||||
u'subnets': [u'subnet3',
|
|
||||||
u'subnet4'],
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'admin_state_up': True,
|
|
||||||
u'id': u'network2',
|
|
||||||
u'name': u'storage',
|
|
||||||
u'router:external': False,
|
|
||||||
u'shared': False,
|
|
||||||
u'status': u'ACTIVE',
|
|
||||||
u'subnets': [u'subnet1'],
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'admin_state_up': True,
|
|
||||||
u'id': u'network3',
|
|
||||||
u'name': u'ext-net',
|
|
||||||
u'router:external': True,
|
|
||||||
u'shared': True,
|
|
||||||
u'status': u'ACTIVE',
|
|
||||||
u'subnets': [u'subnet2'],
|
|
||||||
u'tenant_id': u'tenant1'}]
|
|
||||||
|
|
||||||
self.floatingips = [{u'fixed_ip_address': None,
|
|
||||||
u'floating_ip_address': u'10.8.8.102',
|
|
||||||
u'floating_network_id': u'network3',
|
|
||||||
u'id': u'floating1',
|
|
||||||
u'port_id': None,
|
|
||||||
u'router_id': None,
|
|
||||||
u'status': u'DOWN',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'fixed_ip_address': None,
|
|
||||||
u'floating_ip_address': u'10.8.8.101',
|
|
||||||
u'floating_network_id': u'network3',
|
|
||||||
u'id': u'floating2',
|
|
||||||
u'port_id': None,
|
|
||||||
u'router_id': None,
|
|
||||||
u'status': u'DOWN',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'fixed_ip_address': u'192.168.203.4',
|
|
||||||
u'floating_ip_address': u'10.8.8.168',
|
|
||||||
u'floating_network_id': u'network3',
|
|
||||||
u'id': u'floating3',
|
|
||||||
u'port_id': u'port3',
|
|
||||||
u'router_id': u'router1',
|
|
||||||
u'status': u'ACTIVE',
|
|
||||||
u'tenant_id': u'tenant1'},
|
|
||||||
{u'fixed_ip_address': None,
|
|
||||||
u'floating_ip_address': u'10.8.8.118',
|
|
||||||
u'floating_network_id': u'network3',
|
|
||||||
u'id': u'floating4',
|
|
||||||
u'port_id': None,
|
|
||||||
u'router_id': None,
|
|
||||||
u'status': u'DOWN',
|
|
||||||
u'tenant_id': u'tenant1'}]
|
|
||||||
|
|
||||||
def subnet_list(self):
|
|
||||||
return self.subnets
|
|
||||||
|
|
||||||
def network_list(self):
|
|
||||||
return self.networks
|
|
||||||
|
|
||||||
def port_list(self):
|
|
||||||
return self.ports
|
|
||||||
|
|
||||||
def router_list(self):
|
|
||||||
return self.routers
|
|
||||||
|
|
||||||
def router_interfaces_list(self, router):
|
|
||||||
return [port for port in self.ports
|
|
||||||
if port['device_id'] == router['id']]
|
|
||||||
|
|
||||||
def secgroup_list(self):
|
|
||||||
return self.groups
|
|
||||||
|
|
||||||
def floatingip_list(self):
|
|
||||||
return self.floatingips
|
|
||||||
|
|
||||||
|
|
||||||
class FakeNovaManager(object):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.servers = [FakeServer('server1'),
|
|
||||||
FakeServer('server2'),
|
|
||||||
FakeServer('server3')]
|
|
||||||
self.servergroups = []
|
|
||||||
self.flavors = [FakeFlavor(id='2', name='m1.small')]
|
|
||||||
self.groups = {}
|
|
||||||
self.keypairs = [FakeKeypair(name='testkey',
|
|
||||||
public_key='ssh-rsa XXXX')]
|
|
||||||
|
|
||||||
def keypair_list(self):
|
|
||||||
return self.keypairs
|
|
||||||
|
|
||||||
def flavor_list(self):
|
|
||||||
return self.flavors
|
|
||||||
|
|
||||||
def server_list(self):
|
|
||||||
return self.servers
|
|
||||||
|
|
||||||
def server_security_group_list(self, server):
|
|
||||||
return self.groups.get(server.name, [])
|
|
||||||
|
|
||||||
def servergroup_list(self):
|
|
||||||
return self.servergroups
|
|
||||||
|
|
||||||
|
|
||||||
class FakeCinderManager(object):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.volumes = [FakeVolume(), ]
|
|
||||||
|
|
||||||
def volume_list(self):
|
|
||||||
return self.volumes
|
|
||||||
|
|
||||||
|
|
||||||
class ResourceTestCase(base.TestCase):
|
|
||||||
|
|
||||||
def test_template_resource(self):
|
|
||||||
resource = flame.Resource('my-name',
|
|
||||||
'my-type',
|
|
||||||
properties='my-properties')
|
|
||||||
|
|
||||||
expected = {
|
|
||||||
'my-name': {
|
|
||||||
'type': 'my-type',
|
|
||||||
'properties': 'my-properties',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.assertEqual(expected, resource.template_resource)
|
|
||||||
|
|
||||||
|
|
||||||
class BaseTestCase(base.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(BaseTestCase, self).setUp()
|
|
||||||
self.patch_neutron = mock.patch('flameclient.managers.NeutronManager')
|
|
||||||
self.mock_neutron = self.patch_neutron.start()
|
|
||||||
self.patch_nova = mock.patch('flameclient.managers.NovaManager')
|
|
||||||
self.mock_nova = self.patch_nova.start()
|
|
||||||
self.patch_cinder = mock.patch('flameclient.managers.CinderManager')
|
|
||||||
self.mock_cinder = self.patch_cinder.start()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.mock_neutron.stop()
|
|
||||||
self.mock_nova.stop()
|
|
||||||
self.mock_cinder.stop()
|
|
||||||
super(BaseTestCase, self).tearDown()
|
|
||||||
|
|
||||||
def get_generator(self, exclude_servers, exclude_volumes,
|
|
||||||
exclude_keypairs, generate_data, extract_ports):
|
|
||||||
generator = flame.TemplateGenerator('x', 'x', 'x', 'x', True,
|
|
||||||
'publicURL')
|
|
||||||
generator.extract_vm_details(exclude_servers, exclude_volumes,
|
|
||||||
exclude_keypairs, generate_data,
|
|
||||||
extract_ports)
|
|
||||||
return generator
|
|
||||||
|
|
||||||
def check_stackdata(self, resources, expected_resources):
|
|
||||||
merged_resources = {}
|
|
||||||
for resource in resources:
|
|
||||||
merged_resources.update(resource.stack_resource)
|
|
||||||
|
|
||||||
self.assertEqual(expected_resources, merged_resources)
|
|
||||||
|
|
||||||
def check_template(self, resources, expected_resources,
|
|
||||||
expected_parameters=None):
|
|
||||||
|
|
||||||
expected_parameters = expected_parameters or {}
|
|
||||||
merged_resources = {}
|
|
||||||
merged_parameters = {}
|
|
||||||
for resource in resources:
|
|
||||||
merged_resources.update(resource.template_resource)
|
|
||||||
merged_parameters.update(resource.template_parameter)
|
|
||||||
|
|
||||||
self.assertEqual(expected_resources, merged_resources)
|
|
||||||
self.assertEqual(expected_parameters, merged_parameters)
|
|
||||||
|
|
||||||
|
|
||||||
class StackDataTests(BaseTestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(StackDataTests, self).setUp()
|
|
||||||
self.mock_neutron.return_value = FakeNeutronManager()
|
|
||||||
self.mock_nova.return_value = FakeNovaManager()
|
|
||||||
self.mock_cinder.return_value = FakeCinderManager()
|
|
||||||
|
|
||||||
def test_routers_presents(self):
|
|
||||||
generator = self.get_generator(False, False, False, True, True)
|
|
||||||
extraction = generator._extract_routers()
|
|
||||||
routers = {r.name: r for r in extraction}
|
|
||||||
self.assertIn('router_0', routers)
|
|
||||||
|
|
||||||
def test_routers_resource_names(self):
|
|
||||||
generator = self.get_generator(False, False, False, True, True)
|
|
||||||
generator_output = generator._extract_routers()
|
|
||||||
routers = (res for res in generator_output
|
|
||||||
if res.type == "OS::Neutron::Router")
|
|
||||||
for n, router in enumerate(routers):
|
|
||||||
assert(router.name.startswith("router_"))
|
|
||||||
|
|
||||||
def test_ports_presents(self):
|
|
||||||
generator = self.get_generator(False, False, False, True, True)
|
|
||||||
extraction = generator._extract_ports()
|
|
||||||
ports = {r.name: r for r in extraction}
|
|
||||||
self.assertIn('port_1', ports)
|
|
||||||
self.assertIn('port_2', ports)
|
|
||||||
|
|
||||||
def test_ports_resource_names_types(self):
|
|
||||||
generator = self.get_generator(False, False, False, True, True)
|
|
||||||
extraction = generator._extract_ports()
|
|
||||||
for n, port in enumerate(extraction):
|
|
||||||
props = port.properties
|
|
||||||
assert(extraction[0].name.startswith("port_"))
|
|
||||||
self.assertEqual("OS::Neutron::Port", port.type)
|
|
||||||
self.assertIsInstance(props['admin_state_up'], bool)
|
|
||||||
self.assertIsInstance(props['security_groups'], list)
|
|
||||||
assert(props['device_owner'].startswith("compute:"))
|
|
||||||
|
|
||||||
def test_port_fixed_ip(self):
|
|
||||||
reference = [{'ip_address': '192.168.203.2',
|
|
||||||
'subnet_id': {'get_resource': 'subnet_2'}}]
|
|
||||||
generator = self.get_generator(False, False, False, True, True)
|
|
||||||
extraction = generator._extract_ports()
|
|
||||||
# Get the right port for the test
|
|
||||||
port = next((p for p in extraction if
|
|
||||||
p.properties['mac_address'] == 'fa:16:3e:b0:9a:e2'))
|
|
||||||
props = port.properties
|
|
||||||
self.assertIsInstance(props['fixed_ips'], list)
|
|
||||||
fixed_ips = props['fixed_ips']
|
|
||||||
for ref in reference:
|
|
||||||
self.assertIn(ref, fixed_ips)
|
|
||||||
|
|
||||||
def test_servers_ports_assignations(self):
|
|
||||||
generator = self.get_generator(False, False, False, True, True)
|
|
||||||
extraction = generator._extract_servers()
|
|
||||||
used_ports = []
|
|
||||||
for n, server in enumerate(extraction):
|
|
||||||
props = server.properties
|
|
||||||
self.assertIsInstance(props['networks'], list)
|
|
||||||
for network in props['networks']:
|
|
||||||
port = network['port']['get_resource']
|
|
||||||
assert(port.startswith("port_"))
|
|
||||||
# Port has not been used by another server
|
|
||||||
self.assertNotIn(port, used_ports)
|
|
||||||
used_ports.append(port)
|
|
||||||
|
|
||||||
def test_floating_association(self):
|
|
||||||
generator = self.get_generator(False, False, False, True, True)
|
|
||||||
extraction = generator._extract_floating()
|
|
||||||
associations = (res for res in extraction
|
|
||||||
if res.type == "OS::Neutron::FloatingIPAssociation")
|
|
||||||
for association in associations:
|
|
||||||
props = association.properties
|
|
||||||
assert(props['floatingip_id']['get_resource'].
|
|
||||||
startswith('floatingip_'))
|
|
||||||
assert(props['port_id']['get_resource'].
|
|
||||||
startswith('port_'))
|
|
||||||
|
|
||||||
|
|
||||||
class GenerationTests(BaseTestCase):
|
|
||||||
resource_ref = set(['floatingip_association_2',
|
|
||||||
'subnet_2', 'subnet_3', 'subnet_0',
|
|
||||||
'port_2', 'port_1', 'port_4',
|
|
||||||
'server_2', 'server_1', 'server_0',
|
|
||||||
'router_0',
|
|
||||||
'router_0_interface_0',
|
|
||||||
'router_0_gateway',
|
|
||||||
'key_0',
|
|
||||||
'network_0', 'network_1',
|
|
||||||
'floatingip_0', 'floatingip_1',
|
|
||||||
'floatingip_2', 'floatingip_3',
|
|
||||||
'volume_0'])
|
|
||||||
|
|
||||||
params_ref = set(['volume_0_volume_type',
|
|
||||||
'external_network_for_floating_ip_3',
|
|
||||||
'external_network_for_floating_ip_2',
|
|
||||||
'external_network_for_floating_ip_1',
|
|
||||||
'external_network_for_floating_ip_0',
|
|
||||||
'port_4_default_security_group',
|
|
||||||
'port_1_default_security_group',
|
|
||||||
'port_2_default_security_group',
|
|
||||||
'router_0_external_network',
|
|
||||||
'server_1_image',
|
|
||||||
'server_1_flavor',
|
|
||||||
'server_1_key',
|
|
||||||
'server_2_image',
|
|
||||||
'server_2_flavor',
|
|
||||||
'server_2_key',
|
|
||||||
'server_0_image',
|
|
||||||
'server_0_flavor',
|
|
||||||
'server_0_key'])
|
|
||||||
|
|
||||||
data_ref = set(['floatingip_0', 'floatingip_1', 'floatingip_2',
|
|
||||||
'floatingip_3',
|
|
||||||
'floatingip_association_2',
|
|
||||||
'key_0',
|
|
||||||
'network_0', 'network_1',
|
|
||||||
'port_1', 'port_2', 'port_4',
|
|
||||||
'router_0',
|
|
||||||
'router_0_gateway',
|
|
||||||
'router_0_interface_0',
|
|
||||||
'server_0', 'server_1', 'server_2',
|
|
||||||
'subnet_0', 'subnet_2', 'subnet_3',
|
|
||||||
'volume_0'])
|
|
||||||
|
|
||||||
def filter_set(self, filtered_set, exclude):
|
|
||||||
excluded_set = set()
|
|
||||||
for exc in exclude:
|
|
||||||
excluded_set.update(
|
|
||||||
set([e for e in filtered_set if re.search(exc, e)])
|
|
||||||
)
|
|
||||||
return filtered_set.difference(excluded_set)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(GenerationTests, self).setUp()
|
|
||||||
self.mock_neutron.return_value = FakeNeutronManager()
|
|
||||||
self.mock_nova.return_value = FakeNovaManager()
|
|
||||||
self.mock_cinder.return_value = FakeCinderManager()
|
|
||||||
|
|
||||||
def test_generation(self):
|
|
||||||
|
|
||||||
exclusion_table = [
|
|
||||||
{'call_params': (False, False, False, True, True),
|
|
||||||
'resource_filter': [],
|
|
||||||
'params_filter': ['^server_\d+_key$'],
|
|
||||||
'data_filter': []},
|
|
||||||
# No server
|
|
||||||
{'call_params': (True, False, False, True, True),
|
|
||||||
'resource_filter': ['^server'],
|
|
||||||
'params_filter': ['^server'],
|
|
||||||
'data_filter': ['^server']},
|
|
||||||
# No volumes
|
|
||||||
{'call_params': (False, True, False, True, True),
|
|
||||||
'resource_filter': ['^volume'],
|
|
||||||
'params_filter': [r'^volume_\d+_volume_type$',
|
|
||||||
'^server_\d+_key$'],
|
|
||||||
'data_filter': ['^volume']},
|
|
||||||
# No keys
|
|
||||||
{'call_params': (False, False, True, True, True),
|
|
||||||
'resource_filter': ['^key_\d+$'],
|
|
||||||
'params_filter': [],
|
|
||||||
'data_filter': ['^key', 'server_\d+_key']},
|
|
||||||
# No ports
|
|
||||||
{'call_params': (False, False, False, True, False),
|
|
||||||
'resource_filter': ['^port_\d+$'],
|
|
||||||
'params_filter': ['^port_\d+_default_security_group$',
|
|
||||||
'server_\d+_key$'],
|
|
||||||
'data_filter': ['^port_\d+', '^floatingip_association_\d+$']},
|
|
||||||
]
|
|
||||||
|
|
||||||
for exclusion in exclusion_table:
|
|
||||||
generator = self.get_generator(*exclusion['call_params'])
|
|
||||||
resource_ref = self.filter_set(self.resource_ref,
|
|
||||||
exclusion['resource_filter'])
|
|
||||||
params_ref = self.filter_set(self.params_ref,
|
|
||||||
exclusion['params_filter'])
|
|
||||||
data_ref = self.filter_set(self.data_ref,
|
|
||||||
exclusion['data_filter'])
|
|
||||||
|
|
||||||
generator.extract_data()
|
|
||||||
# All the resources, params and datas are present
|
|
||||||
self.assertEqual(resource_ref,
|
|
||||||
set(generator.template['resources'].keys()),
|
|
||||||
"Called with : %r" % (exclusion['call_params'],))
|
|
||||||
self.assertEqual(params_ref,
|
|
||||||
set(generator.template['parameters'].keys()),
|
|
||||||
"Called with : %r" % (exclusion['call_params'],))
|
|
||||||
self.assertEqual(data_ref,
|
|
||||||
set(generator.stack_data['resources'].keys()),
|
|
||||||
"Called with : %r" % (exclusion['call_params'],))
|
|
||||||
|
|
||||||
def test_floating_association_data(self):
|
|
||||||
generator = self.get_generator(False, False, False, True, True)
|
|
||||||
generator.extract_data()
|
|
||||||
# Look for floating ips
|
|
||||||
assoc_name = 'floatingip_association_2'
|
|
||||||
association_data = generator.stack_data['resources'][assoc_name]
|
|
||||||
reference = {'action': 'CREATE',
|
|
||||||
'metadata': {},
|
|
||||||
'name': 'floatingip_association_2',
|
|
||||||
'resource_data': {},
|
|
||||||
'resource_id': u'floating3:port3',
|
|
||||||
'status': 'COMPLETE',
|
|
||||||
'type': 'OS::Neutron::FloatingIPAssociation'}
|
|
||||||
self.assertEqual(reference, association_data)
|
|
||||||
|
|
||||||
def test_port_data(self):
|
|
||||||
generator = self.get_generator(False, False, False, True, True)
|
|
||||||
generator.extract_data()
|
|
||||||
# Look for floating ips
|
|
||||||
assoc_name = 'port_2'
|
|
||||||
association_data = generator.stack_data['resources'][assoc_name]
|
|
||||||
reference = {'action': 'CREATE',
|
|
||||||
'metadata': {},
|
|
||||||
'name': 'port_2',
|
|
||||||
'resource_data': {},
|
|
||||||
'resource_id': u'port3',
|
|
||||||
'status': 'COMPLETE',
|
|
||||||
'type': 'OS::Neutron::Port'}
|
|
||||||
self.assertEqual(reference, association_data)
|
|
59
flameclient/tests/test_utils.py
Normal file
59
flameclient/tests/test_utils.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
from flameclient.tests import unittest
|
||||||
|
from flameclient import utils
|
||||||
|
|
||||||
|
|
||||||
|
class TestUtils(unittest.TestCase):
|
||||||
|
def test_camel_to_snake(self):
|
||||||
|
for inp, outp in (
|
||||||
|
('camelcase', 'camelcase'),
|
||||||
|
('Camelcase', 'camelcase'),
|
||||||
|
('camelCase', 'camel_case'),
|
||||||
|
('CamelCase', 'camel_case'),
|
||||||
|
('camelCCase', 'camel_c_case'),
|
||||||
|
('CCamelCase', 'c_camel_case'),
|
||||||
|
('CCCCamelCase', 'ccc_camel_case'),
|
||||||
|
('CCCcamelCase', 'cc_ccamel_case'),
|
||||||
|
('Camel123case', 'camel_123case'),
|
||||||
|
('Camel123Case', 'camel_123_case'),
|
||||||
|
):
|
||||||
|
self.assertEqual(utils.camel_to_snake(inp), outp)
|
||||||
|
|
||||||
|
def test_format_option(self):
|
||||||
|
for option, formated in (
|
||||||
|
('--foo-bar', 'foo_bar'),
|
||||||
|
('--this-is-a-long-option', 'this_is_a_long_option')
|
||||||
|
):
|
||||||
|
self.assertEqual(
|
||||||
|
formated, utils.format_option(option)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_format_option_kwargs(self):
|
||||||
|
self.assertEqual(
|
||||||
|
{'foo_bar': 'value'}, utils.format_option_kwargs(
|
||||||
|
{'--foo-bar': 'value'}
|
||||||
|
)
|
||||||
|
)
|
44
flameclient/tests/utils.py
Normal file
44
flameclient/tests/utils.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
import openstack
|
||||||
|
|
||||||
|
from flameclient.tests import mock
|
||||||
|
from flameclient.utils import get_deep_attr
|
||||||
|
from flameclient.utils import munchify
|
||||||
|
|
||||||
|
|
||||||
|
def get_mocked_openstackcloud():
|
||||||
|
from flameclient.tests.fixtures import openstackcloud
|
||||||
|
|
||||||
|
cloud = mock.Mock(spec_set=openstack.connection.Connection)
|
||||||
|
# for each self.conn.`fixture_module.NAME`() call we will return
|
||||||
|
# fixture_module.FIXTURES
|
||||||
|
for fixture_module in six.itervalues(openstackcloud.FIXTURES):
|
||||||
|
get_deep_attr(
|
||||||
|
cloud, fixture_module.NAME
|
||||||
|
).return_value = munchify(fixture_module.FIXTURES)
|
||||||
|
return cloud
|
363
flameclient/utils.py
Normal file
363
flameclient/utils.py
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Orange Cloud for Business / Cloudwatt
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import re
|
||||||
|
from threading import Lock
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import os
|
||||||
|
import pkgutil
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import munch
|
||||||
|
import pkg_resources
|
||||||
|
import six
|
||||||
|
|
||||||
|
from flameclient import collections_abc
|
||||||
|
|
||||||
|
|
||||||
|
CS2STR1 = re.compile('(.)([A-Z][a-z]+)')
|
||||||
|
CS2STR2 = re.compile('(.)([0-9]+)')
|
||||||
|
CS2STR3 = re.compile('([a-z0-9])([A-Z])')
|
||||||
|
REPLSTR = r'\1_\2'
|
||||||
|
|
||||||
|
|
||||||
|
def camel_to_snake(string):
|
||||||
|
"""Transform camel_case string to snake_case string"""
|
||||||
|
return CS2STR3.sub(
|
||||||
|
REPLSTR, CS2STR2.sub(REPLSTR, CS2STR1.sub(REPLSTR, string))
|
||||||
|
).lower()
|
||||||
|
|
||||||
|
|
||||||
|
def sys_path_to_module(path):
|
||||||
|
full_path = os.path.realpath(os.path.abspath(path))
|
||||||
|
path = full_path
|
||||||
|
while True:
|
||||||
|
if path in sys.path:
|
||||||
|
break
|
||||||
|
path = os.path.dirname(path)
|
||||||
|
if path == '/':
|
||||||
|
return ''
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def get_module_name_from_file(filename):
|
||||||
|
filename = os.path.realpath(os.path.abspath(filename))
|
||||||
|
sys_path = '%s/' % sys_path_to_module(filename)
|
||||||
|
package_path = filename.split(sys_path, 1)[1]
|
||||||
|
package_path = package_path.rsplit('.py', 1)[0]
|
||||||
|
return package_path.replace('/', '.')
|
||||||
|
|
||||||
|
|
||||||
|
def load_resource_modules(base_file_or_dir, exclude=tuple()):
|
||||||
|
"""Load packages in a directory
|
||||||
|
|
||||||
|
base_file_or_dir: the base file or dir where we will load packages.
|
||||||
|
prefix: the prefix to add to module names.
|
||||||
|
"""
|
||||||
|
modules = {}
|
||||||
|
if isinstance(exclude, six.string_types):
|
||||||
|
exclude = (exclude, )
|
||||||
|
full_path = os.path.realpath(os.path.abspath(base_file_or_dir))
|
||||||
|
if os.path.isdir(full_path):
|
||||||
|
pkg_dir = full_path
|
||||||
|
elif os.path.isfile(full_path):
|
||||||
|
pkg_dir = os.path.dirname(full_path)
|
||||||
|
else:
|
||||||
|
raise ImportError('Can not find "%s"' % full_path)
|
||||||
|
prefix = "%s." % get_module_name_from_file(pkg_dir)
|
||||||
|
for _, name, ispkg in pkgutil.iter_modules([pkg_dir], prefix):
|
||||||
|
# `name` has the form "foo.bar.plop"
|
||||||
|
# We do not want to load "foo.bar.test*" modules to not load unittest
|
||||||
|
# files.
|
||||||
|
# We also do not want to load files starting with an underscore.
|
||||||
|
if (
|
||||||
|
not name.split('.')[-1].startswith('test') and
|
||||||
|
not name.split('.')[-1].startswith('_') and
|
||||||
|
name not in exclude and
|
||||||
|
not ispkg
|
||||||
|
):
|
||||||
|
modules[name] = importlib.import_module(name)
|
||||||
|
return modules
|
||||||
|
|
||||||
|
|
||||||
|
def load_resource_entry_points(name='openstack_flame'):
|
||||||
|
entry_points = {}
|
||||||
|
for entry_point in pkg_resources.iter_entry_points(name):
|
||||||
|
entry_points[entry_point.name] = entry_point.load()
|
||||||
|
return entry_points
|
||||||
|
|
||||||
|
|
||||||
|
def munchify(obj, iterator_type=list, remunch=False):
|
||||||
|
"""Transforms an object into a `munch.Munch` object when possible.
|
||||||
|
|
||||||
|
The difference with `munch.munchify` is that when an object has a
|
||||||
|
`_to_munch` method, we call this method which was designed for it.
|
||||||
|
|
||||||
|
This method is useful when we have `openstack.resource.Resource` objects
|
||||||
|
because they have a `_to_munch` method.
|
||||||
|
|
||||||
|
The purpose is to have the same type of objects whether we use
|
||||||
|
`openstack.connection.Connection` methods or
|
||||||
|
`shade.openstackcloud.OpenStackCloud` specific methods.
|
||||||
|
|
||||||
|
`openstack.connection.Connection` methods return
|
||||||
|
`openstack.resource.Resource` subclasses and
|
||||||
|
`shade.openstackcloud.OpenStackCloud` methods return `munch.Munch` objects.
|
||||||
|
|
||||||
|
:param bool remunch: If True we return a deep copy of the object if it's
|
||||||
|
already a `munch.Munch` instance. By default we
|
||||||
|
return the `munch.Munch` object as is.
|
||||||
|
|
||||||
|
|
||||||
|
:param function iterator_type: If we have an iterator instead of an
|
||||||
|
iterable object we return a list by default.
|
||||||
|
You can change this behaviour by passing the
|
||||||
|
callable to the type you want (ex.: tuple).
|
||||||
|
This only affects Iterators and not
|
||||||
|
iterables for which we keep the same type.
|
||||||
|
You get an iterator when you have an
|
||||||
|
`openstack.connection.Connection` instance
|
||||||
|
and do e.g.: `conn.compute.servers()`.
|
||||||
|
So if you call
|
||||||
|
`munchify(conn.compute.servers())` you will
|
||||||
|
get the iterator_type (a list by default).
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Check
|
||||||
|
# https://docs.python.org/2/library/collections.html#collections-abstract-base-classes # noqa
|
||||||
|
# or
|
||||||
|
# https://docs.python.org/3/library/collections.abc.html#collections-abstract-base-classes # noqa
|
||||||
|
# To know in which order to test.
|
||||||
|
if not remunch and isinstance(obj, munch.Munch):
|
||||||
|
return obj
|
||||||
|
if hasattr(obj, '_to_munch'):
|
||||||
|
return obj._to_munch()
|
||||||
|
elif isinstance(obj, collections_abc.Mapping): # Test for `dict` likes.
|
||||||
|
# Mappings (dicts, OrderedDict, etc...) are iterable so it
|
||||||
|
# needs to be tested before iterable types.
|
||||||
|
return munch.Munch(
|
||||||
|
(key, munchify(value)) for key, value in six.iteritems(obj)
|
||||||
|
)
|
||||||
|
elif isinstance(obj, six.string_types):
|
||||||
|
# Strings are iterable so this needs to be tested before the
|
||||||
|
# iterable types.
|
||||||
|
return obj
|
||||||
|
elif isinstance(obj, collections_abc.Iterator):
|
||||||
|
# `Iterator` is a subclass of `Iterable` so we need to test it first.
|
||||||
|
return iterator_type(munchify(elt) for elt in obj)
|
||||||
|
elif isinstance(obj, collections_abc.Iterable):
|
||||||
|
# At last, check if we have an iterable object.
|
||||||
|
return type(obj)(munchify(elt) for elt in obj)
|
||||||
|
else:
|
||||||
|
return munch.munchify(obj)
|
||||||
|
|
||||||
|
|
||||||
|
def data_list_to_dict(data_list, enum=True):
|
||||||
|
data_dict = munch.Munch()
|
||||||
|
for num, data in enumerate(data_list):
|
||||||
|
data_dict[data.id] = munchify(data)
|
||||||
|
if enum:
|
||||||
|
data_dict[data.id].enum = num
|
||||||
|
return data_dict
|
||||||
|
|
||||||
|
|
||||||
|
def clean_dict(obj, clean_list=True, super_clean=False, iterator_type=list):
|
||||||
|
"""Returns a dict copy with only values which are not None
|
||||||
|
|
||||||
|
:param bool clean_list: whether to suppress or not None values from lists
|
||||||
|
:param bool super_clean: whether to suppress or not values which evaluate
|
||||||
|
to False (not only None).
|
||||||
|
:param function iterator_type: cast function for iterator types.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if isinstance(obj, six.string_types):
|
||||||
|
return obj
|
||||||
|
elif isinstance(obj, collections_abc.Mapping):
|
||||||
|
if super_clean:
|
||||||
|
return type(obj)(
|
||||||
|
(key, clean_dict(
|
||||||
|
value, clean_list=clean_list, super_clean=super_clean))
|
||||||
|
for key, value in six.iteritems(obj) if value
|
||||||
|
)
|
||||||
|
return type(obj)(
|
||||||
|
(key, clean_dict(
|
||||||
|
value, clean_list=clean_list, super_clean=super_clean))
|
||||||
|
for key, value in six.iteritems(obj)if value is not None
|
||||||
|
)
|
||||||
|
elif isinstance(obj, collections_abc.Iterator):
|
||||||
|
if super_clean:
|
||||||
|
return iterator_type(
|
||||||
|
clean_dict(elt, clean_list=clean_list, super_clean=super_clean)
|
||||||
|
for elt in obj if elt or not clean_list
|
||||||
|
)
|
||||||
|
return iterator_type(
|
||||||
|
clean_dict(elt, clean_list=clean_list, super_clean=super_clean)
|
||||||
|
for elt in obj if elt is not None or not clean_list
|
||||||
|
)
|
||||||
|
elif isinstance(obj, collections_abc.Iterable):
|
||||||
|
# At last, check if we have an iterable object.
|
||||||
|
if super_clean:
|
||||||
|
return type(obj)(
|
||||||
|
clean_dict(elt, clean_list=clean_list, super_clean=super_clean)
|
||||||
|
for elt in obj if elt or not clean_list
|
||||||
|
)
|
||||||
|
return type(obj)(
|
||||||
|
clean_dict(elt, clean_list=clean_list, super_clean=super_clean)
|
||||||
|
for elt in obj if elt is not None or not clean_list
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
def format_option(option_str):
|
||||||
|
option_str = option_str.lstrip('-')
|
||||||
|
option_str = option_str.replace('-', '_')
|
||||||
|
return option_str
|
||||||
|
|
||||||
|
|
||||||
|
def format_option_kwargs(kwargs):
|
||||||
|
"""Format a dictionary with option names to dict keys.
|
||||||
|
|
||||||
|
This will allow further keyword arguments passing of argparse options.
|
||||||
|
|
||||||
|
example:
|
||||||
|
change `{'--foo-bar': 'value'}` to `{'foo_bar': 'value'}` etc...
|
||||||
|
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
format_option(key): value for key, value in six.iteritems(kwargs)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def dict_to_options(kwargs):
|
||||||
|
if kwargs is not None:
|
||||||
|
if isinstance(kwargs, argparse.Namespace):
|
||||||
|
return kwargs
|
||||||
|
return argparse.Namespace(**format_option_kwargs(kwargs))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def rename_os_kwargs(kwargs, clean=False):
|
||||||
|
"""Clean Openstack kwargs from the 'os_' prefix.
|
||||||
|
|
||||||
|
envvars return 'os_username', 'os_auth_url', etc... variables.
|
||||||
|
we want to remove the 'os_' prefix
|
||||||
|
|
||||||
|
:param dict kwargs: the dictionary to clean
|
||||||
|
|
||||||
|
:param bool clean: If true, the returned dictionary will not have keys
|
||||||
|
with empty values.
|
||||||
|
|
||||||
|
"""
|
||||||
|
new_kwargs = {}
|
||||||
|
for key, value in six.iteritems(kwargs):
|
||||||
|
if value or not clean:
|
||||||
|
if key.startswith('os_'):
|
||||||
|
new_kwargs[key.split('os_')[1]] = value
|
||||||
|
else:
|
||||||
|
new_kwargs[key] = value
|
||||||
|
return new_kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def rename_os_options(options, clean=False):
|
||||||
|
"""Clean Openstack envvars from the 'os_' prefix.
|
||||||
|
|
||||||
|
envvars return 'os_username', 'os_auth_url', etc... variables.
|
||||||
|
we want to remove the 'os_' prefix
|
||||||
|
|
||||||
|
:param argparse.Namespace options: the options to clean
|
||||||
|
|
||||||
|
:param bool clean: If true, the returned options will not have
|
||||||
|
attributes with empty values.
|
||||||
|
"""
|
||||||
|
kwargs = vars(options)
|
||||||
|
renamed_kwargs = rename_os_kwargs(kwargs, clean=clean)
|
||||||
|
return argparse.Namespace(**renamed_kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def hash_func_call(func, *args, **kwargs):
|
||||||
|
"""hash a function call"""
|
||||||
|
# kwargs is a dict, and dicts are not hashable.
|
||||||
|
kwargs_tuple = tuple((key, value) for key, value in six.iteritems(kwargs))
|
||||||
|
return hash((func, args, kwargs_tuple))
|
||||||
|
|
||||||
|
|
||||||
|
def get_deep_attr(obj, value):
|
||||||
|
"""Get deep attribute
|
||||||
|
|
||||||
|
example, `getattr(some_object, 'attr.subattr')` does not work.
|
||||||
|
With get_deep_attr it works.
|
||||||
|
|
||||||
|
"""
|
||||||
|
subelts = value.split('.', 1)
|
||||||
|
if len(subelts) == 1:
|
||||||
|
return getattr(obj, value)
|
||||||
|
else:
|
||||||
|
return get_deep_attr(getattr(obj, subelts[0]), subelts[1])
|
||||||
|
|
||||||
|
|
||||||
|
def memoized_property(func):
|
||||||
|
"""Decorator to set properties which will be computed only once
|
||||||
|
|
||||||
|
"""
|
||||||
|
attr_name = '__%s' % func.__name__
|
||||||
|
lock = Lock()
|
||||||
|
|
||||||
|
class FixedProperty(object):
|
||||||
|
def __get__(self, instance, owner):
|
||||||
|
if instance:
|
||||||
|
with lock:
|
||||||
|
try:
|
||||||
|
return getattr(instance, attr_name)
|
||||||
|
except AttributeError:
|
||||||
|
result = func(instance)
|
||||||
|
setattr(instance, attr_name, result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __set__(self, instance, value):
|
||||||
|
with lock:
|
||||||
|
setattr(instance, attr_name, value)
|
||||||
|
|
||||||
|
def __delete__(self, instance):
|
||||||
|
with lock:
|
||||||
|
delattr(instance, attr_name)
|
||||||
|
|
||||||
|
return FixedProperty()
|
||||||
|
|
||||||
|
|
||||||
|
class ClassProperty(classmethod):
|
||||||
|
|
||||||
|
def __get__(self, instance, owner):
|
||||||
|
return self.__func__(owner)
|
||||||
|
|
||||||
|
def __set__(self, instance, value):
|
||||||
|
setattr(instance, self.__func__.__name__, value)
|
||||||
|
|
||||||
|
def __delete__(self, instance):
|
||||||
|
delattr(instance, self.__func__)
|
110
pylintrc
Normal file
110
pylintrc
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
[MASTER]
|
||||||
|
profile=no
|
||||||
|
persistent=yes
|
||||||
|
ignore=migrations
|
||||||
|
|
||||||
|
|
||||||
|
[MESSAGES CONTROL]
|
||||||
|
# C0103 Invalid %s name "%s"
|
||||||
|
# C0111 Missing docstring
|
||||||
|
# C0302 Too many lines in module
|
||||||
|
# C0330 Wrong hanging indentation before block (We let pep8 check this)
|
||||||
|
# E0611 No name %r in module %r
|
||||||
|
# E1101 %s %r has no %r member
|
||||||
|
# E1102 %s is not callable
|
||||||
|
# E1133 Non-iterable value %s is used in an iterating context # (caused by flameclient.utils.memoized_property)
|
||||||
|
# E1135 Value '%s' doesn't support membership test # (caused by flameclient.utils.memoized_property)
|
||||||
|
# E1136 %s is unsubscriptable # (caused by flameclient.utils.fixed_property)
|
||||||
|
# F0401 Unable to import %s
|
||||||
|
# I0011 Warning locally suppressed using disable-msg
|
||||||
|
# I0012 Warning locally suppressed using disable-msg
|
||||||
|
# R0123 Comparison to literal
|
||||||
|
# R0201 Method could be a function
|
||||||
|
# R0901 Too many ancestors
|
||||||
|
# R0902 Too many instance attributes
|
||||||
|
# R0904 Too many public methods
|
||||||
|
# R0911 Too many return statements
|
||||||
|
# R0912 Too many branches
|
||||||
|
# R0914 Too many local variables
|
||||||
|
# R0915 Too many statements
|
||||||
|
# R1705 Unnecessary "else" after "return"
|
||||||
|
# R1710 inconsistent-return-statements
|
||||||
|
# W0142 Used * or * magic* Used when a function or method is called using *args or **kwargs to dispatch arguments.
|
||||||
|
# W0212 Access to a protected member %s of a client class
|
||||||
|
# W0223 Method %r is abstract in class %r but is not overridden
|
||||||
|
# W0232 Class has no __init__ method Used when a class has no __init__ method, neither its parent classes.
|
||||||
|
# W0403 Relative import '%s', should be '%s'
|
||||||
|
# W0511 Used when a warning note as FIXME or XXX is detected.
|
||||||
|
# W0613 Unused argument %r Used when a function or method argument is not used.
|
||||||
|
# W0702 No exception's type specified Used when an except clause doesn't specify exceptions type to catch.
|
||||||
|
# W0704 Except doesn't do anything Used when an except clause does nothing but "pass" and there is no "else" clause
|
||||||
|
# W1113 keyword-arg-before-vararg
|
||||||
|
# example:
|
||||||
|
# disable=C0111,I0011,I0012,R0201,W0142,W0212,W0232,W0613,W0702,W0704
|
||||||
|
# or:
|
||||||
|
# disable=I0011,I0012,W0142,W0212,W0232
|
||||||
|
disable=C0103,C0111,C0302,C0330,E0611,E1101,E1102,E1133,E1135,E1136,I0011,I0012,R0123,R0901,R0902,R0904,R0911,R0912,R0914,R0915,R1705,R1710,W0142,W0212,W0223,W0403,W0511,W0613,W0702,W0704,W1113
|
||||||
|
|
||||||
|
|
||||||
|
[REPORTS]
|
||||||
|
include-ids=yes
|
||||||
|
output-format=parseable
|
||||||
|
#reports=yes
|
||||||
|
|
||||||
|
|
||||||
|
[BASIC]
|
||||||
|
#no-docstring-rgx=__.*__|_.*
|
||||||
|
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__)|logger|register|urlpatterns)$
|
||||||
|
method-rgx=([a-z_][a-z0-9_]{2,30}|setUp|tearDown|test_[a-z0-9_]{2,60}|assert[a-zA-Z0-9]{2,30})$
|
||||||
|
#good-names=_,i,j,k,e,v,db,qs,pk
|
||||||
|
good-names=_,i,j,k,e,v,by,fp,td,tr
|
||||||
|
|
||||||
|
|
||||||
|
[TYPECHECK]
|
||||||
|
ignore-mixin-members=yes
|
||||||
|
#ignored-classes=SQLObject,WSGIRequest
|
||||||
|
#zope=no
|
||||||
|
#generated-members=objects,DoesNotExist,id,pk,_meta,base_fields,context
|
||||||
|
|
||||||
|
|
||||||
|
[VARIABLES]
|
||||||
|
#init-import=no
|
||||||
|
#dummy-variables-rgx=_|dummy
|
||||||
|
#additional-builtins=
|
||||||
|
|
||||||
|
|
||||||
|
[SIMILARITIES]
|
||||||
|
min-similarity-lines=6
|
||||||
|
#ignore-comments=yes
|
||||||
|
#ignore-docstrings=yes
|
||||||
|
ignore-imports=yes
|
||||||
|
|
||||||
|
|
||||||
|
[MISCELLANEOUS]
|
||||||
|
notes=FIXME,XXX,TODO
|
||||||
|
|
||||||
|
|
||||||
|
[FORMAT]
|
||||||
|
max-line-length=1000
|
||||||
|
max-module-lines=500
|
||||||
|
indent-string=' '
|
||||||
|
|
||||||
|
|
||||||
|
[CLASSES]
|
||||||
|
#defining-attr-methods=__init__,__new__,setUp
|
||||||
|
|
||||||
|
|
||||||
|
[DESIGN]
|
||||||
|
max-args=10
|
||||||
|
max-locals=15
|
||||||
|
max-returns=6
|
||||||
|
max-branchs=12
|
||||||
|
max-statements=50
|
||||||
|
max-parents=7
|
||||||
|
max-attributes=7
|
||||||
|
min-public-methods=0
|
||||||
|
max-public-methods=50
|
||||||
|
|
||||||
|
|
||||||
|
[IMPORTS]
|
||||||
|
#deprecated-modules=regsub,TERMIOS,Bastion,rexec
|
@ -1,10 +1,20 @@
|
|||||||
pbr>=1.6
|
certifi==2018.8.24
|
||||||
Babel>=1.3
|
futures>=3.1.1,<=3.2.0
|
||||||
futures
|
keystoneauth1==3.11.0
|
||||||
|
ndg-httpsclient==0.5.1
|
||||||
netaddr>=0.7.12,!=0.7.16
|
netaddr==0.7.19
|
||||||
python-keystoneclient
|
openstacksdk==0.17.2
|
||||||
python-neutronclient
|
os-client-config==1.31.2
|
||||||
python-novaclient
|
pbr==4.2.0
|
||||||
python-cinderclient
|
pyasn1==0.4.4
|
||||||
PyYAML
|
pyOpenSSL==18.0.0
|
||||||
|
python-cinderclient==4.0.1
|
||||||
|
python-glanceclient==2.12.1
|
||||||
|
python-heatclient==1.16.1
|
||||||
|
python-keystoneclient==3.17.0
|
||||||
|
python-neutronclient==6.10.0
|
||||||
|
python-novaclient==11.0.0
|
||||||
|
python-openstackclient==3.16.1
|
||||||
|
python-swiftclient==3.6.0
|
||||||
|
PyYAML==3.13
|
||||||
|
shade==1.29.0
|
||||||
|
@ -3,7 +3,7 @@ name = python-flameclient
|
|||||||
summary = Automatic Heat template generation
|
summary = Automatic Heat template generation
|
||||||
description-file =
|
description-file =
|
||||||
README.rst
|
README.rst
|
||||||
author = CloudWatt
|
author = Orange Cloud for Business / CloudWatt
|
||||||
author-email = info@cloudwatt.com
|
author-email = info@cloudwatt.com
|
||||||
home-page = http://www.cloudwatt.com/
|
home-page = http://www.cloudwatt.com/
|
||||||
classifier =
|
classifier =
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
hacking>=0.10.2,<0.11
|
coverage==4.5.1
|
||||||
|
discover==0.4.0
|
||||||
futures
|
fixtures==3.0.0
|
||||||
coverage>=3.6
|
hacking==1.1.0
|
||||||
discover
|
mccabe<0.6,>=0.2.1
|
||||||
mock>=1.2
|
mock==2.0.0
|
||||||
fixtures>=1.3.1
|
oslosphinx==4.18.0
|
||||||
python-subunit
|
os-testr==1.0.0
|
||||||
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
|
pycodestyle==2.0.0
|
||||||
oslosphinx
|
pylint==1.9.3
|
||||||
testrepository>=0.0.18
|
python-subunit==1.3.0
|
||||||
testscenarios>=0.4
|
sphinx==1.8.0
|
||||||
testtools>=1.4.0
|
stestr==2.1.1
|
||||||
|
testrepository==0.0.20
|
||||||
|
testscenarios==0.5.0
|
||||||
|
testtools==2.3.0
|
||||||
|
tox==3.4.0
|
||||||
|
11
tox.ini
11
tox.ini
@ -1,11 +1,11 @@
|
|||||||
[tox]
|
[tox]
|
||||||
minversion = 1.6
|
minversion = 1.6
|
||||||
envlist = py33,py27,pypy,pep8
|
envlist = py37,py36,py35,py34,py27,pypy,pep8,pylint
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
usedevelop = True
|
usedevelop = True
|
||||||
install_command = pip install -U {opts} {packages}
|
install_command = pip install -c {toxinidir}/upper-constraints.txt -U {opts} {packages}
|
||||||
setenv =
|
setenv =
|
||||||
VIRTUAL_ENV={envdir}
|
VIRTUAL_ENV={envdir}
|
||||||
deps = -r{toxinidir}/requirements.txt
|
deps = -r{toxinidir}/requirements.txt
|
||||||
@ -13,7 +13,10 @@ deps = -r{toxinidir}/requirements.txt
|
|||||||
commands = python setup.py testr --slowest --testr-args='{posargs}'
|
commands = python setup.py testr --slowest --testr-args='{posargs}'
|
||||||
|
|
||||||
[testenv:pep8]
|
[testenv:pep8]
|
||||||
commands = flake8
|
commands = python -m flake8 flameclient
|
||||||
|
|
||||||
|
[testenv:pylint]
|
||||||
|
commands = python -m pylint --rcfile=pylintrc --reports=yes flameclient
|
||||||
|
|
||||||
[testenv:venv]
|
[testenv:venv]
|
||||||
commands = {posargs}
|
commands = {posargs}
|
||||||
@ -30,4 +33,4 @@ commands = python setup.py build_sphinx
|
|||||||
show-source = True
|
show-source = True
|
||||||
ignore = H803
|
ignore = H803
|
||||||
builtins = _
|
builtins = _
|
||||||
exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build
|
exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,flameclient/tests/fixtures/openstackcloud/*
|
||||||
|
552
upper-constraints.txt
Normal file
552
upper-constraints.txt
Normal file
@ -0,0 +1,552 @@
|
|||||||
|
ntlm-auth===1.2.0
|
||||||
|
voluptuous===0.11.5
|
||||||
|
chardet===3.0.4
|
||||||
|
rsa===3.4.2
|
||||||
|
restructuredtext-lint===1.1.3
|
||||||
|
netmiko===2.2.2
|
||||||
|
instack-undercloud===9.3.0
|
||||||
|
PasteDeploy===1.5.2
|
||||||
|
typing===3.6.6
|
||||||
|
python-saharaclient===2.0.0
|
||||||
|
python-hnvclient===0.1.0
|
||||||
|
Routes===2.4.1
|
||||||
|
rtslib-fb===2.1.66
|
||||||
|
XStatic-Angular-Bootstrap===2.2.0.0
|
||||||
|
paunch===3.2.0
|
||||||
|
WebOb===1.8.2
|
||||||
|
sphinxcontrib-actdiag===0.8.5
|
||||||
|
docopt===0.6.2
|
||||||
|
pecan===1.3.2
|
||||||
|
ryu===4.27
|
||||||
|
os-api-ref===1.5.0
|
||||||
|
python-ldap===3.1.0
|
||||||
|
oslo.concurrency===3.27.0
|
||||||
|
websocket-client===0.53.0
|
||||||
|
osprofiler===2.3.0
|
||||||
|
tabulate===0.8.2
|
||||||
|
python-ironic-inspector-client===3.3.0
|
||||||
|
lxml===4.2.5
|
||||||
|
python-kingbirdclient===0.2.1
|
||||||
|
setproctitle===1.1.10
|
||||||
|
pytest===3.8.0
|
||||||
|
python-etcd===0.4.5
|
||||||
|
raven===6.9.0
|
||||||
|
cursive===0.2.2
|
||||||
|
oslo.service===1.32.0
|
||||||
|
django-appconf===1.0.2
|
||||||
|
pykerberos===1.2.1
|
||||||
|
certifi===2018.8.24
|
||||||
|
sphinxcontrib-nwdiag===0.9.5
|
||||||
|
requests-aws===0.1.8
|
||||||
|
alabaster===0.7.11
|
||||||
|
pbr===4.2.0
|
||||||
|
munch===2.3.2
|
||||||
|
attrs===18.2.0
|
||||||
|
microversion-parse===0.2.1
|
||||||
|
Pint===0.8.1
|
||||||
|
oslo.i18n===3.21.0
|
||||||
|
jsonpath-rw-ext===1.1.3
|
||||||
|
python-mistralclient===3.7.0
|
||||||
|
oslo.context===2.21.0
|
||||||
|
python-senlinclient===1.8.0
|
||||||
|
rcssmin===1.0.6
|
||||||
|
pycadf===2.8.0
|
||||||
|
grpcio===1.15.0
|
||||||
|
skydive-client===0.4.5
|
||||||
|
pysendfile===2.0.1
|
||||||
|
fixtures===3.0.0
|
||||||
|
neutron-lib===1.18.0
|
||||||
|
XStatic-FileSaver===1.3.2.0
|
||||||
|
pystache===0.5.4
|
||||||
|
XStatic-Font-Awesome===4.7.0.0
|
||||||
|
nose===1.3.7
|
||||||
|
nosehtmloutput===0.0.5
|
||||||
|
waitress===1.1.0
|
||||||
|
os-refresh-config===9.1.0
|
||||||
|
pysnmp===4.4.6
|
||||||
|
sphinxcontrib-websupport===1.1.0
|
||||||
|
Mako===1.0.7
|
||||||
|
XStatic-angular-ui-router===0.3.1.2
|
||||||
|
pyScss===1.3.4
|
||||||
|
XStatic-jQuery===1.10.2.1
|
||||||
|
jsonmodels===2.3
|
||||||
|
ddt===1.2.0
|
||||||
|
pyserial===3.4
|
||||||
|
ipaddress===1.0.22;python_version=='2.7'
|
||||||
|
python-freezerclient===1.7.0
|
||||||
|
os-xenapi===0.3.4
|
||||||
|
python-vitrageclient===2.3.0
|
||||||
|
nosexcover===1.0.11
|
||||||
|
krest===1.3.1
|
||||||
|
psycopg2===2.7.5
|
||||||
|
networkx===2.1
|
||||||
|
bashate===0.6.0
|
||||||
|
XStatic-Angular===1.5.8.0
|
||||||
|
pyngus===2.2.4
|
||||||
|
Pillow===5.2.0
|
||||||
|
zuul-sphinx===0.2.5
|
||||||
|
python-mimeparse===1.6.0
|
||||||
|
tripleo-common===9.3.0
|
||||||
|
Tempita===0.5.2
|
||||||
|
ply===3.11
|
||||||
|
requests-toolbelt===0.8.0
|
||||||
|
simplejson===3.16.0
|
||||||
|
suds-jurko===0.6
|
||||||
|
python-swiftclient===3.6.0
|
||||||
|
pyOpenSSL===18.0.0
|
||||||
|
monasca-common===2.11.0
|
||||||
|
scipy===1.1.0
|
||||||
|
rsd-lib===0.2.2
|
||||||
|
XStatic-Jasmine===2.4.1.1
|
||||||
|
python-glanceclient===2.12.1
|
||||||
|
pyinotify===0.9.6
|
||||||
|
debtcollector===1.20.0
|
||||||
|
requests-unixsocket===0.1.5
|
||||||
|
asn1crypto===0.24.0
|
||||||
|
croniter===0.3.25
|
||||||
|
python-watcherclient===2.1.0
|
||||||
|
MarkupSafe===1.0
|
||||||
|
pypowervm===1.1.18
|
||||||
|
doc8===0.8.0
|
||||||
|
pymongo===3.7.1
|
||||||
|
sqlparse===0.2.4
|
||||||
|
oslotest===3.6.0
|
||||||
|
jsonpointer===2.0
|
||||||
|
defusedxml===0.5.0
|
||||||
|
netaddr===0.7.19
|
||||||
|
pyghmi===1.2.14
|
||||||
|
sphinxcontrib-blockdiag===1.5.5
|
||||||
|
thrift===0.11.0
|
||||||
|
gnocchiclient===7.0.5
|
||||||
|
wcwidth===0.1.7
|
||||||
|
sphinxcontrib.datatemplates===0.1.0
|
||||||
|
jsonpath-rw===1.4.0
|
||||||
|
prettytable===0.7.2
|
||||||
|
vine===1.1.4
|
||||||
|
taskflow===3.2.0
|
||||||
|
traceback2===1.4.0
|
||||||
|
semantic-version===2.6.0
|
||||||
|
virtualbmc===1.4.0
|
||||||
|
deprecation===2.0.5
|
||||||
|
SQLAlchemy===1.2.11
|
||||||
|
pyroute2===0.5.2
|
||||||
|
google-auth===1.5.1
|
||||||
|
kazoo===2.5.0
|
||||||
|
XStatic-roboto-fontface===0.5.0.0
|
||||||
|
pyudev===0.21.0
|
||||||
|
eventlet===0.24.1
|
||||||
|
openstack-doc-tools===1.8.0
|
||||||
|
frozendict===1.2
|
||||||
|
oslo.messaging===8.1.0
|
||||||
|
jira===2.0.0
|
||||||
|
extras===1.0.0
|
||||||
|
PyJWT===1.6.4
|
||||||
|
zVMCloudConnector===1.2.4
|
||||||
|
paramiko===2.4.1
|
||||||
|
reno===2.11.0
|
||||||
|
unicodecsv===0.14.1;python_version=='2.7'
|
||||||
|
imagesize===1.1.0
|
||||||
|
pydot===1.2.4
|
||||||
|
pathlib===1.0.1;python_version=='2.7'
|
||||||
|
urllib3===1.23
|
||||||
|
graphviz===0.9
|
||||||
|
PyKMIP===0.8.0
|
||||||
|
whereto===0.4.0
|
||||||
|
python-subunit===1.3.0
|
||||||
|
tornado===4.5.3
|
||||||
|
pycparser===2.18
|
||||||
|
mock===2.0.0
|
||||||
|
PyYAML===3.13
|
||||||
|
beautifulsoup4===4.6.3
|
||||||
|
os-net-config===9.2.0
|
||||||
|
ovs===2.9.2
|
||||||
|
cryptography===2.3.1
|
||||||
|
adal===1.1.0
|
||||||
|
backports.ssl-match-hostname===3.5.0.1;python_version=='2.7'
|
||||||
|
openstack-release-test===1.1.0
|
||||||
|
pylxd===2.2.7
|
||||||
|
ruamel.ordereddict===0.4.13;python_version=='2.7'
|
||||||
|
pycryptodomex===3.6.6
|
||||||
|
anyjson===0.3.3
|
||||||
|
requests-mock===1.5.2
|
||||||
|
os-apply-config===9.1.0
|
||||||
|
oslosphinx===4.18.0
|
||||||
|
mox3===0.26.0
|
||||||
|
gunicorn===19.9.0
|
||||||
|
textfsm===0.4.1
|
||||||
|
unittest2===1.1.0
|
||||||
|
django-compressor===2.2
|
||||||
|
libvirt-python===4.6.0
|
||||||
|
python-zunclient===2.1.0
|
||||||
|
asyncio===3.4.3;python_version=='3.4'
|
||||||
|
asyncio===3.4.3;python_version=='3.5'
|
||||||
|
asyncio===3.4.3;python_version=='3.6'
|
||||||
|
tzlocal===1.5.1
|
||||||
|
python-novaclient===11.0.0
|
||||||
|
bcrypt===3.1.4
|
||||||
|
fixtures-git===0.1.0
|
||||||
|
os-client-config===1.31.2
|
||||||
|
XStatic-Angular-Gettext===2.3.8.0
|
||||||
|
XStatic-Hogan===2.0.0.2
|
||||||
|
XStatic-objectpath===1.2.1.0
|
||||||
|
python-manilaclient===1.24.1
|
||||||
|
requests===2.19.1
|
||||||
|
snowballstemmer===1.2.1
|
||||||
|
Jinja2===2.10
|
||||||
|
XStatic-Bootstrap-SCSS===3.3.7.1
|
||||||
|
pyzabbix===0.7.4
|
||||||
|
ptyprocess===0.6.0
|
||||||
|
threadloop===1.0.2
|
||||||
|
amqp===2.3.2
|
||||||
|
ruamel.yaml===0.15.66
|
||||||
|
websockify===0.8.0
|
||||||
|
XStatic-JQuery.quicksearch===2.0.3.1
|
||||||
|
mpmath===1.0.0
|
||||||
|
django-debreach===1.5.2
|
||||||
|
sphinx-feature-classification===0.3.0
|
||||||
|
XStatic-JQuery-Migrate===1.2.1.1
|
||||||
|
appdirs===1.4.3
|
||||||
|
tinyrpc===0.9.3
|
||||||
|
google-auth-httplib2===0.0.3
|
||||||
|
Flask-SQLAlchemy===2.3.2
|
||||||
|
daiquiri===1.5.0
|
||||||
|
influxdb===5.1.0
|
||||||
|
funcparserlib===0.3.6
|
||||||
|
passlib===1.7.1
|
||||||
|
dib-utils===0.0.11
|
||||||
|
cliff===2.13.0
|
||||||
|
os-brick===2.5.3
|
||||||
|
ansible-runner===1.1.1
|
||||||
|
trollius===2.2;python_version=='2.7'
|
||||||
|
scp===0.11.0
|
||||||
|
python-zaqarclient===1.10.0
|
||||||
|
funcsigs===1.0.2;python_version=='2.7'
|
||||||
|
zhmcclient===0.19.0
|
||||||
|
lockfile===0.12.2
|
||||||
|
dnspython3===1.15.0;python_version=='3.4'
|
||||||
|
dnspython3===1.15.0;python_version=='3.5'
|
||||||
|
dnspython3===1.15.0;python_version=='3.6'
|
||||||
|
ldappool===2.3.0
|
||||||
|
termcolor===1.1.0
|
||||||
|
hiredis===0.2.0
|
||||||
|
google-api-python-client===1.7.4
|
||||||
|
castellan===0.19.0
|
||||||
|
oslo.versionedobjects===1.33.3
|
||||||
|
webcolors===1.8.1
|
||||||
|
aodhclient===1.1.1
|
||||||
|
autobahn===18.9.2
|
||||||
|
SQLAlchemy-Utils===0.33.4
|
||||||
|
pluggy===0.7.1
|
||||||
|
coverage===4.5.1
|
||||||
|
freezegun===0.3.10
|
||||||
|
python-pytun===2.2.1
|
||||||
|
pyperclip===1.6.4
|
||||||
|
cassandra-driver===3.15.1
|
||||||
|
mox===0.5.3
|
||||||
|
XStatic-Angular-Schema-Form===0.8.13.0
|
||||||
|
gabbi===1.44.0
|
||||||
|
nwdiag===1.0.4
|
||||||
|
XStatic-bootswatch===3.3.7.0
|
||||||
|
XStatic-JS-Yaml===3.8.1.0
|
||||||
|
XStatic-term.js===0.0.7.0
|
||||||
|
oslo.log===3.39.0
|
||||||
|
nodeenv===1.3.2
|
||||||
|
pylev===1.3.0
|
||||||
|
python-searchlightclient===1.3.0
|
||||||
|
oslo.middleware===3.36.0
|
||||||
|
XStatic-mdi===1.4.57.0
|
||||||
|
django-pyscss===2.0.2
|
||||||
|
uritemplate===3.0.0
|
||||||
|
django-babel===0.6.2
|
||||||
|
docutils===0.14
|
||||||
|
notifier===1.0.3
|
||||||
|
ujson===1.35
|
||||||
|
selenium===3.14.0
|
||||||
|
python-glareclient===0.5.3
|
||||||
|
mypy===0.620;python_version=='3.4'
|
||||||
|
mypy===0.620;python_version=='3.5'
|
||||||
|
mypy===0.620;python_version=='3.6'
|
||||||
|
mistral-lib===1.0.0
|
||||||
|
dogtag-pki===10.3.5.1
|
||||||
|
XStatic-Angular-UUID===0.0.4.0
|
||||||
|
sphinxcontrib-seqdiag===0.8.5
|
||||||
|
os-win===4.0.1
|
||||||
|
dictdiffer===0.7.1
|
||||||
|
retrying===1.3.3
|
||||||
|
shade===1.29.0
|
||||||
|
pathlib2===2.3.2
|
||||||
|
pydotplus===2.0.2
|
||||||
|
flask-oslolog===0.1
|
||||||
|
jeepney===0.3.1;python_version=='3.4'
|
||||||
|
jeepney===0.3.1;python_version=='3.5'
|
||||||
|
jeepney===0.3.1;python_version=='3.6'
|
||||||
|
stestr===2.1.1
|
||||||
|
singledispatch===3.4.0.3;python_version=='2.7'
|
||||||
|
oslo.serialization===2.27.0
|
||||||
|
warlock===1.3.0
|
||||||
|
exabgp===4.0.8
|
||||||
|
sphinxcontrib-httpdomain===1.7.0
|
||||||
|
metalsmith===0.7.0
|
||||||
|
thriftpy===0.3.9;python_version=='2.7'
|
||||||
|
text-unidecode===1.2
|
||||||
|
murano-pkg-check===0.3.0
|
||||||
|
oslo.vmware===2.31.0
|
||||||
|
sqlalchemy-migrate===0.11.0
|
||||||
|
python-monascaclient===1.12.1
|
||||||
|
ldap3===2.5.1
|
||||||
|
requests-ntlm===1.1.0
|
||||||
|
python-string-utils===0.6.0
|
||||||
|
automaton===1.15.0
|
||||||
|
os-service-types===1.3.0
|
||||||
|
keyring===15.1.0
|
||||||
|
testscenarios===0.5.0
|
||||||
|
sphinxcontrib-pecanwsme===0.9.0
|
||||||
|
sadisplay===0.4.9
|
||||||
|
enum34===1.1.6
|
||||||
|
packaging===17.1
|
||||||
|
flask-keystone===0.2
|
||||||
|
nose-exclude===0.5.0
|
||||||
|
psutil===5.4.7
|
||||||
|
py===1.6.0
|
||||||
|
txaio===18.8.1
|
||||||
|
python-qinlingclient===2.0.0
|
||||||
|
elasticsearch===2.4.1
|
||||||
|
django-nose===1.4.5
|
||||||
|
XStatic-JQuery.TableSorter===2.14.5.1
|
||||||
|
pifpaf===2.1.1
|
||||||
|
pysmi===0.3.1
|
||||||
|
blockdiag===1.5.4
|
||||||
|
testtools===2.3.0
|
||||||
|
Parsley===1.3
|
||||||
|
XStatic-tv4===1.2.7.0
|
||||||
|
XStatic-JSEncrypt===2.3.1.1
|
||||||
|
python-cinderclient===4.0.1
|
||||||
|
keystonemiddleware===5.2.0
|
||||||
|
django-formtools===2.1
|
||||||
|
python-ceilometerclient===2.9.0
|
||||||
|
XStatic-Spin===1.2.5.2
|
||||||
|
openshift===0.7.1
|
||||||
|
tap-as-a-service===3.0.0
|
||||||
|
os-traits===0.9.0
|
||||||
|
SecretStorage===2.3.1;python_version=='2.7'
|
||||||
|
SecretStorage===3.1.0;python_version=='3.4'
|
||||||
|
SecretStorage===3.1.0;python_version=='3.5'
|
||||||
|
SecretStorage===3.1.0;python_version=='3.6'
|
||||||
|
opentracing===1.3.0
|
||||||
|
XStatic-Rickshaw===1.5.0.0
|
||||||
|
iso8601===0.1.12
|
||||||
|
tooz===1.62.0
|
||||||
|
linecache2===1.0.0
|
||||||
|
oauth2client===4.1.3
|
||||||
|
idna===2.7
|
||||||
|
python-karborclient===1.1.0
|
||||||
|
weakrefmethod===1.0.3;python_version=='2.7'
|
||||||
|
PuLP===1.6.8
|
||||||
|
crc16===0.1.1
|
||||||
|
protobuf===3.6.1
|
||||||
|
os-dpm===1.1.0
|
||||||
|
sushy===1.6.0
|
||||||
|
python-neutronclient===6.10.0
|
||||||
|
pika===0.12.0
|
||||||
|
oslo.cache===1.30.1
|
||||||
|
WebTest===2.0.30
|
||||||
|
openstack.nose-plugin===0.11
|
||||||
|
os-collect-config===9.2.0
|
||||||
|
python-qpid-proton===0.23.0
|
||||||
|
python-octaviaclient===1.6.0
|
||||||
|
pysaml2===4.6.2
|
||||||
|
requests-oauthlib===1.0.0
|
||||||
|
oslo.reports===1.28.0
|
||||||
|
ceilometermiddleware===1.3.0
|
||||||
|
python-nss===1.0.1
|
||||||
|
testrepository===0.0.20
|
||||||
|
sympy===1.3
|
||||||
|
sphinxmark===0.1.19
|
||||||
|
PyNaCl===1.2.1
|
||||||
|
osc-lib===1.11.1
|
||||||
|
python-consul===1.1.0
|
||||||
|
Faker===0.9.1
|
||||||
|
more-itertools===4.3.0
|
||||||
|
seqdiag===0.9.6
|
||||||
|
numpy===1.15.1
|
||||||
|
msgpack===0.5.6
|
||||||
|
Sphinx===1.8.0
|
||||||
|
oslo.config===6.4.0
|
||||||
|
tempest===19.0.0
|
||||||
|
django-floppyforms===1.7.0
|
||||||
|
openstackdocstheme===1.23.2
|
||||||
|
osc-placement===1.3.0
|
||||||
|
zake===0.2.2
|
||||||
|
python-rsdclient===0.1.3
|
||||||
|
python-magic===0.4.15
|
||||||
|
python-solumclient===2.7.1
|
||||||
|
PyMySQL===0.9.2
|
||||||
|
kubernetes===7.0.0
|
||||||
|
httplib2===0.11.3
|
||||||
|
bottle===0.12.13
|
||||||
|
betamax===0.8.1
|
||||||
|
construct===2.8.22
|
||||||
|
pyparsing===2.2.0
|
||||||
|
dogpile.cache===0.6.7
|
||||||
|
python-barbicanclient===4.7.0
|
||||||
|
tricircleclient===0.4.0
|
||||||
|
WSME===0.9.3
|
||||||
|
proboscis===1.2.6.0
|
||||||
|
fortiosclient===0.0.3
|
||||||
|
stevedore===1.29.0
|
||||||
|
botocore===1.12.4
|
||||||
|
xmltodict===0.11.0
|
||||||
|
pyasn1===0.4.4
|
||||||
|
oslo.rootwrap===5.14.1
|
||||||
|
Django===1.11.15;python_version=='2.7'
|
||||||
|
Django===2.0.8;python_version=='3.4'
|
||||||
|
Django===2.0.8;python_version=='3.5'
|
||||||
|
Django===2.0.8;python_version=='3.6'
|
||||||
|
pexpect===4.6.0
|
||||||
|
cmd2===0.8.9;python_version=='2.7'
|
||||||
|
cmd2===0.9.4;python_version=='3.4'
|
||||||
|
cmd2===0.9.4;python_version=='3.5'
|
||||||
|
cmd2===0.9.4;python_version=='3.6'
|
||||||
|
redis===2.10.6
|
||||||
|
jmespath===0.9.3
|
||||||
|
click===6.7
|
||||||
|
atomicwrites===1.2.1
|
||||||
|
docker-pycreds===0.3.0
|
||||||
|
XStatic-smart-table===1.4.13.2
|
||||||
|
kuryr-lib===0.8.0
|
||||||
|
scrypt===0.8.6
|
||||||
|
jsonpatch===1.23
|
||||||
|
python-daemon===2.2.0
|
||||||
|
typed-ast===1.1.0;python_version=='3.4'
|
||||||
|
typed-ast===1.1.0;python_version=='3.5'
|
||||||
|
typed-ast===1.1.0;python_version=='3.6'
|
||||||
|
os-testr===1.0.0
|
||||||
|
cotyledon===1.7.1
|
||||||
|
stomp.py===4.1.21
|
||||||
|
xattr===0.9.6
|
||||||
|
systemd-python===234
|
||||||
|
python-memcached===1.59
|
||||||
|
openstacksdk===0.17.2
|
||||||
|
six===1.11.0
|
||||||
|
dulwich===0.19.6
|
||||||
|
pykafka===2.7.0
|
||||||
|
kombu===4.2.1
|
||||||
|
distro===1.3.0
|
||||||
|
betamax-matchers===0.4.0
|
||||||
|
yaql===1.1.3
|
||||||
|
requestsexceptions===1.4.0
|
||||||
|
testresources===2.0.1
|
||||||
|
falcon===1.4.1
|
||||||
|
subprocess32===3.5.2;python_version=='2.7'
|
||||||
|
etcd3gw===0.2.4
|
||||||
|
Flask-RESTful===0.3.6
|
||||||
|
GitPython===2.1.11
|
||||||
|
python-ironicclient===2.5.0
|
||||||
|
XStatic===1.0.1
|
||||||
|
XStatic-Angular-FileUpload===12.0.4.0
|
||||||
|
python-openstackclient===3.16.1
|
||||||
|
pyzmq===17.1.2
|
||||||
|
oslo.db===4.40.0
|
||||||
|
simplegeneric===0.8.1
|
||||||
|
python-pcre===0.7
|
||||||
|
abclient===0.2.3
|
||||||
|
pymemcache===2.0.0
|
||||||
|
wrapt===1.10.11
|
||||||
|
oslo.privsep===1.29.0
|
||||||
|
sphinxcontrib-apidoc===0.2.1
|
||||||
|
oslo.policy===1.38.1
|
||||||
|
python-muranoclient===1.1.1
|
||||||
|
pyeclib===1.5.0
|
||||||
|
wsgi-intercept===1.8.0
|
||||||
|
ndg-httpsclient===0.5.1;python_version=='2.7'
|
||||||
|
repoze.lru===0.7
|
||||||
|
rfc3986===1.1.0
|
||||||
|
tenacity===5.0.2
|
||||||
|
python-designateclient===2.10.0
|
||||||
|
future===0.16.0
|
||||||
|
Paste===2.0.3
|
||||||
|
jaeger-client===3.11.0
|
||||||
|
XStatic-Json2yaml===0.1.1.0
|
||||||
|
boto===2.49.0
|
||||||
|
functools32===3.2.3.post2;python_version=='2.7'
|
||||||
|
os-vif===1.11.1
|
||||||
|
python-masakariclient===5.2.0
|
||||||
|
Werkzeug===0.14.1
|
||||||
|
pyasn1-modules===0.2.2
|
||||||
|
entrypoints===0.2.3
|
||||||
|
APScheduler===3.5.3
|
||||||
|
monotonic===1.5
|
||||||
|
python-smaugclient===0.0.8
|
||||||
|
python-troveclient===2.16.0
|
||||||
|
etcd3===0.8.1
|
||||||
|
XStatic-Bootstrap-Datepicker===1.3.1.0
|
||||||
|
CouchDB===1.2
|
||||||
|
netifaces===0.10.7
|
||||||
|
cachetools===2.1.0
|
||||||
|
ws4py===0.5.1
|
||||||
|
backports-abc===0.5;python_version=='2.7'
|
||||||
|
keystoneauth1===3.11.0
|
||||||
|
statsd===3.3.0
|
||||||
|
XenAPI===1.2
|
||||||
|
python-keystoneclient===3.17.0
|
||||||
|
ceilometer===11.0.0
|
||||||
|
demjson===2.2.4
|
||||||
|
diskimage-builder===2.17.0
|
||||||
|
heat-translator===1.1.0
|
||||||
|
python-magnumclient===2.10.0
|
||||||
|
docker===3.5.0
|
||||||
|
qpid-python===1.36.0.post1;python_version=='2.7'
|
||||||
|
contextlib2===0.5.5
|
||||||
|
XStatic-Angular-lrdragndrop===1.0.2.2
|
||||||
|
python-congressclient===1.11.0
|
||||||
|
ovsdbapp===0.12.1
|
||||||
|
aniso8601===3.0.2
|
||||||
|
rjsmin===1.0.12
|
||||||
|
icalendar===4.0.2
|
||||||
|
configparser===3.5.0;python_version=='2.7'
|
||||||
|
decorator===4.3.0
|
||||||
|
cffi===1.11.5
|
||||||
|
futurist===1.7.0
|
||||||
|
jsonschema===2.6.0
|
||||||
|
python-blazarclient===2.0.1
|
||||||
|
alembic===1.0.0
|
||||||
|
glance-store===0.26.1
|
||||||
|
sphinxcontrib-programoutput===0.11
|
||||||
|
sphinx-testing===0.7.2
|
||||||
|
dnspython===1.15.0
|
||||||
|
oauthlib===2.1.0
|
||||||
|
Babel===2.6.0
|
||||||
|
logutils===0.3.5
|
||||||
|
scandir===1.9.0;python_version=='2.7'
|
||||||
|
sphinxcontrib-fulltoc===1.2.0
|
||||||
|
smmap2===2.0.4
|
||||||
|
greenlet===0.4.15
|
||||||
|
XStatic-Angular-Vis===4.16.0.0
|
||||||
|
confluent-kafka===0.11.5
|
||||||
|
xvfbwrapper===0.2.9
|
||||||
|
futures===3.2.0;python_version=='2.7'
|
||||||
|
tosca-parser===1.1.0
|
||||||
|
Flask===1.0.2
|
||||||
|
happybase===1.1.0;python_version=='2.7'
|
||||||
|
marathon===0.10.0
|
||||||
|
fasteners===0.14.1
|
||||||
|
sortedcontainers===2.0.5
|
||||||
|
python-tackerclient===0.14.0
|
||||||
|
python-heatclient===1.16.1
|
||||||
|
kafka-python===1.4.3
|
||||||
|
oslo.utils===3.37.0
|
||||||
|
python-editor===1.0.3
|
||||||
|
gitdb2===2.0.4
|
||||||
|
requests-kerberos===0.12.0
|
||||||
|
itsdangerous===0.24
|
||||||
|
XStatic-jquery-ui===1.12.0.1
|
||||||
|
monasca-statsd===1.10.1
|
||||||
|
python-dateutil===2.7.3
|
||||||
|
virtualenv===16.0.0
|
||||||
|
colorama===0.3.9
|
||||||
|
ironic-lib===2.14.0
|
||||||
|
pytz===2018.5
|
||||||
|
XStatic-D3===3.5.17.0
|
||||||
|
actdiag===0.5.4
|
||||||
|
sysv-ipc===1.0.0
|
||||||
|
scikit-learn===0.19.2
|
Loading…
Reference in New Issue
Block a user