def delete(self, subcloud_ref):
        """Delete a subcloud.

        :param subcloud_ref: ID or name of subcloud to delete.
        """
        context = restcomm.extract_context_from_environ()
        subcloud = None

        if subcloud_ref.isdigit():
            # Look up subcloud as an ID
            try:
                subcloud = db_api.subcloud_get(context, subcloud_ref)
            except exceptions.SubcloudNotFound:
                pecan.abort(404, _('Subcloud not found'))
        else:
            # Look up subcloud by name
            try:
                subcloud = db_api.subcloud_get_by_name(context, subcloud_ref)
            except exceptions.SubcloudNameNotFound:
                pecan.abort(404, _('Subcloud not found'))

        subcloud_id = subcloud.id

        try:
            # Ask dcmanager-manager to delete the subcloud.
            # It will do all the real work...
            return self.rpc_client.delete_subcloud(context, subcloud_id)
        except RemoteError as e:
            pecan.abort(422, e.value)
        except Exception as e:
            LOG.exception(e)
            pecan.abort(500, _('Unable to delete subcloud'))
    def patch(self, subcloud_ref=None):
        """Update a subcloud.

        :param subcloud_ref: ID or name of subcloud to update
        """

        context = restcomm.extract_context_from_environ()
        subcloud = None

        if subcloud_ref is None:
            pecan.abort(400, _('Subcloud ID required'))

        payload = eval(request.body)
        if not payload:
            pecan.abort(400, _('Body required'))

        if subcloud_ref.isdigit():
            # Look up subcloud as an ID
            try:
                subcloud = db_api.subcloud_get(context, subcloud_ref)
            except exceptions.SubcloudNotFound:
                pecan.abort(404, _('Subcloud not found'))
        else:
            # Look up subcloud by name
            try:
                subcloud = db_api.subcloud_get_by_name(context, subcloud_ref)
            except exceptions.SubcloudNameNotFound:
                pecan.abort(404, _('Subcloud not found'))

        subcloud_id = subcloud.id

        management_state = payload.get('management-state')
        description = payload.get('description')
        location = payload.get('location')

        if not (management_state or description or location):
            pecan.abort(400, _('nothing to update'))

        # Syntax checking
        if management_state and \
                management_state not in [consts.MANAGEMENT_UNMANAGED,
                                         consts.MANAGEMENT_MANAGED]:
            pecan.abort(400, _('Invalid management-state'))

        try:
            # Inform dcmanager-manager that subcloud has been updated.
            # It will do all the real work...
            subcloud = self.rpc_client.update_subcloud(
                context,
                subcloud_id,
                management_state=management_state,
                description=description,
                location=location)
            return subcloud
        except RemoteError as e:
            pecan.abort(422, e.value)
        except Exception as e:
            # additional exceptions.
            LOG.exception(e)
            pecan.abort(500, _('Unable to update subcloud'))
Example #3
0
    def get(self, subcloud_ref=None):
        """Get details about software update options.

        :param subcloud: name or id of subcloud (optional)
        """
        context = restcomm.extract_context_from_environ()

        if subcloud_ref is None:
            # List of all subcloud options requested.
            # Prepend the all clouds default options to the result.

            result = dict()
            result['sw-update-options'] = list()

            default_sw_update_opts_dict = utils.get_sw_update_opts(context)

            result['sw-update-options'].append(default_sw_update_opts_dict)

            subclouds = db_api.sw_update_opts_get_all_plus_subcloud_info(
                context)

            for subcloud, sw_update_opts in subclouds:
                if sw_update_opts:
                    result['sw-update-options'].append(
                        db_api.sw_update_opts_w_name_db_model_to_dict(
                            sw_update_opts, subcloud.name))

            return result

        elif subcloud_ref == consts.DEFAULT_REGION_NAME:
            # Default options requested, guaranteed to succeed

            return utils.get_sw_update_opts(context)

        else:
            # Specific subcloud options requested

            if subcloud_ref.isdigit():
                # Look up subcloud as an ID
                try:
                    subcloud = db_api.subcloud_get(context, subcloud_ref)
                except exceptions.SubcloudNotFound:
                    pecan.abort(404, _('Subcloud not found'))
            else:
                # Look up subcloud by name
                try:
                    subcloud = db_api.subcloud_get_by_name(
                        context, subcloud_ref)
                except exceptions.SubcloudNameNotFound:
                    pecan.abort(404, _('Subcloud not found'))

            try:
                return utils.get_sw_update_opts(context,
                                                subcloud_id=subcloud.id)
            except Exception as e:
                pecan.abort(404, _('%s') % e)
