Esempio n. 1
0
    def _create_network(self, obj):
        client = self.network(obj)
        try:
            net = client.network_create()
            subnet = client.subnet_create(network_id=net.id,
                                          cidr='10.7.0.0/24',
                                          ip_version=4)
        except exc.InternalError as ex:
            raise exc.EResourceCreation(type='kubernetes',
                                        message=str(ex),
                                        resource_id=obj.id)
        pub_net = client.network_get(self.properties[self.PUBLIC_NETWORK])
        try:
            router = client.router_create(
                external_gateway_info={"network_id": pub_net.id})
            client.add_interface_to_router(router, subnet_id=subnet.id)
            fip = client.floatingip_create(floating_network_id=pub_net.id)
        except exc.InternalError as ex:
            raise exc.EResourceCreation(type='kubernetes',
                                        message=str(ex),
                                        resource_id=obj.id)

        ctx = context.get_service_context(user_id=obj.user,
                                          project_id=obj.project)
        data = obj.data
        data[self.PRIVATE_NETWORK] = net.id
        data[self.PRIVATE_SUBNET] = subnet.id
        data[self.PRIVATE_ROUTER] = router.id
        data[self.KUBE_MASTER_FLOATINGIP] = fip.floating_ip_address
        data[self.KUBE_MASTER_FLOATINGIP_ID] = fip.id

        cluster_obj.Cluster.update(ctx, obj.id, {'data': data})

        return net.id
Esempio n. 2
0
    def _validate_flavor(self, obj, name_or_id, reason=None):
        flavor = None
        msg = ''
        try:
            flavor = self.compute(obj).flavor_find(name_or_id, False)
        except exc.InternalError as ex:
            msg = six.text_type(ex)
            if reason is None:  # reaons is 'validate'
                if ex.code == 404:
                    msg = _(
                        "The specified %(k)s '%(v)s' could not be found.") % {
                            'k': self.FLAVOR,
                            'v': name_or_id
                        }
                    raise exc.InvalidSpec(message=msg)
                else:
                    raise

        if flavor is not None:
            if not flavor.is_disabled:
                return flavor
            msg = _("The specified %(k)s '%(v)s' is disabled") % {
                'k': self.FLAVOR,
                'v': name_or_id
            }

        if reason == 'create':
            raise exc.EResourceCreation(type='server', message=msg)
        elif reason == 'update':
            raise exc.EResourceUpdate(type='server',
                                      id=obj.physical_id,
                                      message=msg)
        else:
            raise exc.InvalidSpec(message=msg)
Esempio n. 3
0
    def do_create(self, obj):
        """Create a heat stack using the given node object.

        :param obj: The node object to operate on.
        :returns: The UUID of the heat stack created.
        """
        kwargs = {
            'stack_name': obj.name + '-' + utils.random_name(8),
            'template': self.properties[self.TEMPLATE],
            'template_url': self.properties[self.TEMPLATE_URL],
            'timeout_mins': self.properties[self.TIMEOUT],
            'disable_rollback': self.properties[self.DISABLE_ROLLBACK],
            'parameters': self.properties[self.PARAMETERS],
            'files': self.properties[self.FILES],
            'environment': self.properties[self.ENVIRONMENT],
        }

        try:
            stack = self.orchestration(obj).stack_create(**kwargs)

            # Timeout = None means we will use the 'default_action_timeout'
            # It can be overridden by the TIMEOUT profile propertie
            timeout = None
            if self.properties[self.TIMEOUT]:
                timeout = self.properties[self.TIMEOUT] * 60

            self.orchestration(obj).wait_for_stack(stack.id, 'CREATE_COMPLETE',
                                                   timeout=timeout)
            return stack.id
        except exc.InternalError as ex:
            raise exc.EResourceCreation(type='stack', message=ex.message)
