Beispiel #1
0
    def post(self, node_ident, callback_url):
        """Process a heartbeat from the deploy ramdisk.

        :param node_ident: the UUID or logical name of a node.
        :param callback_url: the URL to reach back to the ramdisk.
        :raises: NodeNotFound if node with provided UUID or name was not found.
        :raises: InvalidUuidOrName if node_ident is not valid name or UUID.
        :raises: NoValidHost if RPC topic for node could not be retrieved.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:node:ipa_heartbeat', cdict, cdict)

        rpc_node = api_utils.get_rpc_node(node_ident)

        try:
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
        except exception.NoValidHost as e:
            e.code = http_client.BAD_REQUEST
            raise

        pecan.request.rpcapi.heartbeat(pecan.request.context,
                                       rpc_node.uuid, callback_url,
                                       topic=topic)
    def post(self, node_ident, callback_url):
        """Process a heartbeat from the deploy ramdisk.

        :param node_ident: the UUID or logical name of a node.
        :param callback_url: the URL to reach back to the ramdisk.
        :raises: NodeNotFound if node with provided UUID or name was not found.
        :raises: InvalidUuidOrName if node_ident is not valid name or UUID.
        :raises: NoValidHost if RPC topic for node could not be retrieved.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:node:ipa_heartbeat', cdict, cdict)

        rpc_node = api_utils.get_rpc_node(node_ident)

        try:
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
        except exception.NoValidHost as e:
            e.code = http_client.BAD_REQUEST
            raise

        pecan.request.rpcapi.heartbeat(pecan.request.context,
                                       rpc_node.uuid,
                                       callback_url,
                                       topic=topic)
Beispiel #3
0
    def post(self, node_ident, callback_url, agent_version=None,
             agent_token=None):
        """Process a heartbeat from the deploy ramdisk.

        :param node_ident: the UUID or logical name of a node.
        :param callback_url: the URL to reach back to the ramdisk.
        :param agent_version: The version of the agent that is heartbeating.
            ``None`` indicates that the agent that is heartbeating is a version
            before sending agent_version was introduced so agent v3.0.0 (the
            last release before sending agent_version was introduced) will be
            assumed.
        :param agent_token: randomly generated validation token.
        :raises: NodeNotFound if node with provided UUID or name was not found.
        :raises: InvalidUuidOrName if node_ident is not valid name or UUID.
        :raises: NoValidHost if RPC topic for node could not be retrieved.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        if agent_version and not api_utils.allow_agent_version_in_heartbeat():
            raise exception.InvalidParameterValue(
                _('Field "agent_version" not recognised'))

        cdict = api.request.context.to_policy_values()
        policy.authorize('baremetal:node:ipa_heartbeat', cdict, cdict)

        rpc_node = api_utils.get_rpc_node_with_suffix(node_ident)
        dii = rpc_node['driver_internal_info']
        agent_url = dii.get('agent_url')
        # If we have an agent_url on file, and we get something different
        # we should fail because this is unexpected behavior of the agent.
        if agent_url is not None and agent_url != callback_url:
            LOG.error('Received heartbeat for node %(node)s with '
                      'callback URL %(url)s. This is not expected, '
                      'and the heartbeat will not be processed.',
                      {'node': rpc_node.uuid, 'url': callback_url})
            raise exception.Invalid(
                _('Detected change in ramdisk provided '
                  '"callback_url"'))
        # NOTE(TheJulia): If tokens are required, lets go ahead and fail the
        # heartbeat very early on.
        token_required = CONF.require_agent_token
        if token_required and agent_token is None:
            LOG.error('Agent heartbeat received for node %(node)s '
                      'without an agent token.', {'node': node_ident})
            raise exception.InvalidParameterValue(
                _('Agent token is required for heartbeat processing.'))

        try:
            topic = api.request.rpcapi.get_topic_for(rpc_node)
        except exception.NoValidHost as e:
            e.code = http_client.BAD_REQUEST
            raise

        api.request.rpcapi.heartbeat(
            api.request.context, rpc_node.uuid, callback_url,
            agent_version, agent_token, topic=topic)
Beispiel #4
0
    def post(self, node_ident, callback_url, agent_version=None):
        """Process a heartbeat from the deploy ramdisk.

        :param node_ident: the UUID or logical name of a node.
        :param callback_url: the URL to reach back to the ramdisk.
        :param agent_version: The version of the agent that is heartbeating.
            ``None`` indicates that the agent that is heartbeating is a version
            before sending agent_version was introduced so agent v3.0.0 (the
            last release before sending agent_version was introduced) will be
            assumed.
        :raises: NodeNotFound if node with provided UUID or name was not found.
        :raises: InvalidUuidOrName if node_ident is not valid name or UUID.
        :raises: NoValidHost if RPC topic for node could not be retrieved.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        if agent_version and not api_utils.allow_agent_version_in_heartbeat():
            raise exception.InvalidParameterValue(
                _('Field "agent_version" not recognised'))

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:node:ipa_heartbeat', cdict, cdict)

        rpc_node = api_utils.get_rpc_node_with_suffix(node_ident)

        try:
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
        except exception.NoValidHost as e:
            e.code = http_client.BAD_REQUEST
            raise

        pecan.request.rpcapi.heartbeat(pecan.request.context,
                                       rpc_node.uuid,
                                       callback_url,
                                       agent_version,
                                       topic=topic)