Example #4
0
    def get(self, steps=None, cloud_name=None):
        """Get details about software update strategy.

        :param steps: get the steps for this strategy (optional)
        :param cloud_name: name of cloud (optional)
        """
        context = restcomm.extract_context_from_environ()

        if steps is None:
            # Strategy requested
            strategy = None
            try:
                strategy = db_api.sw_update_strategy_get(context)
            except exceptions.NotFound:
                pecan.abort(404, _('Strategy not found'))

            strategy_dict = db_api.sw_update_strategy_db_model_to_dict(
                strategy)
            return strategy_dict

        elif steps == "steps":
            # Steps for the strategy requested
            if cloud_name is None:
                # List of steps requested
                result = dict()
                result['strategy-steps'] = list()
                strategy_steps = db_api.strategy_step_get_all(context)
                for strategy_step in strategy_steps:
                    result['strategy-steps'].append(
                        db_api.strategy_step_db_model_to_dict(strategy_step))

                return result
            else:
                # Single step requested
                strategy_step = None
                if cloud_name == consts.SYSTEM_CONTROLLER_NAME:
                    # The system controller step does not map to a subcloud,
                    # so has no name.
                    try:
                        strategy_step = db_api.strategy_step_get(context, None)
                    except exceptions.StrategyStepNotFound:
                        pecan.abort(404, _('Strategy step not found'))
                else:
                    try:
                        strategy_step = db_api.strategy_step_get_by_name(
                            context, cloud_name)
                    except exceptions.StrategyStepNameNotFound:
                        pecan.abort(404, _('Strategy step not found'))

                strategy_step_dict = db_api.strategy_step_db_model_to_dict(
                    strategy_step)
                return strategy_step_dict
Example #5
0
    def delete(self):
        """Delete the software update strategy."""
        context = restcomm.extract_context_from_environ()

        try:
            # Ask dcmanager-manager to delete the strategy.
            # It will do all the real work...
            return self.rpc_client.delete_sw_update_strategy(context)
        except RemoteError as e:
            pecan.abort(422, e.value)
        except Exception as e:
            LOG.exception(e)
            pecan.abort(500, _('Unable to delete strategy'))
 def _get_alarm_aggregates(self):
     summary = []
     context = restcomm.extract_context_from_environ()
     alarms = self.dcorch_rpc_client.get_alarm_summary(context)
     for alarm in alarms:
         alarm_dict = {
             'region_name': alarm['region_name'],
             'uuid': alarm['uuid'],
             'critical_alarms': alarm['critical_alarms'],
             'major_alarms': alarm['major_alarms'],
             'minor_alarms': alarm['minor_alarms'],
             'warnings': alarm['warnings'],
             'cloud_status': alarm['cloud_status']
         }
         summary.append(alarm_dict)
     return {'alarm_summary': summary}