Esempio n. 4
0
    def _get_master_cluster_info(self, obj):
        ctx = context.get_service_context(user_id=obj.user,
                                          project_id=obj.project)
        master = self.properties[self.MASTER_CLUSTER]
        try:
            cluster = cluster_obj.Cluster.find(ctx, master)
        except Exception as ex:
            raise exc.EResourceCreation(type='kubernetes.worker',
                                        message=six.text_type(ex))
        for key in self.MASTER_CLUSTER_KEYS:
            if key not in cluster.data:
                raise exc.EResourceCreation(
                    type='kubernetes.worker',
                    message="Can't find %s in cluster %s" % (key, master))

        return cluster.data
Esempio n. 5
0
    def post_lifecycle_hook_message(self, lifecycle_action_token, node_id,
                                    resource_id, lifecycle_transition_type):
        message_list = [{
            "ttl": CONF.notification.ttl,
            "body": {
                "lifecycle_action_token": lifecycle_action_token,
                "node_id": node_id,
                "resource_id": resource_id,
                "lifecycle_transition_type": lifecycle_transition_type
            }
        }]
        try:
            if not self.zaqar().queue_exists(self.queue_name):
                kwargs = {
                    "_max_messages_post_size":
                    CONF.notification.max_message_size,
                    "description": "Senlin lifecycle hook notification",
                    "name": self.queue_name
                }
                self.zaqar().queue_create(**kwargs)

            return self.zaqar().message_post(self.queue_name, message_list)
        except exception.InternalError as ex:
            raise exception.EResourceCreation(type='queue',
                                              message=six.text_type(ex))
Esempio n. 6
0
    def do_create(self, obj):
        """Create a container instance using the given profile.

        :param obj: The node object for this container.
        :returns: ID of the container instance or ``None`` if driver fails.
        :raises: `EResourceCreation`
        """
        name = self.properties[self.NAME]
        if name is None:
            name = '-'.join([obj.name, utils.random_name()])

        params = {
            'image': self.properties[self.IMAGE],
            'name': name,
            'command': self.properties[self.COMMAND],
        }

        try:
            ctx = context.get_service_context(project=obj.project,
                                              user=obj.user)
            dockerclient = self.docker(obj)
            db_api.node_add_dependents(ctx, self.host.id, obj.id)
            container = dockerclient.container_create(**params)
            dockerclient.start(container['Id'])
        except exc.InternalError as ex:
            raise exc.EResourceCreation(type='container', message=str(ex))

        self.container_id = container['Id'][:36]
        return self.container_id
Esempio n. 7
0
 def _build_trust(self):
     # Get zaqar trustee user ID for trust building
     auth = ks_loading.load_auth_from_conf_options(CONF, 'zaqar')
     session = ks_loading.load_session_from_conf_options(CONF, 'zaqar')
     zaqar_trustee_user_id = session.get_user_id(auth=auth)
     try:
         trust = self.keystone().trust_get_by_trustor(
             self.user, zaqar_trustee_user_id, self.project)
         if not trust:
             # Create a trust if no existing one found
             roles = self.notifier_roles
             for role in roles:
                 # Remove 'admin' role from delegated roles list
                 # unless it is the only role user has
                 if role == 'admin' and len(roles) > 1:
                     roles.remove(role)
             trust = self.keystone().trust_create(self.user,
                                                  zaqar_trustee_user_id,
                                                  self.project, roles)
     except exc.InternalError as ex:
         msg = _('Can not build trust between user %(user)s and zaqar '
                 'service user %(zaqar)s for receiver %(receiver)s.') % {
                     'user': self.user,
                     'zaqar': zaqar_trustee_user_id,
                     'receiver': self.id
                 }
         LOG.error(msg)
         raise exc.EResourceCreation(type='trust', message=ex.message)
     return trust.id
Esempio n. 8
0
    def test_do_create_invalid_image(self):
        profile = server.ServerProfile('s2', self.spec)
        err = exc.EResourceCreation(type='server', message='boom')
        mock_image = self.patchobject(profile,
                                      '_validate_image',
                                      side_effect=err)
        node_obj = mock.Mock()

        self.assertRaises(exc.EResourceCreation, profile.do_create, node_obj)

        mock_image.assert_called_once_with(node_obj, 'FAKE_IMAGE', 'create')