Beispiel #5
0
    def get_all(self, addresses=None, node_uuid=None):
        """Look up a node by its MAC addresses and optionally UUID.

        If the "restrict_lookup" option is set to True (the default), limit
        the search to nodes in certain transient states (e.g. deploy wait).

        :param addresses: list of MAC addresses for a node.
        :param node_uuid: UUID of a node.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        :raises: NotFound if suitable node was not found.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:driver:ipa_lookup', cdict, cdict)

        if not addresses and not node_uuid:
            raise exception.IncompleteLookup()

        try:
            if node_uuid:
                node = objects.Node.get_by_uuid(
                    pecan.request.context, node_uuid)
            else:
                node = objects.Node.get_by_port_addresses(
                    pecan.request.context, addresses)
        except exception.NotFound:
            # NOTE(dtantsur): we are reraising the same exception to make sure
            # we don't disclose the difference between nodes that are not found
            # at all and nodes in a wrong state by different error messages.
            raise exception.NotFound()

        if (CONF.api.restrict_lookup and
                node.provision_state not in _LOOKUP_ALLOWED_STATES):
            raise exception.NotFound()

        return LookupResult.convert_with_links(node)
Beispiel #6
0
    def post(self, node_ident, callback_url):
        """Process a heartbeat from the deploy ramdisk.

        :param node_ident: the UUID or logical name of a node.
        :param callback_url: the URL to reach back to the ramdisk.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:node:ipa_heartbeat', cdict, cdict)

        rpc_node = api_utils.get_rpc_node(node_ident)

        try:
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
        except exception.NoValidHost as e:
            e.code = http_client.BAD_REQUEST
            raise

        pecan.request.rpcapi.heartbeat(pecan.request.context,
                                       rpc_node.uuid, callback_url,
                                       topic=topic)
