mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
ProfitBricks CloudAPI v4 updates
This commit is contained in:
parent
015d66be4d
commit
3407b272c0
@ -11,7 +11,7 @@ and disk size without being tied to a particular server size.
|
||||
Dependencies
|
||||
============
|
||||
|
||||
* profitbricks >= 3.0.0
|
||||
* profitbricks >= 4.1.1
|
||||
|
||||
Configuration
|
||||
=============
|
||||
@ -34,8 +34,10 @@ Configuration
|
||||
#
|
||||
username: user@domain.com
|
||||
password: 123456
|
||||
# datacenter_id is the UUID of a pre-existing virtual data center.
|
||||
datacenter_id: 9e6709a0-6bf9-4bd6-8692-60349c70ce0e
|
||||
# datacenter is the UUID of a pre-existing virtual data center.
|
||||
datacenter: 9e6709a0-6bf9-4bd6-8692-60349c70ce0e
|
||||
# delete_volumes is forcing a deletion of all volumes attached to a server on a deletion of a server
|
||||
delete_volumes: true
|
||||
# Connect to public LAN ID 1.
|
||||
public_lan: 1
|
||||
ssh_public_key: /path/to/id_rsa.pub
|
||||
@ -65,6 +67,13 @@ A list of existing virtual data centers can be retrieved with the following comm
|
||||
|
||||
salt-cloud -f list_datacenters my-profitbricks-config
|
||||
|
||||
A new data center can be created with the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-cloud -f create_datacenter my-profitbricks-config name=example location=us/las description="my description"
|
||||
|
||||
|
||||
Authentication
|
||||
==============
|
||||
|
||||
@ -81,7 +90,9 @@ Here is an example of a profile:
|
||||
profitbricks_staging
|
||||
provider: my-profitbricks-config
|
||||
size: Micro Instance
|
||||
image: 2f98b678-6e7e-11e5-b680-52540066fee9
|
||||
image_alias: 'ubuntu:latest'
|
||||
# image or image_alias must be provided
|
||||
# image: 2f98b678-6e7e-11e5-b680-52540066fee9
|
||||
cores: 2
|
||||
ram: 4096
|
||||
public_lan: 1
|
||||
@ -117,8 +128,31 @@ Here is an example of a profile:
|
||||
disk_size: 500
|
||||
db_log:
|
||||
disk_size: 50
|
||||
disk_type: HDD
|
||||
disk_availability_zone: ZONE_3
|
||||
disk_type: SSD
|
||||
|
||||
Locations can be obtained using the ``--list-locations`` option for the ``salt-cloud``
|
||||
command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt-cloud --list-locations my-profitbricks-config
|
||||
|
||||
Images can be obtained using the ``--list-sizes`` option for the ``salt-cloud``
|
||||
command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt-cloud --list-images my-profitbricks-config
|
||||
|
||||
Sizes can be obtained using the ``--list-sizes`` option for the ``salt-cloud``
|
||||
command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt-cloud --list-sizes my-profitbricks-config
|
||||
|
||||
Profile Specifics:
|
||||
------------------
|
||||
|
||||
The following list explains some of the important properties.
|
||||
|
||||
@ -127,14 +161,21 @@ size
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-cloud --list-sizes my-profitbricks
|
||||
salt-cloud --list-sizes my-profitbricks-config
|
||||
|
||||
image
|
||||
Can be one of the options listed in the output of the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-cloud --list-images my-profitbricks
|
||||
salt-cloud --list-images my-profitbricks-config
|
||||
|
||||
image_alias
|
||||
Can be one of the options listed in the output of the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-cloud -f list_images my-profitbricks-config
|
||||
|
||||
disk_size
|
||||
This option allows you to override the size of the disk as defined by the
|
||||
@ -144,9 +185,6 @@ disk_type
|
||||
This option allow the disk type to be set to HDD or SSD. The default is
|
||||
HDD.
|
||||
|
||||
disk_availability_zone
|
||||
This option will provision the volume in the specified availability_zone.
|
||||
|
||||
cores
|
||||
This option allows you to override the number of CPU cores as defined by
|
||||
the size.
|
||||
@ -156,10 +194,6 @@ ram
|
||||
The value must be a multiple of 256, e.g. 256, 512, 768, 1024, and so
|
||||
forth.
|
||||
|
||||
availability_zone
|
||||
This options specifies in which availability zone the server should be
|
||||
built. Zones include ZONE_1 and ZONE_2. The default is AUTO.
|
||||
|
||||
public_lan
|
||||
This option will connect the server to the specified public LAN. If no
|
||||
LAN exists, then a new public LAN will be created. The value accepts a LAN
|
||||
@ -179,9 +213,6 @@ public_firewall_rules
|
||||
icmp_type: <icmp-type>
|
||||
icmp_code: <icmp-code>
|
||||
|
||||
nat
|
||||
This option will enable NAT on the private NIC.
|
||||
|
||||
private_lan
|
||||
This option will connect the server to the specified private LAN. If no
|
||||
LAN exists, then a new private LAN will be created. The value accepts a LAN
|
||||
@ -209,7 +240,7 @@ ssh_public_key
|
||||
|
||||
ssh_interface
|
||||
This option will use the private LAN IP for node connections (such as
|
||||
bootstrapping the node) instead of the public LAN IP. The value accepts
|
||||
as bootstrapping the node) instead of the public LAN IP. The value accepts
|
||||
'private_lan'.
|
||||
|
||||
cpu_family
|
||||
@ -228,5 +259,5 @@ wait_for_timeout
|
||||
The timeout to wait in seconds for provisioning resources such as servers.
|
||||
The default wait_for_timeout is 15 minutes.
|
||||
|
||||
For more information concerning cloud profiles, see :ref:`here
|
||||
<salt-cloud-profiles>`.
|
||||
For more information concerning cloud profiles, see :doc:`here
|
||||
</topics/cloud/profiles>`.
|
||||
|
@ -48,6 +48,9 @@ Set up the cloud configuration at ``/etc/salt/cloud.providers`` or
|
||||
availability_zone: ZONE_1
|
||||
# Name or UUID of the HDD image to use.
|
||||
image: <UUID>
|
||||
# Image alias could be provided instead of image.
|
||||
# Example 'ubuntu:latest'
|
||||
#image_alias: <IMAGE_ALIAS>
|
||||
# Size of the node disk in GB (overrides server size).
|
||||
disk_size: 40
|
||||
# Type of disk (HDD or SSD).
|
||||
@ -96,6 +99,7 @@ import logging
|
||||
import os
|
||||
import pprint
|
||||
import time
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils.cloud
|
||||
@ -112,11 +116,12 @@ from salt.exceptions import (
|
||||
# Import 3rd-party libs
|
||||
from salt.ext import six
|
||||
try:
|
||||
import profitbricks
|
||||
from profitbricks.client import (
|
||||
ProfitBricksService, Server,
|
||||
NIC, Volume, FirewallRule,
|
||||
Datacenter, LoadBalancer, LAN,
|
||||
PBNotFoundError
|
||||
PBNotFoundError, PBError
|
||||
)
|
||||
HAS_PROFITBRICKS = True
|
||||
except ImportError:
|
||||
@ -153,6 +158,13 @@ def get_configured_provider():
|
||||
)
|
||||
|
||||
|
||||
def version_compatible(version):
|
||||
'''
|
||||
Checks profitbricks version
|
||||
'''
|
||||
return LooseVersion(profitbricks.API_VERSION) >= LooseVersion(version)
|
||||
|
||||
|
||||
def get_dependencies():
|
||||
'''
|
||||
Warn if dependencies are not met.
|
||||
@ -183,6 +195,31 @@ def get_conn():
|
||||
)
|
||||
|
||||
|
||||
def avail_locations(call=None):
|
||||
'''
|
||||
Return a dict of all available VM locations on the cloud provider with
|
||||
relevant data
|
||||
'''
|
||||
if call == 'action':
|
||||
raise SaltCloudSystemExit(
|
||||
'The avail_images function must be called with '
|
||||
'-f or --function, or with the --list-locations option'
|
||||
)
|
||||
|
||||
ret = {}
|
||||
conn = get_conn()
|
||||
|
||||
for item in conn.list_locations()['items']:
|
||||
reg, loc = item['id'].split('/')
|
||||
location = {'id': item['id']}
|
||||
|
||||
if reg not in ret:
|
||||
ret[reg] = {}
|
||||
|
||||
ret[reg][loc] = location
|
||||
return ret
|
||||
|
||||
|
||||
def avail_images(call=None):
|
||||
'''
|
||||
Return a list of the images that are on the provider
|
||||
@ -195,18 +232,51 @@ def avail_images(call=None):
|
||||
|
||||
ret = {}
|
||||
conn = get_conn()
|
||||
datacenter = get_datacenter(conn)
|
||||
|
||||
for item in conn.list_images()['items']:
|
||||
if (item['properties']['location'] ==
|
||||
datacenter['properties']['location']):
|
||||
image = {'id': item['id']}
|
||||
image.update(item['properties'])
|
||||
ret[image['name']] = image
|
||||
image = {'id': item['id']}
|
||||
image.update(item['properties'])
|
||||
ret[image['name']] = image
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def list_images(call=None, kwargs=None):
|
||||
'''
|
||||
List all the images with alias by location
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-cloud -f list_images my-profitbricks-config location=us/las
|
||||
'''
|
||||
if call != 'function':
|
||||
raise SaltCloudSystemExit(
|
||||
'The list_images function must be called with '
|
||||
'-f or --function.'
|
||||
)
|
||||
|
||||
if not version_compatible('4.0'):
|
||||
raise SaltCloudNotFound(
|
||||
"The 'image_alias' feature requires the profitbricks "
|
||||
"SDK v4.0.0 or greater."
|
||||
)
|
||||
|
||||
ret = {}
|
||||
conn = get_conn()
|
||||
|
||||
if kwargs.get('location') is not None:
|
||||
item = conn.get_location(kwargs.get('location'), 3)
|
||||
ret[item['id']] = {'image_alias': item['properties']['imageAliases']}
|
||||
return ret
|
||||
|
||||
for item in conn.list_locations(3)['items']:
|
||||
ret[item['id']] = {'image_alias': item['properties']['imageAliases']}
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def avail_sizes(call=None):
|
||||
'''
|
||||
Return a dict of all available VM sizes on the cloud provider with
|
||||
@ -288,13 +358,24 @@ def get_datacenter_id():
|
||||
'''
|
||||
Return datacenter ID from provider configuration
|
||||
'''
|
||||
return config.get_cloud_config_value(
|
||||
datacenter_id = config.get_cloud_config_value(
|
||||
'datacenter_id',
|
||||
get_configured_provider(),
|
||||
__opts__,
|
||||
search_global=False
|
||||
)
|
||||
|
||||
conn = get_conn()
|
||||
|
||||
try:
|
||||
conn.get_datacenter(datacenter_id=datacenter_id)
|
||||
except PBNotFoundError:
|
||||
log.error('Failed to get datacenter: {0}'.format(
|
||||
datacenter_id))
|
||||
raise
|
||||
|
||||
return datacenter_id
|
||||
|
||||
|
||||
def list_loadbalancers(call=None):
|
||||
'''
|
||||
@ -373,7 +454,8 @@ def create_datacenter(call=None, kwargs=None):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-cloud -f create_datacenter profitbricks name=mydatacenter location=us/las description="my description"
|
||||
salt-cloud -f create_datacenter profitbricks name=mydatacenter
|
||||
location=us/las description="my description"
|
||||
'''
|
||||
if call != 'function':
|
||||
raise SaltCloudSystemExit(
|
||||
@ -492,6 +574,7 @@ def list_nodes(conn=None, call=None):
|
||||
for item in nodes['items']:
|
||||
node = {'id': item['id']}
|
||||
node.update(item['properties'])
|
||||
node['state'] = node.pop('vmState')
|
||||
ret[node['name']] = node
|
||||
|
||||
return ret
|
||||
@ -517,10 +600,13 @@ def list_nodes_full(conn=None, call=None):
|
||||
for item in nodes['items']:
|
||||
node = {'id': item['id']}
|
||||
node.update(item['properties'])
|
||||
node['state'] = node.pop('vmState')
|
||||
node['public_ips'] = []
|
||||
node['private_ips'] = []
|
||||
if item['entities']['nics']['items'] > 0:
|
||||
for nic in item['entities']['nics']['items']:
|
||||
if len(nic['properties']['ips']) > 0:
|
||||
pass
|
||||
ip_address = nic['properties']['ips'][0]
|
||||
if salt.utils.cloud.is_public_ip(ip_address):
|
||||
node['public_ips'].append(ip_address)
|
||||
@ -673,6 +759,23 @@ def get_key_filename(vm_):
|
||||
return key_filename
|
||||
|
||||
|
||||
def signal_event(vm_, event, description):
|
||||
args = __utils__['cloud.filter_event'](
|
||||
event,
|
||||
vm_,
|
||||
['name', 'profile', 'provider', 'driver']
|
||||
)
|
||||
|
||||
__utils__['cloud.fire_event'](
|
||||
'event',
|
||||
description,
|
||||
'salt/cloud/{0}/creating'.format(vm_['name']),
|
||||
args=args,
|
||||
sock_dir=__opts__['sock_dir'],
|
||||
transport=__opts__['transport']
|
||||
)
|
||||
|
||||
|
||||
def create(vm_):
|
||||
'''
|
||||
Create a single VM from a data dict
|
||||
@ -680,22 +783,24 @@ def create(vm_):
|
||||
try:
|
||||
# Check for required profile parameters before sending any API calls.
|
||||
if (vm_['profile'] and
|
||||
config.is_profile_configured(__opts__,
|
||||
(__active_provider_name__ or
|
||||
'profitbricks'),
|
||||
vm_['profile']) is False):
|
||||
config.is_profile_configured(__opts__,
|
||||
(__active_provider_name__ or
|
||||
'profitbricks'),
|
||||
vm_['profile']) is False):
|
||||
return False
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
__utils__['cloud.fire_event'](
|
||||
'event',
|
||||
'starting create',
|
||||
'salt/cloud/{0}/creating'.format(vm_['name']),
|
||||
args=__utils__['cloud.filter_event']('creating', vm_, ['name', 'profile', 'provider', 'driver']),
|
||||
sock_dir=__opts__['sock_dir'],
|
||||
transport=__opts__['transport']
|
||||
)
|
||||
if 'image_alias' in vm_ and not version_compatible('4.0'):
|
||||
raise SaltCloudNotFound(
|
||||
"The 'image_alias' parameter requires the profitbricks "
|
||||
"SDK v4.0.0 or greater."
|
||||
)
|
||||
|
||||
if 'image' not in vm_ and 'image_alias' not in vm_:
|
||||
log.error('The image or image_alias parameter is required.')
|
||||
|
||||
signal_event(vm_, 'creating', 'starting create')
|
||||
|
||||
data = None
|
||||
datacenter_id = get_datacenter_id()
|
||||
@ -712,14 +817,7 @@ def create(vm_):
|
||||
# Assembla the composite server object.
|
||||
server = _get_server(vm_, volumes, nics)
|
||||
|
||||
__utils__['cloud.fire_event'](
|
||||
'event',
|
||||
'requesting instance',
|
||||
'salt/cloud/{0}/requesting'.format(vm_['name']),
|
||||
args=__utils__['cloud.filter_event']('requesting', vm_, ['name', 'profile', 'provider', 'driver']),
|
||||
sock_dir=__opts__['sock_dir'],
|
||||
transport=__opts__['transport']
|
||||
)
|
||||
signal_event(vm_, 'requesting', 'requesting instance')
|
||||
|
||||
try:
|
||||
data = conn.create_server(datacenter_id=datacenter_id, server=server)
|
||||
@ -728,11 +826,20 @@ def create(vm_):
|
||||
|
||||
_wait_for_completion(conn, data, get_wait_timeout(vm_),
|
||||
'create_server')
|
||||
except Exception as exc: # pylint: disable=W0703
|
||||
except PBError as exc:
|
||||
log.error(
|
||||
'Error creating {0} on ProfitBricks\n\n'
|
||||
'The following exception was thrown by the profitbricks library '
|
||||
'when trying to run the initial deployment: \n{1}'.format(
|
||||
'when trying to run the initial deployment: \n{1}:\n{2}'.format(
|
||||
vm_['name'], exc, exc.content
|
||||
),
|
||||
exc_info_on_loglevel=logging.DEBUG
|
||||
)
|
||||
return False
|
||||
except Exception as exc: # pylint: disable=W0703
|
||||
log.error(
|
||||
'Error creating {0} \n\n'
|
||||
'Error: \n{1}'.format(
|
||||
vm_['name'], exc
|
||||
),
|
||||
exc_info_on_loglevel=logging.DEBUG
|
||||
@ -754,7 +861,7 @@ def create(vm_):
|
||||
'Loaded node data for {0}:\nname: {1}\nstate: {2}'.format(
|
||||
vm_['name'],
|
||||
pprint.pformat(data['name']),
|
||||
data['vmState']
|
||||
data['state']
|
||||
)
|
||||
)
|
||||
except Exception as err:
|
||||
@ -768,7 +875,7 @@ def create(vm_):
|
||||
# Trigger a failure in the wait for IP function
|
||||
return False
|
||||
|
||||
running = data['vmState'] == 'RUNNING'
|
||||
running = data['state'] == 'RUNNING'
|
||||
if not running:
|
||||
# Still not running, trigger another iteration
|
||||
return
|
||||
@ -807,14 +914,7 @@ def create(vm_):
|
||||
)
|
||||
)
|
||||
|
||||
__utils__['cloud.fire_event'](
|
||||
'event',
|
||||
'created instance',
|
||||
'salt/cloud/{0}/created'.format(vm_['name']),
|
||||
args=__utils__['cloud.filter_event']('created', vm_, ['name', 'profile', 'provider', 'driver']),
|
||||
sock_dir=__opts__['sock_dir'],
|
||||
transport=__opts__['transport']
|
||||
)
|
||||
signal_event(vm_, 'created', 'created instance')
|
||||
|
||||
if 'ssh_host' in vm_:
|
||||
vm_['key_filename'] = get_key_filename(vm_)
|
||||
@ -859,9 +959,32 @@ def destroy(name, call=None):
|
||||
datacenter_id = get_datacenter_id()
|
||||
conn = get_conn()
|
||||
node = get_node(conn, name)
|
||||
attached_volumes = None
|
||||
|
||||
delete_volumes = config.get_cloud_config_value(
|
||||
'delete_volumes',
|
||||
get_configured_provider(),
|
||||
__opts__,
|
||||
search_global=False
|
||||
)
|
||||
# Get volumes before the server is deleted
|
||||
attached_volumes = conn.get_attached_volumes(
|
||||
datacenter_id=datacenter_id,
|
||||
server_id=node['id']
|
||||
)
|
||||
|
||||
conn.delete_server(datacenter_id=datacenter_id, server_id=node['id'])
|
||||
|
||||
# The server is deleted and now is safe to delete the volumes
|
||||
if delete_volumes:
|
||||
for vol in attached_volumes['items']:
|
||||
log.debug('Deleting volume {0}'.format(vol['id']))
|
||||
conn.delete_volume(
|
||||
datacenter_id=datacenter_id,
|
||||
volume_id=vol['id']
|
||||
)
|
||||
log.debug('Deleted volume {0}'.format(vol['id']))
|
||||
|
||||
__utils__['cloud.fire_event'](
|
||||
'event',
|
||||
'destroyed instance',
|
||||
@ -1010,14 +1133,17 @@ def _get_system_volume(vm_):
|
||||
volume = Volume(
|
||||
name='{0} Storage'.format(vm_['name']),
|
||||
size=disk_size,
|
||||
image=get_image(vm_)['id'],
|
||||
disk_type=get_disk_type(vm_),
|
||||
ssh_keys=ssh_keys
|
||||
)
|
||||
|
||||
# Set volume availability zone if defined in the cloud profile
|
||||
if 'disk_availability_zone' in vm_:
|
||||
volume.availability_zone = vm_['disk_availability_zone']
|
||||
if 'image_alias' in vm_.keys():
|
||||
volume.image_alias = vm_['image_alias']
|
||||
else:
|
||||
volume.image = get_image(vm_)['id']
|
||||
# Set volume availability zone if defined in the cloud profile
|
||||
if 'disk_availability_zone' in vm_:
|
||||
volume.availability_zone = vm_['disk_availability_zone']
|
||||
|
||||
return volume
|
||||
|
||||
@ -1109,4 +1235,4 @@ def _wait_for_completion(conn, promise, wait_timeout, msg):
|
||||
raise Exception(
|
||||
'Timed out waiting for async operation ' + msg + ' "' + str(
|
||||
promise['requestId']
|
||||
) + '" to complete.')
|
||||
) + '" to complete.')
|
||||
|
@ -124,15 +124,6 @@ VALID_OPTS = {
|
||||
# master address will not be split into IP and PORT.
|
||||
'master_uri_format': str,
|
||||
|
||||
# The following optiosn refer to the Minion only, and they specify
|
||||
# the details of the source address / port to be used when connecting to
|
||||
# the Master. This is useful when dealing withmachines where due to firewall
|
||||
# rules you are restricted to use a certain IP/port combination only.
|
||||
'source_interface_name': str,
|
||||
'source_address': str,
|
||||
'source_ret_port': (six.string_types, int),
|
||||
'source_publish_port': (six.string_types, int),
|
||||
|
||||
# The fingerprint of the master key may be specified to increase security. Generate
|
||||
# a master fingerprint with `salt-key -F master`
|
||||
'master_finger': str,
|
||||
@ -174,10 +165,6 @@ VALID_OPTS = {
|
||||
# The master_pubkey_signature must also be set for this.
|
||||
'master_use_pubkey_signature': bool,
|
||||
|
||||
# Enable master stats eveents to be fired, these events will contain information about
|
||||
# what commands the master is processing and what the rates are of the executions
|
||||
'master_stats': bool,
|
||||
'master_stats_event_iter': int,
|
||||
# The key fingerprint of the higher-level master for the syndic to verify it is talking to the
|
||||
# intended master
|
||||
'syndic_finger': str,
|
||||
@ -255,10 +242,7 @@ VALID_OPTS = {
|
||||
'autoload_dynamic_modules': bool,
|
||||
|
||||
# Force the minion into a single environment when it fetches files from the master
|
||||
'saltenv': str,
|
||||
|
||||
# Prevent saltenv from being overriden on the command line
|
||||
'lock_saltenv': bool,
|
||||
'environment': str,
|
||||
|
||||
# Force the minion into a single pillar root when it fetches pillar data from the master
|
||||
'pillarenv': str,
|
||||
@ -1153,9 +1137,6 @@ VALID_OPTS = {
|
||||
# part of the extra_minion_data param
|
||||
# Subconfig entries can be specified by using the ':' notation (e.g. key:subkey)
|
||||
'pass_to_ext_pillars': (six.string_types, list),
|
||||
|
||||
# Used by salt.modules.dockermod.compare_container_networks to specify which keys are compared
|
||||
'docker.compare_container_networks': dict,
|
||||
}
|
||||
|
||||
# default configurations
|
||||
@ -1164,10 +1145,6 @@ DEFAULT_MINION_OPTS = {
|
||||
'master': 'salt',
|
||||
'master_type': 'str',
|
||||
'master_uri_format': 'default',
|
||||
'source_interface_name': '',
|
||||
'source_address': '',
|
||||
'source_ret_port': 0,
|
||||
'source_publish_port': 0,
|
||||
'master_port': 4506,
|
||||
'master_finger': '',
|
||||
'master_shuffle': False,
|
||||
@ -1200,8 +1177,7 @@ DEFAULT_MINION_OPTS = {
|
||||
'random_startup_delay': 0,
|
||||
'failhard': False,
|
||||
'autoload_dynamic_modules': True,
|
||||
'saltenv': None,
|
||||
'lock_saltenv': False,
|
||||
'environment': None,
|
||||
'pillarenv': None,
|
||||
'pillarenv_from_saltenv': False,
|
||||
'pillar_opts': False,
|
||||
@ -1435,11 +1411,6 @@ DEFAULT_MINION_OPTS = {
|
||||
'extmod_whitelist': {},
|
||||
'extmod_blacklist': {},
|
||||
'minion_sign_messages': False,
|
||||
'docker.compare_container_networks': {
|
||||
'static': ['Aliases', 'Links', 'IPAMConfig'],
|
||||
'automatic': ['IPAddress', 'Gateway',
|
||||
'GlobalIPv6Address', 'IPv6Gateway'],
|
||||
},
|
||||
}
|
||||
|
||||
DEFAULT_MASTER_OPTS = {
|
||||
@ -1483,8 +1454,7 @@ DEFAULT_MASTER_OPTS = {
|
||||
},
|
||||
'top_file_merging_strategy': 'merge',
|
||||
'env_order': [],
|
||||
'saltenv': None,
|
||||
'lock_saltenv': False,
|
||||
'environment': None,
|
||||
'default_top': 'base',
|
||||
'file_client': 'local',
|
||||
'git_pillar_base': 'master',
|
||||
@ -1545,8 +1515,6 @@ DEFAULT_MASTER_OPTS = {
|
||||
'svnfs_saltenv_whitelist': [],
|
||||
'svnfs_saltenv_blacklist': [],
|
||||
'max_event_size': 1048576,
|
||||
'master_stats': False,
|
||||
'master_stats_event_iter': 60,
|
||||
'minionfs_env': 'base',
|
||||
'minionfs_mountpoint': '',
|
||||
'minionfs_whitelist': [],
|
||||
@ -2444,7 +2412,7 @@ def syndic_config(master_config_path,
|
||||
# Prepend root_dir to other paths
|
||||
prepend_root_dirs = [
|
||||
'pki_dir', 'key_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules',
|
||||
'autosign_file', 'autoreject_file', 'token_dir', 'autosign_grains_dir'
|
||||
'autosign_file', 'autoreject_file', 'token_dir'
|
||||
]
|
||||
for config_key in ('log_file', 'key_logfile', 'syndic_log_file'):
|
||||
# If this is not a URI and instead a local path
|
||||
@ -3339,7 +3307,7 @@ def is_profile_configured(opts, provider, profile_name, vm_=None):
|
||||
alias, driver = provider.split(':')
|
||||
|
||||
# Most drivers need an image to be specified, but some do not.
|
||||
non_image_drivers = ['nova', 'virtualbox', 'libvirt', 'softlayer', 'oneandone']
|
||||
non_image_drivers = ['nova', 'virtualbox', 'libvirt', 'softlayer', 'oneandone', 'profitbricks']
|
||||
|
||||
# Most drivers need a size, but some do not.
|
||||
non_size_drivers = ['opennebula', 'parallels', 'proxmox', 'scaleway',
|
||||
@ -3624,24 +3592,6 @@ def apply_minion_config(overrides=None,
|
||||
if overrides:
|
||||
opts.update(overrides)
|
||||
|
||||
if 'environment' in opts:
|
||||
if 'saltenv' in opts:
|
||||
log.warning(
|
||||
'The \'saltenv\' and \'environment\' minion config options '
|
||||
'cannot both be used. Ignoring \'environment\' in favor of '
|
||||
'\'saltenv\'.',
|
||||
)
|
||||
# Set environment to saltenv in case someone's custom module is
|
||||
# refrencing __opts__['environment']
|
||||
opts['environment'] = opts['saltenv']
|
||||
else:
|
||||
log.warning(
|
||||
'The \'environment\' minion config option has been renamed '
|
||||
'to \'saltenv\'. Using %s as the \'saltenv\' config value.',
|
||||
opts['environment']
|
||||
)
|
||||
opts['saltenv'] = opts['environment']
|
||||
|
||||
opts['__cli'] = os.path.basename(sys.argv[0])
|
||||
|
||||
# No ID provided. Will getfqdn save us?
|
||||
@ -3794,24 +3744,6 @@ def apply_master_config(overrides=None, defaults=None):
|
||||
if overrides:
|
||||
opts.update(overrides)
|
||||
|
||||
if 'environment' in opts:
|
||||
if 'saltenv' in opts:
|
||||
log.warning(
|
||||
'The \'saltenv\' and \'environment\' master config options '
|
||||
'cannot both be used. Ignoring \'environment\' in favor of '
|
||||
'\'saltenv\'.',
|
||||
)
|
||||
# Set environment to saltenv in case someone's custom runner is
|
||||
# refrencing __opts__['environment']
|
||||
opts['environment'] = opts['saltenv']
|
||||
else:
|
||||
log.warning(
|
||||
'The \'environment\' master config option has been renamed '
|
||||
'to \'saltenv\'. Using %s as the \'saltenv\' config value.',
|
||||
opts['environment']
|
||||
)
|
||||
opts['saltenv'] = opts['environment']
|
||||
|
||||
if len(opts['sock_dir']) > len(opts['cachedir']) + 10:
|
||||
opts['sock_dir'] = os.path.join(opts['cachedir'], '.salt-unix')
|
||||
|
||||
@ -3854,7 +3786,7 @@ def apply_master_config(overrides=None, defaults=None):
|
||||
prepend_root_dirs = [
|
||||
'pki_dir', 'key_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules',
|
||||
'autosign_file', 'autoreject_file', 'token_dir', 'syndic_dir',
|
||||
'sqlite_queue_dir', 'autosign_grains_dir'
|
||||
'sqlite_queue_dir'
|
||||
]
|
||||
|
||||
# These can be set to syslog, so, not actual paths on the system
|
||||
|
@ -18,7 +18,8 @@ from salt.config import cloud_providers_config
|
||||
|
||||
# Import Third-Party Libs
|
||||
try:
|
||||
from profitbricks.client import ProfitBricksService # pylint: disable=unused-import
|
||||
# pylint: disable=unused-import
|
||||
from profitbricks.client import ProfitBricksService
|
||||
HAS_PROFITBRICKS = True
|
||||
except ImportError:
|
||||
HAS_PROFITBRICKS = False
|
||||
@ -29,7 +30,7 @@ PROVIDER_NAME = 'profitbricks'
|
||||
DRIVER_NAME = 'profitbricks'
|
||||
|
||||
|
||||
@skipIf(HAS_PROFITBRICKS is False, 'salt-cloud requires >= profitbricks 2.3.0')
|
||||
@skipIf(HAS_PROFITBRICKS is False, 'salt-cloud requires >= profitbricks 4.1.0')
|
||||
class ProfitBricksTest(ShellCase):
|
||||
'''
|
||||
Integration tests for the ProfitBricks cloud provider
|
||||
@ -65,6 +66,7 @@ class ProfitBricksTest(ShellCase):
|
||||
username = config[profile_str][DRIVER_NAME]['username']
|
||||
password = config[profile_str][DRIVER_NAME]['password']
|
||||
datacenter_id = config[profile_str][DRIVER_NAME]['datacenter_id']
|
||||
self.datacenter_id = datacenter_id
|
||||
if username == '' or password == '' or datacenter_id == '':
|
||||
self.skipTest(
|
||||
'A username, password, and an datacenter must be provided to '
|
||||
@ -77,10 +79,104 @@ class ProfitBricksTest(ShellCase):
|
||||
'''
|
||||
Tests the return of running the --list-images command for ProfitBricks
|
||||
'''
|
||||
image_list = self.run_cloud('--list-images {0}'.format(PROVIDER_NAME))
|
||||
list_images = self.run_cloud('--list-images {0}'.format(PROVIDER_NAME))
|
||||
self.assertIn(
|
||||
'Ubuntu-16.04-LTS-server-2016-10-06',
|
||||
[i.strip() for i in image_list]
|
||||
'Ubuntu-16.04-LTS-server-2017-10-01',
|
||||
[i.strip() for i in list_images]
|
||||
)
|
||||
|
||||
def test_list_image_alias(self):
|
||||
'''
|
||||
Tests the return of running the -f list_images
|
||||
command for ProfitBricks
|
||||
'''
|
||||
cmd = '-f list_images {0}'.format(PROVIDER_NAME)
|
||||
list_images = self.run_cloud(cmd)
|
||||
self.assertIn(
|
||||
'- ubuntu:latest',
|
||||
[i.strip() for i in list_images]
|
||||
)
|
||||
|
||||
def test_list_sizes(self):
|
||||
'''
|
||||
Tests the return of running the --list_sizes command for ProfitBricks
|
||||
'''
|
||||
list_sizes = self.run_cloud('--list-sizes {0}'.format(PROVIDER_NAME))
|
||||
self.assertIn(
|
||||
'Micro Instance:',
|
||||
[i.strip() for i in list_sizes]
|
||||
)
|
||||
|
||||
def test_list_datacenters(self):
|
||||
'''
|
||||
Tests the return of running the -f list_datacenters
|
||||
command for ProfitBricks
|
||||
'''
|
||||
cmd = '-f list_datacenters {0}'.format(PROVIDER_NAME)
|
||||
list_datacenters = self.run_cloud(cmd)
|
||||
self.assertIn(
|
||||
self.datacenter_id,
|
||||
[i.strip() for i in list_datacenters]
|
||||
)
|
||||
|
||||
def test_list_nodes(self):
|
||||
'''
|
||||
Tests the return of running the -f list_nodes command for ProfitBricks
|
||||
'''
|
||||
list_nodes = self.run_cloud('-f list_nodes {0}'.format(PROVIDER_NAME))
|
||||
self.assertIn(
|
||||
'state:',
|
||||
[i.strip() for i in list_nodes]
|
||||
)
|
||||
|
||||
self.assertIn(
|
||||
'name:',
|
||||
[i.strip() for i in list_nodes]
|
||||
)
|
||||
|
||||
def test_list_nodes_full(self):
|
||||
'''
|
||||
Tests the return of running the -f list_nodes_full
|
||||
command for ProfitBricks
|
||||
'''
|
||||
cmd = '-f list_nodes_full {0}'.format(PROVIDER_NAME)
|
||||
list_nodes = self.run_cloud(cmd)
|
||||
self.assertIn(
|
||||
'state:',
|
||||
[i.strip() for i in list_nodes]
|
||||
)
|
||||
|
||||
self.assertIn(
|
||||
'name:',
|
||||
[i.strip() for i in list_nodes]
|
||||
)
|
||||
|
||||
def test_list_location(self):
|
||||
'''
|
||||
Tests the return of running the --list-locations
|
||||
command for ProfitBricks
|
||||
'''
|
||||
cmd = '--list-locations {0}'.format(PROVIDER_NAME)
|
||||
list_locations = self.run_cloud(cmd)
|
||||
|
||||
self.assertIn(
|
||||
'de/fkb',
|
||||
[i.strip() for i in list_locations]
|
||||
)
|
||||
|
||||
self.assertIn(
|
||||
'de/fra',
|
||||
[i.strip() for i in list_locations]
|
||||
)
|
||||
|
||||
self.assertIn(
|
||||
'us/las',
|
||||
[i.strip() for i in list_locations]
|
||||
)
|
||||
|
||||
self.assertIn(
|
||||
'us/ewr',
|
||||
[i.strip() for i in list_locations]
|
||||
)
|
||||
|
||||
def test_instance(self):
|
||||
@ -92,11 +188,15 @@ class ProfitBricksTest(ShellCase):
|
||||
self.assertIn(
|
||||
INSTANCE_NAME,
|
||||
[i.strip() for i in self.run_cloud(
|
||||
'-p profitbricks-test {0}'.format(INSTANCE_NAME), timeout=500
|
||||
'-p profitbricks-test {0}'.format(INSTANCE_NAME),
|
||||
timeout=500
|
||||
)]
|
||||
)
|
||||
except AssertionError:
|
||||
self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME), timeout=500)
|
||||
self.run_cloud(
|
||||
'-d {0} --assume-yes'.format(INSTANCE_NAME),
|
||||
timeout=500
|
||||
)
|
||||
raise
|
||||
|
||||
# delete the instance
|
||||
@ -119,4 +219,7 @@ class ProfitBricksTest(ShellCase):
|
||||
|
||||
# if test instance is still present, delete it
|
||||
if ret in query:
|
||||
self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME), timeout=500)
|
||||
self.run_cloud(
|
||||
'-d {0} --assume-yes'.format(INSTANCE_NAME),
|
||||
timeout=500
|
||||
)
|
||||
|
@ -1,6 +1,6 @@
|
||||
profitbricks-test:
|
||||
provider: profitbricks-config
|
||||
image: Ubuntu-16.04-LTS-server-2016-10-06
|
||||
image_alias: 'ubuntu:latest'
|
||||
image_password: volume2016
|
||||
size: Small Instance
|
||||
disk_size: 10
|
||||
|
Loading…
Reference in New Issue
Block a user