Esempio n. 9
0
    def test_do_create_invalid_keypair(self):
        profile = server.ServerProfile('s2', self.spec)
        self._stubout_profile(profile, mock_image=True, mock_flavor=True)
        err = exc.EResourceCreation(type='server', message='boom')
        mock_kp = self.patchobject(profile,
                                   '_validate_keypair',
                                   side_effect=err)
        node_obj = mock.Mock()

        self.assertRaises(exc.EResourceCreation, profile.do_create, node_obj)

        mock_kp.assert_called_once_with(node_obj, 'FAKE_KEYNAME', 'create')
Esempio n. 10
0
    def _validate_az(self, obj, az_name, reason=None):
        try:
            res = self.compute(obj).validate_azs([az_name])
        except exc.InternalError as ex:
            if reason == 'create':
                raise exc.EResourceCreation(type='server',
                                            message=six.text_type(ex))
            else:
                raise

        if not res:
            msg = _("The specified %(key)s '%(value)s' could not be found") % {
                'key': self.AVAILABILITY_ZONE,
                'value': az_name
            }
            if reason == 'create':
                raise exc.EResourceCreation(type='server', message=msg)
            else:
                raise exc.InvalidSpec(message=msg)

        return az_name
Esempio n. 11
0
    def test_do_recover_with_recreate_failed_create(self):
        profile = self._create_profile('test-profile')
        self.patchobject(profile, 'do_delete', return_value=True)
        err = exception.EResourceCreation(type='STACK', message='BANNG')
        self.patchobject(profile, 'do_create', side_effect=err)

        ex = self.assertRaises(exception.EResourceOperation,
                               profile.do_recover,
                               mock.Mock(id='NODE_ID'),
                               operation='RECREATE')
        msg = ("Failed in recovering node NODE_ID: Failed in creating "
               "STACK: BANNG.")
        self.assertEqual(msg, six.text_type(ex))
Esempio n. 12
0
    def _create_queue(self):
        queue_name = "senlin-receiver-%s" % self.id
        kwargs = {
            "_max_messages_post_size": CONF.receiver.max_message_size,
            "description": "Senlin receiver %s." % self.id,
            "name": queue_name
        }
        try:
            self.zaqar().queue_create(**kwargs)
        except exc.InternalError as ex:
            raise exc.EResourceCreation(type='queue', message=ex.message)

        return queue_name
Esempio n. 13
0
    def test_node_create_not_created(self, mock_create, mock_status):

        node = nodem.Node('node1', PROFILE_ID, CLUSTER_ID, self.context)
        mock_create.side_effect = exception.EResourceCreation(
            type='PROFILE', message='Boom', resource_id='test_id')

        res = node.do_create(self.context)

        self.assertFalse(res)
        mock_status.assert_any_call(self.context, consts.NS_CREATING,
                                    'Creation in progress')
        mock_status.assert_any_call(self.context, consts.NS_ERROR,
                                    'Failed in creating PROFILE: Boom.',
                                    physical_id='test_id')
Esempio n. 14
0
 def _set_security_group_rules(self, obj, sgid):
     client = self.network(obj)
     open_ports = {
         'tcp':
         [22, 80, 8000, 8080, 6443, 8001, 8443, 443, 179, 8082, 8086],
         'udp': [8285, 8472],
         'icmp': [None]
     }
     for p in open_ports.keys():
         for port in open_ports[p]:
             try:
                 client.security_group_rule_create(sgid, port, protocol=p)
             except Exception as ex:
                 raise exc.EResourceCreation(type='kubernetes',
                                             message=str(ex))
Esempio n. 15
0
    def _create_security_group(self, obj):
        ctx = context.get_service_context(user_id=obj.user,
                                          project_id=obj.project)
        sgid = obj.data.get(self.SECURITY_GROUP, None)
        if sgid:
            return sgid

        client = self.network(obj)
        try:
            sg = client.security_group_create(name=self.name)
        except Exception as ex:
            raise exc.EResourceCreation(type='kubernetes', message=str(ex))
        data = obj.data
        data[self.SECURITY_GROUP] = sg.id
        cluster_obj.Cluster.update(ctx, obj.id, {'data': data})
        self._set_security_group_rules(obj, sg.id)

        return sg.id