Beispiel #7
0
    def post(self, node_ident, callback_url):
        """Process a heartbeat from the deploy ramdisk.

        :param node_ident: the UUID or logical name of a node.
        :param callback_url: the URL to reach back to the ramdisk.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:node:ipa_heartbeat', cdict, cdict)

        rpc_node = api_utils.get_rpc_node(node_ident)

        try:
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
        except exception.NoValidHost as e:
            e.code = http_client.BAD_REQUEST
            raise

        pecan.request.rpcapi.heartbeat(pecan.request.context,
                                       rpc_node.uuid, callback_url,
                                       topic=topic)
Beispiel #8
0
    def get_all(self, addresses=None, node_uuid=None):
        """Look up a node by its MAC addresses and optionally UUID.

        If the "restrict_lookup" option is set to True (the default), limit
        the search to nodes in certain transient states (e.g. deploy wait).

        :param addresses: list of MAC addresses for a node.
        :param node_uuid: UUID of a node.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        :raises: NotFound if suitable node was not found or node's provision
            state is not allowed for the lookup.
        :raises: IncompleteLookup if neither node UUID nor any valid MAC
            address was provided.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:driver:ipa_lookup', cdict, cdict)

        # Validate the list of MAC addresses
        if addresses is None:
            addresses = []

        valid_addresses = []
        invalid_addresses = []
        for addr in addresses:
            try:
                mac = utils.validate_and_normalize_mac(addr)
                valid_addresses.append(mac)
            except exception.InvalidMAC:
                invalid_addresses.append(addr)

        if invalid_addresses:
            node_log = ('' if not node_uuid else '(Node UUID: %s)' % node_uuid)
            LOG.warning(
                'The following MAC addresses "%(addrs)s" are '
                'invalid and will be ignored by the lookup '
                'request %(node)s', {
                    'addrs': ', '.join(invalid_addresses),
                    'node': node_log
                })

        if not valid_addresses and not node_uuid:
            raise exception.IncompleteLookup()

        try:
            if node_uuid:
                node = objects.Node.get_by_uuid(pecan.request.context,
                                                node_uuid)
            else:
                node = objects.Node.get_by_port_addresses(
                    pecan.request.context, valid_addresses)
        except exception.NotFound:
            # NOTE(dtantsur): we are reraising the same exception to make sure
            # we don't disclose the difference between nodes that are not found
            # at all and nodes in a wrong state by different error messages.
            raise exception.NotFound()

        if (CONF.api.restrict_lookup
                and node.provision_state not in _LOOKUP_ALLOWED_STATES):
            raise exception.NotFound()

        return LookupResult.convert_with_links(node)
Beispiel #9
0
 def test_allow_ramdisk_endpoints(self, mock_request):
     mock_request.version.minor = 22
     self.assertTrue(utils.allow_ramdisk_endpoints())
     mock_request.version.minor = 21
     self.assertFalse(utils.allow_ramdisk_endpoints())
Beispiel #10
0
 def convert():
     v1 = V1()
     v1.id = "v1"
     v1.links = [
         link.Link.make_link('self',
                             pecan.request.public_url,
                             'v1',
                             '',
                             bookmark=True),
         link.Link.make_link('describedby',
                             'http://docs.openstack.org',
                             'developer/ironic/dev',
                             'api-spec-v1.html',
                             bookmark=True,
                             type='text/html')
     ]
     v1.media_types = [
         MediaType('application/json',
                   'application/vnd.openstack.ironic.v1+json')
     ]
     v1.chassis = [
         link.Link.make_link('self', pecan.request.public_url, 'chassis',
                             ''),
         link.Link.make_link('bookmark',
                             pecan.request.public_url,
                             'chassis',
                             '',
                             bookmark=True)
     ]
     v1.nodes = [
         link.Link.make_link('self', pecan.request.public_url, 'nodes', ''),
         link.Link.make_link('bookmark',
                             pecan.request.public_url,
                             'nodes',
                             '',
                             bookmark=True)
     ]
     v1.ports = [
         link.Link.make_link('self', pecan.request.public_url, 'ports', ''),
         link.Link.make_link('bookmark',
                             pecan.request.public_url,
                             'ports',
                             '',
                             bookmark=True)
     ]
     if utils.allow_portgroups():
         v1.portgroups = [
             link.Link.make_link('self', pecan.request.public_url,
                                 'portgroups', ''),
             link.Link.make_link('bookmark',
                                 pecan.request.public_url,
                                 'portgroups',
                                 '',
                                 bookmark=True)
         ]
     v1.drivers = [
         link.Link.make_link('self', pecan.request.public_url, 'drivers',
                             ''),
         link.Link.make_link('bookmark',
                             pecan.request.public_url,
                             'drivers',
                             '',
                             bookmark=True)
     ]
     if utils.allow_volume():
         v1.volume = [
             link.Link.make_link('self', pecan.request.public_url, 'volume',
                                 ''),
             link.Link.make_link('bookmark',
                                 pecan.request.public_url,
                                 'volume',
                                 '',
                                 bookmark=True)
         ]
     v1.books = [
         link.Link.make_link('self', pecan.request.public_url, 'books', ''),
         link.Link.make_link('bookmark',
                             pecan.request.public_url,
                             'books',
                             '',
                             bookmark=True)
     ]
     if utils.allow_ramdisk_endpoints():
         v1.lookup = [
             link.Link.make_link('self', pecan.request.public_url, 'lookup',
                                 ''),
             link.Link.make_link('bookmark',
                                 pecan.request.public_url,
                                 'lookup',
                                 '',
                                 bookmark=True)
         ]
         v1.heartbeat = [
             link.Link.make_link('self', pecan.request.public_url,
                                 'heartbeat', ''),
             link.Link.make_link('bookmark',
                                 pecan.request.public_url,
                                 'heartbeat',
                                 '',
                                 bookmark=True)
         ]
     return v1