Example #7
0
    def delete(self, subcloud_ref):
        """Delete the software update options."""

        context = restcomm.extract_context_from_environ()

        if subcloud_ref == consts.DEFAULT_REGION_NAME:
            # Delete defaults.
            # Note by deleting these, the next get will repopulate with
            # the global constants.

            try:
                db_api.sw_update_opts_default_destroy(context)
            except Exception:
                return
        else:

            if subcloud_ref.isdigit():
                # Look up subcloud as an ID
                try:
                    subcloud = db_api.subcloud_get(context, subcloud_ref)
                except exceptions.SubcloudNotFound:
                    pecan.abort(404, _('Subcloud not found'))

            else:
                # Look up subcloud by name
                try:
                    subcloud = db_api.subcloud_get_by_name(
                        context, subcloud_ref)
                except exceptions.SubcloudNameNotFound:
                    pecan.abort(404, _('Subcloud not found'))

            # Delete the subcloud specific options
            if db_api.sw_update_opts_get(context, subcloud.id):
                db_api.sw_update_opts_destroy(context, subcloud.id)
            else:
                pecan.abort(404, _('Subcloud patch options not found'))
    def post(self, subcloud_ref=None, qualifier=None):
        """Create a new subcloud.

        :param subcloud_ref: ID of or name subcloud (only used when generating
                             config)
        :param qualifier: if 'config', returns the config INI file for the
                          subcloud
        """

        context = restcomm.extract_context_from_environ()

        if subcloud_ref is None:
            payload = eval(request.body)
            if not payload:
                pecan.abort(400, _('Body required'))
            name = payload.get('name')
            if not name:
                pecan.abort(400, _('name required'))
            management_subnet = payload.get('management-subnet')
            if not management_subnet:
                pecan.abort(400, _('management-subnet required'))
            management_start_ip = payload.get('management-start-ip')
            if not management_start_ip:
                pecan.abort(400, _('management-start-ip required'))
            management_end_ip = payload.get('management-end-ip')
            if not management_end_ip:
                pecan.abort(400, _('management-end-ip required'))
            management_gateway_ip = payload.get('management-gateway-ip')
            if not management_gateway_ip:
                pecan.abort(400, _('management-gateway-ip required'))
            systemcontroller_gateway_ip = \
                payload.get('systemcontroller-gateway-ip')
            if not systemcontroller_gateway_ip:
                pecan.abort(400, _('systemcontroller-gateway-ip required'))

            self._validate_subcloud_config(context, name, management_subnet,
                                           management_start_ip,
                                           management_end_ip,
                                           management_gateway_ip,
                                           systemcontroller_gateway_ip)

            try:
                # Ask dcmanager-manager to add the subcloud.
                # It will do all the real work...
                return self.rpc_client.add_subcloud(context, payload)
            except RemoteError as e:
                pecan.abort(422, e.value)
            except Exception as e:
                LOG.exception(e)
                pecan.abort(500, _('Unable to create subcloud'))
        elif qualifier:
            if qualifier == 'config':
                subcloud = None

                if subcloud_ref.isdigit():
                    # Look up subcloud as an ID
                    try:
                        subcloud = db_api.subcloud_get(context, subcloud_ref)
                    except exceptions.SubcloudNotFound:
                        pecan.abort(404, _('Subcloud not found'))
                else:
                    # Look up subcloud by name
                    try:
                        subcloud = db_api.subcloud_get_by_name(
                            context, subcloud_ref)
                    except exceptions.SubcloudNameNotFound:
                        pecan.abort(404, _('Subcloud not found'))

                payload = dict()
                if request.body:
                    payload = eval(request.body)
                config_file = self._create_subcloud_config_file(
                    context, subcloud, payload)
                result = dict()
                result['config'] = config_file
                return result
            else:
                pecan.abort(400, _('Invalid request'))
        else:
            pecan.abort(400, _('Invalid request'))
    def get(self, subcloud_ref=None, qualifier=None):
        """Get details about subcloud.

        :param subcloud_ref: ID or name of subcloud
        """
        context = restcomm.extract_context_from_environ()

        if subcloud_ref is None:
            # List of subclouds requested
            subclouds = db_api.subcloud_get_all_with_status(context)
            result = dict()
            result['subclouds'] = []
            first_time = True
            subcloud_list = []
            subcloud_status_list = []

            # We get back a subcloud, subcloud_status pair for every
            # subcloud_status entry corresponding to a subcloud.  (Subcloud
            # info repeats)
            # Aggregate all the sync status for each of the
            # endpoints per subcloud into an overall sync status
            for subcloud, subcloud_status in subclouds:
                subcloud_dict = db_api.subcloud_db_model_to_dict(subcloud)
                subcloud_status_dict = db_api.subcloud_status_db_model_to_dict(
                    subcloud_status)
                subcloud_dict.update(subcloud_status_dict)

                if not first_time:
                    if subcloud_list[-1]['id'] == subcloud_dict['id']:
                        # We have a match for this subcloud id already,
                        # check if we have a same sync_status
                        if subcloud_list[-1][consts.SYNC_STATUS] != \
                                subcloud_dict[consts.SYNC_STATUS]:
                            subcloud_list[-1][consts.SYNC_STATUS] = \
                                consts.SYNC_STATUS_OUT_OF_SYNC

                        if subcloud_status:
                            subcloud_status_list.append(
                                db_api.
                                subcloud_endpoint_status_db_model_to_dict(  # noqa
                                    subcloud_status))
                        subcloud_list[-1][
                            consts.ENDPOINT_SYNC_STATUS] = subcloud_status_list

                    else:
                        subcloud_status_list = []
                        if subcloud_status:
                            subcloud_status_list.append(
                                db_api.
                                subcloud_endpoint_status_db_model_to_dict(  # noqa
                                    subcloud_status))

                        subcloud_list.append(subcloud_dict)
                else:
                    if subcloud_status:
                        subcloud_status_list.append(
                            db_api.subcloud_endpoint_status_db_model_to_dict(
                                subcloud_status))
                    subcloud_list.append(subcloud_dict)

                first_time = False

            for s in subcloud_list:
                result['subclouds'].append(s)

            return result
        else:
            # Single subcloud requested
            subcloud = None
            subcloud_dict = dict()
            subcloud_status_list = []
            endpoint_sync_dict = dict()

            if subcloud_ref.isdigit():
                # Look up subcloud as an ID
                try:
                    subcloud = db_api.subcloud_get(context, subcloud_ref)
                except exceptions.SubcloudNotFound:
                    pecan.abort(404, _('Subcloud not found'))
            else:
                # Look up subcloud by name
                try:
                    subcloud = db_api.subcloud_get_by_name(
                        context, subcloud_ref)
                except exceptions.SubcloudNameNotFound:
                    pecan.abort(404, _('Subcloud not found'))

            subcloud_id = subcloud.id

            if qualifier:
                # Configuration for this subcloud requested.
                # Encrypt before sending.
                if qualifier == 'config':
                    result = dict()
                    user_list = self._get_subcloud_users()

                    # Use a hash of the subcloud name + management subnet
                    # as the encryption key
                    hashstring = subcloud.name + subcloud.management_subnet
                    h = MD5.new()
                    h.update(hashstring)
                    encryption_key = h.hexdigest()
                    user_list_string = json.dumps(user_list)
                    user_list_encrypted = crypt.urlsafe_encrypt(
                        encryption_key, user_list_string)
                    result['users'] = user_list_encrypted
                    return result
                else:
                    pecan.abort(400, _('Invalid request'))
            else:
                # Data for this subcloud requested
                # Build up and append a dictionary of the endpoints
                # sync status to the result.
                for subcloud, subcloud_status in db_api. \
                        subcloud_get_with_status(context, subcloud_id):
                    subcloud_dict = db_api.subcloud_db_model_to_dict(subcloud)
                    # may be empty subcloud_status entry, account for this
                    if subcloud_status:
                        subcloud_status_list.append(
                            db_api.subcloud_endpoint_status_db_model_to_dict(
                                subcloud_status))
                endpoint_sync_dict = {
                    consts.ENDPOINT_SYNC_STATUS: subcloud_status_list
                }
                subcloud_dict.update(endpoint_sync_dict)

                return subcloud_dict