Esempio n. 16
0
 def _validate_keypair(self, obj, name_or_id, reason=None):
     try:
         return self.compute(obj).keypair_find(name_or_id, False)
     except exc.InternalError as ex:
         if reason == 'create':
             raise exc.EResourceCreation(type='server',
                                         message=six.text_type(ex))
         elif reason == 'update':
             raise exc.EResourceUpdate(type='server',
                                       id=obj.physical_id,
                                       message=six.text_type(ex))
         elif ex.code == 404:
             msg = _("The specified %(k)s '%(v)s' could not be found.") % {
                 'k': self.KEY_NAME,
                 'v': name_or_id
             }
             raise exc.InvalidSpec(message=msg)
         else:
             raise
Esempio n. 17
0
    def _create_subscription(self, queue_name):
        subscriber = self._generate_subscriber_url()
        trust_id = self._build_trust()

        # FIXME(Yanyanhu): For Zaqar doesn't support to create a
        # subscription that never expires, we specify a very large
        # ttl value which doesn't exceed the max time of python.
        kwargs = {
            "ttl": 2**36,
            "subscriber": subscriber,
            "options": {
                "trust_id": trust_id
            }
        }
        try:
            subscription = self.zaqar().subscription_create(
                queue_name, **kwargs)
        except exc.InternalError as ex:
            raise exc.EResourceCreation(type='subscription', message=str(ex))
        return subscription
Esempio n. 18
0
    def test_do_create_invalid_network(self):
        cc = mock.Mock()
        nc = mock.Mock()
        node_obj = mock.Mock(id='FAKE_NODE_ID',
                             data={},
                             index=123,
                             cluster_id='FAKE_CLUSTER_ID')
        spec = {
            'type': 'os.nova.server',
            'version': '1.0',
            'properties': {
                'flavor': 'FLAV',
                'image': 'FAKE_IMAGE',
                'key_name': 'FAKE_KEYNAME',
                'name': 'FAKE_SERVER_NAME',
                'networks': [{
                    'network': 'FAKE_NET'
                }]
            }
        }

        profile = server.ServerProfile('s2', spec)
        profile._computeclient = cc
        profile._networkclient = nc
        self._stubout_profile(profile,
                              mock_image=True,
                              mock_flavor=True,
                              mock_keypair=True)
        err = exc.EResourceCreation(type='server', message='FOO')
        mock_net = self.patchobject(profile,
                                    '_validate_network',
                                    side_effect=err)

        self.assertRaises(exc.EResourceCreation, profile.do_create, node_obj)
        mock_net.assert_called_once_with(node_obj, {
            'network': 'FAKE_NET',
            'port': None,
            'fixed_ip': None
        }, 'create')
Esempio n. 19
0
    def test_post_lifecycle_hook_message_queue_retry(self, mock_zaqar):
        cfg.CONF.set_override('max_message_size', 8192, 'notification')
        mock_zc = mock.Mock()
        mock_zaqar.return_value = mock_zc
        queue_name = 'my_queue'
        message = mmod.Message(queue_name)
        mock_zc.queue_exists.return_value = True
        test_exception = exception.EResourceCreation(type='queue',
                                                     message="test")
        mock_zc.message_post.side_effect = [
            test_exception, test_exception, None
        ]

        lifecycle_action_token = 'ACTION_ID'
        node_id = 'NODE_ID'
        resource_id = 'RESOURCE_ID'
        lifecycle_transition_type = 'TYPE'

        message.post_lifecycle_hook_message(lifecycle_action_token, node_id,
                                            resource_id,
                                            lifecycle_transition_type)

        mock_zc.queue_create.assert_not_called()
        self.assertEqual(3, mock_zc.message_post.call_count)