Beispiel #11
0
 def convert():
     v1 = V1()
     v1.id = "v1"
     v1.links = [link.Link.make_link('self', pecan.request.public_url,
                                     'v1', '', bookmark=True),
                 link.Link.make_link('describedby',
                                     'https://docs.openstack.org',
                                     '/ironic/latest/contributor/',
                                     'webapi.html',
                                     bookmark=True, type='text/html')
                 ]
     v1.media_types = [MediaType('application/json',
                       'application/vnd.openstack.ironic.v1+json')]
     v1.chassis = [link.Link.make_link('self', pecan.request.public_url,
                                       'chassis', ''),
                   link.Link.make_link('bookmark',
                                       pecan.request.public_url,
                                       'chassis', '',
                                       bookmark=True)
                   ]
     v1.nodes = [link.Link.make_link('self', pecan.request.public_url,
                                     'nodes', ''),
                 link.Link.make_link('bookmark',
                                     pecan.request.public_url,
                                     'nodes', '',
                                     bookmark=True)
                 ]
     v1.ports = [link.Link.make_link('self', pecan.request.public_url,
                                     'ports', ''),
                 link.Link.make_link('bookmark',
                                     pecan.request.public_url,
                                     'ports', '',
                                     bookmark=True)
                 ]
     if utils.allow_portgroups():
         v1.portgroups = [
             link.Link.make_link('self', pecan.request.public_url,
                                 'portgroups', ''),
             link.Link.make_link('bookmark', pecan.request.public_url,
                                 'portgroups', '', bookmark=True)
         ]
     v1.drivers = [link.Link.make_link('self', pecan.request.public_url,
                                       'drivers', ''),
                   link.Link.make_link('bookmark',
                                       pecan.request.public_url,
                                       'drivers', '',
                                       bookmark=True)
                   ]
     if utils.allow_volume():
         v1.volume = [
             link.Link.make_link('self',
                                 pecan.request.public_url,
                                 'volume', ''),
             link.Link.make_link('bookmark',
                                 pecan.request.public_url,
                                 'volume', '',
                                 bookmark=True)
         ]
     if utils.allow_ramdisk_endpoints():
         v1.lookup = [link.Link.make_link('self', pecan.request.public_url,
                                          'lookup', ''),
                      link.Link.make_link('bookmark',
                                          pecan.request.public_url,
                                          'lookup', '',
                                          bookmark=True)
                      ]
         v1.heartbeat = [link.Link.make_link('self',
                                             pecan.request.public_url,
                                             'heartbeat', ''),
                         link.Link.make_link('bookmark',
                                             pecan.request.public_url,
                                             'heartbeat', '',
                                             bookmark=True)
                         ]
     if utils.allow_expose_conductors():
         v1.conductors = [link.Link.make_link('self',
                                              pecan.request.public_url,
                                              'conductors', ''),
                          link.Link.make_link('bookmark',
                                              pecan.request.public_url,
                                              'conductors', '',
                                              bookmark=True)
                          ]
     if utils.allow_allocations():
         v1.allocations = [link.Link.make_link('self',
                                               pecan.request.public_url,
                                               'allocations', ''),
                           link.Link.make_link('bookmark',
                                               pecan.request.public_url,
                                               'allocations', '',
                                               bookmark=True)
                           ]
     if utils.allow_expose_events():
         v1.events = [link.Link.make_link('self', pecan.request.public_url,
                                          'events', ''),
                      link.Link.make_link('bookmark',
                                          pecan.request.public_url,
                                          'events', '',
                                          bookmark=True)
                      ]
     if utils.allow_deploy_templates():
         v1.deploy_templates = [
             link.Link.make_link('self',
                                 pecan.request.public_url,
                                 'deploy_templates', ''),
             link.Link.make_link('bookmark',
                                 pecan.request.public_url,
                                 'deploy_templates', '',
                                 bookmark=True)
         ]
     v1.version = version.default_version()
     return v1