Example #10
0
    def post(self, subcloud_ref=None):
        """Update or create sw update options.

        :param subcloud: name or id of subcloud (optional)
        """

        # Note creating or updating subcloud specific options require
        # setting all options.

        context = restcomm.extract_context_from_environ()

        payload = eval(request.body)
        if not payload:
            pecan.abort(400, _('Body required'))

        if subcloud_ref == consts.DEFAULT_REGION_NAME:

            # update default options
            subcloud_name = consts.SW_UPDATE_DEFAULT_TITLE

            if db_api.sw_update_opts_default_get(context):
                # entry already in db, update it.
                try:
                    sw_update_opts_ref = db_api.sw_update_opts_default_update(
                        context, payload['storage-apply-type'],
                        payload['compute-apply-type'],
                        payload['max-parallel-computes'],
                        payload['alarm-restriction-type'],
                        payload['default-instance-action'])
                except Exception as e:
                    LOG.exception(e)
                    raise e
            else:
                # no entry in db, create one.
                try:
                    sw_update_opts_ref = db_api.sw_update_opts_default_create(
                        context, payload['storage-apply-type'],
                        payload['compute-apply-type'],
                        payload['max-parallel-computes'],
                        payload['alarm-restriction-type'],
                        payload['default-instance-action'])
                except Exception as e:
                    LOG.exception(e)
                    raise e
        else:
            # update subcloud options

            if subcloud_ref.isdigit():
                # Look up subcloud as an ID
                try:
                    subcloud = db_api.subcloud_get(context, subcloud_ref)
                except exceptions.SubcloudNotFound:
                    pecan.abort(404, _('Subcloud not found'))

                subcloud_name = subcloud.name

            else:
                # Look up subcloud by name
                try:
                    subcloud = db_api.subcloud_get_by_name(
                        context, subcloud_ref)
                except exceptions.SubcloudNameNotFound:
                    pecan.abort(404, _('Subcloud not found'))

                subcloud_name = subcloud_ref

            sw_update_opts = db_api.sw_update_opts_get(context, subcloud.id)

            if sw_update_opts is None:
                sw_update_opts_ref = db_api.sw_update_opts_create(
                    context, subcloud.id, payload['storage-apply-type'],
                    payload['compute-apply-type'],
                    payload['max-parallel-computes'],
                    payload['alarm-restriction-type'],
                    payload['default-instance-action'])

            else:
                # a row is present in table, update
                sw_update_opts_ref = db_api.sw_update_opts_update(
                    context, subcloud.id, payload['storage-apply-type'],
                    payload['compute-apply-type'],
                    payload['max-parallel-computes'],
                    payload['alarm-restriction-type'],
                    payload['default-instance-action'])

        return db_api.sw_update_opts_w_name_db_model_to_dict(
            sw_update_opts_ref, subcloud_name)
