summaryrefslogtreecommitdiffstats
path: root/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py
diff options
context:
space:
mode:
Diffstat (limited to 'tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py')
-rwxr-xr-xtosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py274
1 files changed, 0 insertions, 274 deletions
diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py
deleted file mode 100755
index 137418d..0000000
--- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py
+++ /dev/null
@@ -1,274 +0,0 @@
-#
-# 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 json
-import logging
-import os
-import requests
-
-from toscaparser.utils.validateutils import TOSCAVersionProperty
-import translator.common.utils
-from translator.hot.syntax.hot_resource import HotResource
-log = logging.getLogger('tosca')
-
-# Name used to dynamically load appropriate map class.
-TARGET_CLASS_NAME = 'ToscaCompute'
-
-# Required environment variables to create novaclient object.
-ENV_VARIABLES = ['OS_AUTH_URL', 'OS_PASSWORD', 'OS_USERNAME', 'OS_TENANT_NAME']
-
-# A design issue to be resolved is how to translate the generic TOSCA server
-# properties to OpenStack flavors and images. At the Atlanta design summit,
-# there was discussion on using Glance to store metadata and Graffiti to
-# describe artifacts. We will follow these projects to see if they can be
-# leveraged for this TOSCA translation.
-# For development purpose at this time, we temporarily hardcode a list of
-# flavors and images here
-FLAVORS = {'m1.xlarge': {'mem_size': 16384, 'disk_size': 160, 'num_cpus': 8},
- 'm1.large': {'mem_size': 8192, 'disk_size': 80, 'num_cpus': 4},
- 'm1.medium': {'mem_size': 4096, 'disk_size': 40, 'num_cpus': 2},
- 'm1.small': {'mem_size': 2048, 'disk_size': 20, 'num_cpus': 1},
- 'm1.tiny': {'mem_size': 512, 'disk_size': 1, 'num_cpus': 1},
- 'm1.micro': {'mem_size': 128, 'disk_size': 0, 'num_cpus': 1},
- 'm1.nano': {'mem_size': 64, 'disk_size': 0, 'num_cpus': 1}}
-
-IMAGES = {'ubuntu-software-config-os-init': {'architecture': 'x86_64',
- 'type': 'Linux',
- 'distribution': 'Ubuntu',
- 'version': '14.04'},
- 'ubuntu-12.04-software-config-os-init': {'architecture': 'x86_64',
- 'type': 'Linux',
- 'distribution': 'Ubuntu',
- 'version': '12.04'},
- 'fedora-amd64-heat-config': {'architecture': 'x86_64',
- 'type': 'Linux',
- 'distribution': 'Fedora',
- 'version': '18.0'},
- 'F18-x86_64-cfntools': {'architecture': 'x86_64',
- 'type': 'Linux',
- 'distribution': 'Fedora',
- 'version': '19'},
- 'Fedora-x86_64-20-20131211.1-sda': {'architecture': 'x86_64',
- 'type': 'Linux',
- 'distribution': 'Fedora',
- 'version': '20'},
- 'cirros-0.3.1-x86_64-uec': {'architecture': 'x86_64',
- 'type': 'Linux',
- 'distribution': 'CirrOS',
- 'version': '0.3.1'},
- 'cirros-0.3.2-x86_64-uec': {'architecture': 'x86_64',
- 'type': 'Linux',
- 'distribution': 'CirrOS',
- 'version': '0.3.2'},
- 'rhel-6.5-test-image': {'architecture': 'x86_64',
- 'type': 'Linux',
- 'distribution': 'RHEL',
- 'version': '6.5'}}
-
-
-class ToscaCompute(HotResource):
- '''Translate TOSCA node type tosca.nodes.Compute.'''
-
- toscatype = 'tosca.nodes.Compute'
-
- def __init__(self, nodetemplate):
- super(ToscaCompute, self).__init__(nodetemplate,
- type='OS::Nova::Server')
- # List with associated hot port resources with this server
- self.assoc_port_resources = []
- pass
-
- def handle_properties(self):
- self.properties = self.translate_compute_flavor_and_image(
- self.nodetemplate.get_capability('host'),
- self.nodetemplate.get_capability('os'))
- self.properties['user_data_format'] = 'SOFTWARE_CONFIG'
- # TODO(anyone): handle user key
- # hardcoded here for testing
- self.properties['key_name'] = 'userkey'
-
- # To be reorganized later based on new development in Glance and Graffiti
- def translate_compute_flavor_and_image(self,
- host_capability,
- os_capability):
- hot_properties = {}
- host_cap_props = {}
- os_cap_props = {}
- image = None
- flavor = None
- if host_capability:
- for prop in host_capability.get_properties_objects():
- host_cap_props[prop.name] = prop.value
- flavor = self._best_flavor(host_cap_props)
- if os_capability:
- for prop in os_capability.get_properties_objects():
- os_cap_props[prop.name] = prop.value
- image = self._best_image(os_cap_props)
- hot_properties['flavor'] = flavor
- hot_properties['image'] = image
- # TODO(anyone): consider adding the flavor or image as a template
- # parameter if no match is found.
- return hot_properties
-
- def _check_for_env_variables(self):
- return set(ENV_VARIABLES) < set(os.environ.keys())
-
- def _create_nova_flavor_dict(self):
- '''Populates and returns the flavors dict using Nova ReST API'''
-
- tenant_name = os.getenv('OS_TENANT_NAME')
- username = os.getenv('OS_USERNAME')
- password = os.getenv('OS_PASSWORD')
- auth_url = os.getenv('OS_AUTH_URL')
-
- auth_dict = {
- "auth": {
- "tenantName": tenant_name,
- "passwordCredentials": {
- "username": username,
- "password": password
- }
- }
- }
- headers = {'Content-Type': 'application/json'}
- keystone_response = requests.post(auth_url + '/tokens',
- data=json.dumps(auth_dict),
- headers=headers)
- if keystone_response.status_code != 200:
- return None
- access_dict = json.loads(keystone_response.content)
- access_token = access_dict['access']['token']['id']
- service_catalog = access_dict['access']['serviceCatalog']
- nova_url = ''
- for service in service_catalog:
- if service['type'] == 'compute':
- nova_url = service['endpoints'][0]['publicURL']
- if not nova_url:
- return None
- nova_response = requests.get(nova_url + '/flavors/detail',
- headers={'X-Auth-Token': access_token})
- if nova_response.status_code != 200:
- return None
- flavors = json.loads(nova_response.content)['flavors']
- flavor_dict = dict()
- for flavor in flavors:
- flavor_name = str(flavor['name'])
- flavor_dict[flavor_name] = {
- 'mem_size': flavor['ram'],
- 'disk_size': flavor['disk'],
- 'num_cpus': flavor['vcpus'],
- }
- return flavor_dict
-
- def _best_flavor(self, properties):
- # Check whether user exported all required environment variables.
- flavors = FLAVORS
- if self._check_for_env_variables():
- resp = self._create_nova_flavor_dict()
- if resp:
- flavors = resp
-
- # start with all flavors
- match_all = flavors.keys()
-
- # TODO(anyone): Handle the case where the value contains something like
- # get_input instead of a value.
- # flavors that fit the CPU count
- cpu = properties.get('num_cpus')
- match_cpu = self._match_flavors(match_all, flavors, 'num_cpus', cpu)
-
- # flavors that fit the mem size
- mem = properties.get('mem_size')
- if mem:
- mem = translator.common.utils.MemoryUnit.convert_unit_size_to_num(
- mem, 'MB')
- match_cpu_mem = self._match_flavors(match_cpu, flavors,
- 'mem_size', mem)
- # flavors that fit the disk size
- disk = properties.get('disk_size')
- if disk:
- disk = translator.common.utils.MemoryUnit.\
- convert_unit_size_to_num(disk, 'GB')
- match_cpu_mem_disk = self._match_flavors(match_cpu_mem, flavors,
- 'disk_size', disk)
- # if multiple match, pick the flavor with the least memory
- # the selection can be based on other heuristic, e.g. pick one with the
- # least total resource
- if len(match_cpu_mem_disk) > 1:
- return self._least_flavor(match_cpu_mem_disk, flavors, 'mem_size')
- elif len(match_cpu_mem_disk) == 1:
- return match_cpu_mem_disk[0]
- else:
- return None
-
- def _best_image(self, properties):
- match_all = IMAGES.keys()
- architecture = properties.get('architecture')
- match_arch = self._match_images(match_all, IMAGES,
- 'architecture', architecture)
- type = properties.get('type')
- match_type = self._match_images(match_arch, IMAGES, 'type', type)
- distribution = properties.get('distribution')
- match_distribution = self._match_images(match_type, IMAGES,
- 'distribution',
- distribution)
- version = properties.get('version')
- version = TOSCAVersionProperty(version).get_version()
- match_version = self._match_images(match_distribution, IMAGES,
- 'version', version)
-
- if len(match_version):
- return list(match_version)[0]
-
- def _match_flavors(self, this_list, this_dict, attr, size):
- '''Return from this list all flavors matching the attribute size.'''
- if not size:
- return list(this_list)
- matching_flavors = []
- for flavor in this_list:
- if isinstance(size, int):
- if this_dict[flavor][attr] >= size:
- matching_flavors.append(flavor)
- return matching_flavors
-
- def _least_flavor(self, this_list, this_dict, attr):
- '''Return from this list the flavor with the smallest attr.'''
- least_flavor = this_list[0]
- for flavor in this_list:
- if this_dict[flavor][attr] < this_dict[least_flavor][attr]:
- least_flavor = flavor
- return least_flavor
-
- def _match_images(self, this_list, this_dict, attr, prop):
- if not prop:
- return this_list
- matching_images = []
- for image in this_list:
- if this_dict[image][attr].lower() == str(prop).lower():
- matching_images.append(image)
- return matching_images
-
- def get_hot_attribute(self, attribute, args):
- attr = {}
- # Convert from a TOSCA attribute for a nodetemplate to a HOT
- # attribute for the matching resource. Unless there is additional
- # runtime support, this should be a one to one mapping.
-
- # Note: We treat private and public IP addresses equally, but
- # this will change in the future when TOSCA starts to support
- # multiple private/public IP addresses.
- if attribute == 'private_address' or \
- attribute == 'public_address':
- attr['get_attr'] = [self.name, 'networks', 'private', 0]
-
- return attr