Beispiel #12
0
    def post(self,
             node_ident,
             callback_url,
             agent_version=None,
             agent_token=None,
             agent_verify_ca=None,
             agent_status=None,
             agent_status_message=None):
        """Process a heartbeat from the deploy ramdisk.

        :param node_ident: the UUID or logical name of a node.
        :param callback_url: the URL to reach back to the ramdisk.
        :param agent_version: The version of the agent that is heartbeating.
            ``None`` indicates that the agent that is heartbeating is a version
            before sending agent_version was introduced so agent v3.0.0 (the
            last release before sending agent_version was introduced) will be
            assumed.
        :param agent_token: randomly generated validation token.
        :param agent_verify_ca: TLS certificate to use to connect to the agent.
        :param agent_status: Current status of the heartbeating agent. Used by
            anaconda ramdisk to send status back to Ironic. The valid states
            are 'start', 'end', 'error'
        :param agent_status_message: Optional status message describing current
            agent_status
        :raises: NodeNotFound if node with provided UUID or name was not found.
        :raises: InvalidUuidOrName if node_ident is not valid name or UUID.
        :raises: NoValidHost if RPC topic for node could not be retrieved.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        if agent_version and not api_utils.allow_agent_version_in_heartbeat():
            raise exception.InvalidParameterValue(
                _('Field "agent_version" not recognised'))

        if ((agent_status or agent_status_message)
                and not api_utils.allow_status_in_heartbeat()):
            raise exception.InvalidParameterValue(
                _('Fields "agent_status" and "agent_status_message" '
                  'not recognised.'))

        api_utils.check_policy('baremetal:node:ipa_heartbeat')

        if (agent_verify_ca is not None
                and not api_utils.allow_verify_ca_in_heartbeat()):
            raise exception.InvalidParameterValue(
                _('Field "agent_verify_ca" not recognised in this version'))

        rpc_node = api_utils.get_rpc_node_with_suffix(node_ident)
        dii = rpc_node['driver_internal_info']
        agent_url = dii.get('agent_url')
        # If we have an agent_url on file, and we get something different
        # we should fail because this is unexpected behavior of the agent.
        if agent_url is not None and agent_url != callback_url:
            LOG.error(
                'Received heartbeat for node %(node)s with '
                'callback URL %(url)s. This is not expected, '
                'and the heartbeat will not be processed.', {
                    'node': rpc_node.uuid,
                    'url': callback_url
                })
            raise exception.Invalid(
                _('Detected change in ramdisk provided '
                  '"callback_url"'))
        # NOTE(TheJulia): If tokens are required, lets go ahead and fail the
        # heartbeat very early on.
        if agent_token is None:
            LOG.error(
                'Agent heartbeat received for node %(node)s '
                'without an agent token.', {'node': node_ident})
            raise exception.InvalidParameterValue(
                _('Agent token is required for heartbeat processing.'))

        if agent_status is not None and agent_status not in AGENT_VALID_STATES:
            valid_states = ','.join(AGENT_VALID_STATES)
            LOG.error(
                'Agent heartbeat received for node %(node)s '
                'has an invalid agent status: %(agent_status)s. '
                'Valid states are %(valid_states)s ', {
                    'node': node_ident,
                    'agent_status': agent_status,
                    'valid_states': valid_states
                })
            msg = (_('Agent status is invalid. Valid states are %s.') %
                   valid_states)
            raise exception.InvalidParameterValue(msg)

        try:
            topic = api.request.rpcapi.get_topic_for(rpc_node)
        except exception.NoValidHost as e:
            e.code = http_client.BAD_REQUEST
            raise

        api.request.rpcapi.heartbeat(api.request.context,
                                     rpc_node.uuid,
                                     callback_url,
                                     agent_version,
                                     agent_token,
                                     agent_verify_ca,
                                     agent_status,
                                     agent_status_message,
                                     topic=topic)
Beispiel #13
0
    def get_all(self, addresses=None, node_uuid=None):
        """Look up a node by its MAC addresses and optionally UUID.

        If the "restrict_lookup" option is set to True (the default), limit
        the search to nodes in certain transient states (e.g. deploy wait).

        :param addresses: list of MAC addresses for a node.
        :param node_uuid: UUID of a node.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        :raises: NotFound if suitable node was not found.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:driver:ipa_lookup', cdict, cdict)

        # Validate the list of MAC addresses
        if addresses is None:
            addresses = []

        valid_addresses = []
        invalid_addresses = []
        for addr in addresses:
            try:
                mac = utils.validate_and_normalize_mac(addr)
                valid_addresses.append(mac)
            except exception.InvalidMAC:
                invalid_addresses.append(addr)

        if invalid_addresses:
            node_log = ('' if not node_uuid
                        else _LW('(Node UUID: %s)') % node_uuid)
            LOG.warning(_LW('The following MAC addresses "%(addrs)s" are '
                            'invalid and will be ignored by the lookup '
                            'request %(node)s'),
                        {'addrs': ', '.join(invalid_addresses),
                         'node': node_log})

        if not valid_addresses and not node_uuid:
            raise exception.IncompleteLookup()

        try:
            if node_uuid:
                node = objects.Node.get_by_uuid(
                    pecan.request.context, node_uuid)
            else:
                node = objects.Node.get_by_port_addresses(
                    pecan.request.context, valid_addresses)
        except exception.NotFound:
            # NOTE(dtantsur): we are reraising the same exception to make sure
            # we don't disclose the difference between nodes that are not found
            # at all and nodes in a wrong state by different error messages.
            raise exception.NotFound()

        if (CONF.api.restrict_lookup and
                node.provision_state not in _LOOKUP_ALLOWED_STATES):
            raise exception.NotFound()

        return LookupResult.convert_with_links(node)