Example #11
0
    def post(self, actions=None):
        """Create a new software update strategy."""
        context = restcomm.extract_context_from_environ()

        payload = eval(request.body)
        if not payload:
            pecan.abort(400, _('Body required'))

        if actions is None:
            # Validate any options that were supplied
            strategy_type = payload.get('type')
            if not strategy_type:
                pecan.abort(400, _('type required'))
            if strategy_type not in consts.SW_UPDATE_TYPE_PATCH:
                pecan.abort(400, _('type invalid'))

            subcloud_apply_type = payload.get('subcloud-apply-type')
            if subcloud_apply_type is not None:
                if subcloud_apply_type not in [
                        consts.SUBCLOUD_APPLY_TYPE_PARALLEL,
                        consts.SUBCLOUD_APPLY_TYPE_SERIAL
                ]:
                    pecan.abort(400, _('subcloud-apply-type invalid'))

            max_parallel_subclouds_str = payload.get('max-parallel-subclouds')
            if max_parallel_subclouds_str is not None:
                max_parallel_subclouds = None
                try:
                    max_parallel_subclouds = int(max_parallel_subclouds_str)
                except ValueError:
                    pecan.abort(400, _('max-parallel-subclouds invalid'))
                # TODO(Bart): Decide on a maximum
                if max_parallel_subclouds < 1 or max_parallel_subclouds > 100:
                    pecan.abort(400, _('max-parallel-subclouds invalid'))

            stop_on_failure = payload.get('stop-on-failure')
            if stop_on_failure is not None:
                if stop_on_failure not in ["true", "false"]:
                    pecan.abort(400, _('stop-on-failure invalid'))

            try:
                # Ask dcmanager-manager to create the strategy.
                # It will do all the real work...
                return self.rpc_client.create_sw_update_strategy(
                    context, payload)
            except RemoteError as e:
                pecan.abort(422, e.value)
            except Exception as e:
                LOG.exception(e)
                pecan.abort(500, _('Unable to create strategy'))
        elif actions == 'actions':
            # Apply or abort a strategy
            action = payload.get('action')
            if not action:
                pecan.abort(400, _('action required'))
            if action == consts.SW_UPDATE_ACTION_APPLY:
                try:
                    # Ask dcmanager-manager to apply the strategy.
                    # It will do all the real work...
                    return self.rpc_client.apply_sw_update_strategy(context)
                except RemoteError as e:
                    pecan.abort(422, e.value)
                except Exception as e:
                    LOG.exception(e)
                    pecan.abort(500, _('Unable to apply strategy'))
            elif action == consts.SW_UPDATE_ACTION_ABORT:
                try:
                    # Ask dcmanager-manager to abort the strategy.
                    # It will do all the real work...
                    return self.rpc_client.abort_sw_update_strategy(context)
                except RemoteError as e:
                    pecan.abort(422, e.value)
                except Exception as e:
                    LOG.exception(e)
                    pecan.abort(500, _('Unable to abort strategy'))