Esempio n. 20
0
    def do_create(self, obj):
        """Create a server for the node object.

        :param obj: The node object for which a server will be created.
        """
        kwargs = {}
        for key in self.KEYS:
            # context is treated as connection parameters
            if key == self.CONTEXT:
                continue

            if self.properties[key] is not None:
                kwargs[key] = self.properties[key]

        admin_pass = self.properties[self.ADMIN_PASS]
        if admin_pass:
            kwargs.pop(self.ADMIN_PASS)
            kwargs['adminPass'] = admin_pass

        auto_disk_config = self.properties[self.AUTO_DISK_CONFIG]
        kwargs.pop(self.AUTO_DISK_CONFIG)
        kwargs['OS-DCF:diskConfig'] = 'AUTO' if auto_disk_config else 'MANUAL'

        image_ident = self.properties[self.IMAGE]
        if image_ident is not None:
            image = self._validate_image(obj, image_ident, 'create')
            kwargs.pop(self.IMAGE)
            kwargs['imageRef'] = image.id

        flavor_ident = self.properties[self.FLAVOR]
        flavor = self._validate_flavor(obj, flavor_ident, 'create')
        kwargs.pop(self.FLAVOR)
        kwargs['flavorRef'] = flavor.id

        keypair_name = self.properties[self.KEY_NAME]
        if keypair_name:
            keypair = self._validate_keypair(obj, keypair_name, 'create')
            kwargs['key_name'] = keypair.name

        kwargs['name'] = self.properties[self.NAME] or obj.name

        metadata = self._build_metadata(obj, self.properties[self.METADATA])
        kwargs['metadata'] = metadata

        block_device_mapping_v2 = self.properties[self.BLOCK_DEVICE_MAPPING_V2]
        if block_device_mapping_v2 is not None:
            kwargs['block_device_mapping_v2'] = self._resolve_bdm(
                block_device_mapping_v2)

        user_data = self.properties[self.USER_DATA]
        if user_data is not None:
            ud = encodeutils.safe_encode(user_data)
            kwargs['user_data'] = encodeutils.safe_decode(base64.b64encode(ud))

        networks = self.properties[self.NETWORKS]
        if networks is not None:
            kwargs['networks'] = []
            for net_spec in networks:
                net = self._validate_network(obj, net_spec, 'create')
                kwargs['networks'].append(net)

        secgroups = self.properties[self.SECURITY_GROUPS]
        if secgroups:
            kwargs['security_groups'] = [{'name': sg} for sg in secgroups]

        if 'placement' in obj.data:
            if 'zone' in obj.data['placement']:
                kwargs['availability_zone'] = obj.data['placement']['zone']

            if 'servergroup' in obj.data['placement']:
                group_id = obj.data['placement']['servergroup']
                hints = self.properties.get(self.SCHEDULER_HINTS, {})
                hints.update({'group': group_id})
                kwargs['scheduler_hints'] = hints

        server = None
        resource_id = 'UNKNOWN'
        try:
            server = self.compute(obj).server_create(**kwargs)
            self.compute(obj).wait_for_server(server.id)
            return server.id
        except exc.InternalError as ex:
            if server and server.id:
                resource_id = server.id
            raise exc.EResourceCreation(type='server',
                                        message=ex.message,
                                        resource_id=resource_id)