Beispiel #14
0
 def test_allow_ramdisk_endpoints(self, mock_request):
     mock_request.version.minor = 22
     self.assertTrue(utils.allow_ramdisk_endpoints())
     mock_request.version.minor = 21
     self.assertFalse(utils.allow_ramdisk_endpoints())
Beispiel #15
0
def v1():
    v1 = {
        'id':
        "v1",
        'links': [
            link.make_link('self',
                           api.request.public_url,
                           'v1',
                           '',
                           bookmark=True),
            link.make_link('describedby',
                           'https://docs.openstack.org',
                           '/ironic/latest/contributor/',
                           'webapi.html',
                           bookmark=True,
                           type='text/html')
        ],
        'media_types': {
            'base': 'application/json',
            'type': 'application/vnd.openstack.ironic.v1+json'
        },
        'chassis': [
            link.make_link('self', api.request.public_url, 'chassis', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'chassis',
                           '',
                           bookmark=True)
        ],
        'nodes': [
            link.make_link('self', api.request.public_url, 'nodes', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'nodes',
                           '',
                           bookmark=True)
        ],
        'ports': [
            link.make_link('self', api.request.public_url, 'ports', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'ports',
                           '',
                           bookmark=True)
        ],
        'drivers': [
            link.make_link('self', api.request.public_url, 'drivers', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'drivers',
                           '',
                           bookmark=True)
        ],
        'version':
        version.default_version()
    }
    if utils.allow_portgroups():
        v1['portgroups'] = [
            link.make_link('self', api.request.public_url, 'portgroups', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'portgroups',
                           '',
                           bookmark=True)
        ]
    if utils.allow_volume():
        v1['volume'] = [
            link.make_link('self', api.request.public_url, 'volume', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'volume',
                           '',
                           bookmark=True)
        ]
    if utils.allow_ramdisk_endpoints():
        v1['lookup'] = [
            link.make_link('self', api.request.public_url, 'lookup', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'lookup',
                           '',
                           bookmark=True)
        ]
        v1['heartbeat'] = [
            link.make_link('self', api.request.public_url, 'heartbeat', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'heartbeat',
                           '',
                           bookmark=True)
        ]
    if utils.allow_expose_conductors():
        v1['conductors'] = [
            link.make_link('self', api.request.public_url, 'conductors', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'conductors',
                           '',
                           bookmark=True)
        ]
    if utils.allow_allocations():
        v1['allocations'] = [
            link.make_link('self', api.request.public_url, 'allocations', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'allocations',
                           '',
                           bookmark=True)
        ]
    if utils.allow_expose_events():
        v1['events'] = [
            link.make_link('self', api.request.public_url, 'events', ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'events',
                           '',
                           bookmark=True)
        ]
    if utils.allow_deploy_templates():
        v1['deploy_templates'] = [
            link.make_link('self', api.request.public_url, 'deploy_templates',
                           ''),
            link.make_link('bookmark',
                           api.request.public_url,
                           'deploy_templates',
                           '',
                           bookmark=True)
        ]
    return v1
Beispiel #16
0
 def convert():
     v1 = V1()
     v1.id = "v1"
     v1.links = [link.Link.make_link('self', pecan.request.public_url,
                                     'v1', '', bookmark=True),
                 link.Link.make_link('describedby',
                                     'http://docs.openstack.org',
                                     'developer/ironic/dev',
                                     'api-spec-v1.html',
                                     bookmark=True, type='text/html')
                 ]
     v1.media_types = [MediaType('application/json',
                       'application/vnd.openstack.ironic.v1+json')]
     v1.chassis = [link.Link.make_link('self', pecan.request.public_url,
                                       'chassis', ''),
                   link.Link.make_link('bookmark',
                                       pecan.request.public_url,
                                       'chassis', '',
                                       bookmark=True)
                   ]
     v1.nodes = [link.Link.make_link('self', pecan.request.public_url,
                                     'nodes', ''),
                 link.Link.make_link('bookmark',
                                     pecan.request.public_url,
                                     'nodes', '',
                                     bookmark=True)
                 ]
     v1.ports = [link.Link.make_link('self', pecan.request.public_url,
                                     'ports', ''),
                 link.Link.make_link('bookmark',
                                     pecan.request.public_url,
                                     'ports', '',
                                     bookmark=True)
                 ]
     if utils.allow_portgroups():
         v1.portgroups = [
             link.Link.make_link('self', pecan.request.public_url,
                                 'portgroups', ''),
             link.Link.make_link('bookmark', pecan.request.public_url,
                                 'portgroups', '', bookmark=True)
         ]
     v1.drivers = [link.Link.make_link('self', pecan.request.public_url,
                                       'drivers', ''),
                   link.Link.make_link('bookmark',
                                       pecan.request.public_url,
                                       'drivers', '',
                                       bookmark=True)
                   ]
     if utils.allow_ramdisk_endpoints():
         v1.lookup = [link.Link.make_link('self', pecan.request.public_url,
                                          'lookup', ''),
                      link.Link.make_link('bookmark',
                                          pecan.request.public_url,
                                          'lookup', '',
                                          bookmark=True)
                      ]
         v1.heartbeat = [link.Link.make_link('self',
                                             pecan.request.public_url,
                                             'heartbeat', ''),
                         link.Link.make_link('bookmark',
                                             pecan.request.public_url,
                                             'heartbeat', '',
                                             bookmark=True)
                         ]
     return v1