Esempio n. 21
0
    def _validate_network(self, obj, network, reason=None):
        result = {}
        error = None
        # check network
        net_ident = network.get(self.NETWORK)
        if net_ident:
            try:
                net = self.network(obj).network_get(net_ident)
                if reason == 'update':
                    result['net_id'] = net.id
                else:
                    result['uuid'] = net.id
            except exc.InternalError as ex:
                error = six.text_type(ex)

        # check port
        port_ident = network.get(self.PORT)
        if not error and port_ident:
            try:
                port = self.network(obj).port_find(port_ident)
                if port.status != 'DOWN':
                    error = _(
                        "The status of the port %(port)s must be DOWN") % {
                            'port': port_ident
                        }

                if reason == 'update':
                    result['port_id'] = port.id
                else:
                    result['port'] = port.id
            except exc.InternalError as ex:
                error = six.text_type(ex)
        elif port_ident is None and net_ident is None:
            error = _("'%(port)s' is required if '%(net)s' is omitted") % {
                'port': self.PORT,
                'net': self.NETWORK
            }

        fixed_ip = network.get(self.FIXED_IP)
        if not error and fixed_ip:
            if port_ident is not None:
                error = _("The '%(port)s' property and the '%(fixed_ip)s' "
                          "property cannot be specified at the same time") % {
                              'port': self.PORT,
                              'fixed_ip': self.FIXED_IP
                          }
            else:
                if reason == 'update':
                    result['fixed_ips'] = [{'ip_address': fixed_ip}]
                else:
                    result['fixed_ip'] = fixed_ip

        if error:
            if reason == 'create':
                raise exc.EResourceCreation(type='server', message=error)
            elif reason == 'update':
                raise exc.EResourceUpdate(type='server',
                                          id=obj.physical_id,
                                          message=error)
            else:
                raise exc.InvalidSpec(message=error)

        return result
Esempio n. 22
0
    def do_create(self, obj):
        """Create a server for the node object.

        :param obj: The node object for which a server will be created.
        """
        kwargs = {}
        for key in self.KEYS:
            if self.properties[key] is not None:
                kwargs[key] = self.properties[key]

        image_ident = self.properties[self.IMAGE]
        if image_ident is not None:
            image = self._validate_image(obj, image_ident, 'create')
            kwargs.pop(self.IMAGE)
            kwargs['imageRef'] = image.id

        flavor_ident = self.properties[self.FLAVOR]
        flavor = self._validate_flavor(obj, flavor_ident, 'create')
        kwargs.pop(self.FLAVOR)
        kwargs['flavorRef'] = flavor.id

        keypair_name = self.properties[self.KEY_NAME]
        if keypair_name:
            keypair = self._validate_keypair(obj, keypair_name, 'create')
            kwargs['key_name'] = keypair.name

        kwargs['name'] = obj.name

        metadata = self._build_metadata(obj, {})
        kwargs['metadata'] = metadata

        jj_vars = {}
        cluster_data = self._get_cluster_data(obj)
        kwargs['networks'] = [{'uuid': cluster_data[self.PRIVATE_NETWORK]}]

        # Get user_data parameters from metadata
        jj_vars['KUBETOKEN'] = cluster_data[self.KUBEADM_TOKEN]
        jj_vars['MASTER_FLOATINGIP'] = cluster_data[
            self.KUBE_MASTER_FLOATINGIP]

        block_device_mapping_v2 = self.properties[self.BLOCK_DEVICE_MAPPING_V2]
        if block_device_mapping_v2 is not None:
            kwargs['block_device_mapping_v2'] = self._resolve_bdm(
                obj, block_device_mapping_v2, 'create')

        # user_data = self.properties[self.USER_DATA]
        user_data = base.loadScript('./scripts/master.sh')
        if user_data is not None:
            # Use jinja2 to replace variables defined in user_data
            try:
                jj_t = jinja2.Template(user_data)
                user_data = jj_t.render(**jj_vars)
            except (jinja2.exceptions.UndefinedError, ValueError) as ex:
                # TODO(anyone) Handle jinja2 error
                pass
            ud = encodeutils.safe_encode(user_data)
            kwargs['user_data'] = encodeutils.safe_decode(base64.b64encode(ud))

        sgid = self._get_security_group(obj)
        kwargs['security_groups'] = [{'name': sgid}]

        server = None
        resource_id = None
        try:
            server = self.compute(obj).server_create(**kwargs)
            self.compute(obj).wait_for_server(server.id)
            server = self.compute(obj).server_get(server.id)
            self._update_master_ip(obj, server.addresses[''][0]['addr'])
            self._associate_floatingip(obj, server)
            LOG.info("Created master node: %s" % server.id)
            return server.id
        except exc.InternalError as ex:
            if server and server.id:
                resource_id = server.id
            raise exc.EResourceCreation(type='server',
                                        message=six.text_type(ex),
                                        resource_id=resource_id)