Redfish Proxy for Ironic Node Power Controls

https://storyboard.openstack.org/#!/story/2009184

One important aspect of our goal of improving support for node multi-tenancy is to provide a seamless user experience for node lessees. This includes enabling lessees to use their existing provisioning workflows on leased nodes and to have these tools work as expected. Ironic policy does allow for lessees to access basic power controls through either the Ironic REST API or the openstack baremetal CLI; however, if such tools lack instructions for communicating with the Ironic API, the only way for them to function is by making requests directly to the BMC of the node they wish to provision. This would require giving the lessee BMC power credentials, which is especially problematic considering that one of the goals of node multi-tenancy is to enable this sort of functionality without giving the user such low-level access. [NMTSTORY] [NODELEAS]

Because such a solution is undesirable, to enable the use of existing provisioning tools, we instead intend to emulate a standards-based interface (Redfish, in this case) for use by node lessees. This interface will receive Redfish API calls such as those made by provisioning tools, perform the corresponding action within Ironic, and return a response in the format defined by the Redfish schema. Redfish clients will be able to authenticate in the way they expect to and these requests will be handled using the same authentication strategy as the rest of the existing Ironic infrastructure. If all goes according to plan, this feature will solve the compatibility problem previously described, and will do so without giving any special permissions to the lessee.

Problem description

The main concern here is compatibility– the problem in which a lessee has tools that expect to communicate via an inaccessible interface has two undesirable solutions.

The first is for the lessee’s workflow to be refactored to instead make use of the Ironic API. For the user this is both time and resource-consuming, especially considering these lessees will often have access to bare metal nodes for a limited timeframe.

The second is to provide the lessee with BMC credentials, which aside from going against the principles of node multi-tenancy, is a huge security risk. If these credentials are not limited in access scope, lessees could possibly damage or otherwise compromise the bare metal node. Additionally, if the provided credentials are not immediately revoked when the lessee is supposed to lose access to the node, they would retain access to the node’s power controls (and potentially more) until the credentials are changed.

These solutions potentially address the compatibility issue, but in turn, they create either a major efficiency issue or a major security issue. This feature intends to address compatibility without significantly compromising security or efficiency.

Proposed change

We will create a new WSGI service within the main Ironic repo which will serve a REST API at /redfish that to the end user, will function like a legitimate v1 Redfish endpoint, albeit with a limited feature set. This interface will provide minimal functionality, just enough to allow Redfish provisioning tools to set the power state of an Ironic node. In the future, this service could be extended to provide additional features, such as boot devices, boot modes, and virtual media; however, this is beyond the scope of what we aim to achieve in this spec.

Implementation details

The three key components necessary to achieve this goal are:

  1. a means by which users can be authenticated

  2. a way to determine the user’s identity (roles, projects, privileges, etc.)

  3. interfaces for performing operations on the nodes the user wishes to provision.

Broadly, the workflow for making use of this feature shall be as follows:

  1. Acquire credentials to be used for authenticating with the Ironic Redfish intermediary.

    • If the Ironic system in question uses Keystone for authentication, the user must create a set of application credentials scoped to the appropriate project(s) and domain.

    • If not, the user will authenticate via HTTP basic authentication, which will be handled using Ironic’s basic auth middleware. Configuring the backend where credentials are stored will be left up to individual Ironic system operators.

  2. (Keystone users only) Authenticate using the Redfish SessionService interface.

    • Keystone users will authenticate through the Redfish SessionService interface using the UUID of their newly created application credential as a username and the credential’s secret as a password. In response, they will receive a Redfish schema-compliant Session object in the body, as well as an authorization token and the URL of the newly created Session’s interface in the header.

  3. Perform the necessary provisioning operations.

    • All requests to Systems endpoints will require authentication; users who authenticated with the SessionService in step 2 must provide the X-Auth-Token they received in each request header, and users working with HTTP Basic Auth must provide base64-encoded credentials in each request header (as specified in [RFC7617]).

  4. (Keystone users only) End the Session created in step 2.

    • Keystone users will send a DELETE request to the URL of the Session object returned to them previously, internally revoking the created Keystone authentication token (note: not the application credential). If the user wishes to perform further actions, they will need to repeat the authentication process from step 2 again.

Authentication

The actions that this feature shall provide access to should only be accessed by certain users. The question of authentication is one of “is the person that is requesting access really who they claim to be?” How we are to answer this question depends on the authenticaton strategy in place on the Ironic system in question.

In the context of Keystone (v3), the question of “who is this person?” requires a few pieces of information– the user’s identifier, the identifier of the project they’re working on, and the identifier of the domain in which the user and project exist. However, Redfish expects only the identifier of the user (UUID or username) to determine identity and as such, authentication would end up requiring the Redfish user to provide more information than they would otherwise expect to provide, which poses a potential problem.

We intend to solve this problem through the use of application credentials, which specify the user, project, and domain they are scoped to. Since each application credential posesses a UUID, we can use this identifier in place of all the information that would otherwise be required by Keystone. [APPCREDS] This approach is also beneficial from a security standpoint, as it reduces the number of times raw user credentials are handled directly.

The user will pass the credential’s UUID and secret to the SessionService, where it will internally be passed along to Keystone for verification. If the information provided is valid, an authorization token will be created and sent back to the user in a format emulating that of a Redfish Session. Since Redfish Sessions are required to have a UUID, we will use the audit ID of the newly created Keystone auth token to satisfy this requirement. According to the Keystone API reference, “You can use these audit IDs to track the use of a token … without exposing the token ID to non-privileged users.” [KSTNEAPI] We want to make sure this proxy does not unintentionally expose sensitive information, and the decision to use audit IDs seems like a sensible one in the context of this problem.

Once the user is finished performing the provisioning actions they intend to carry out, they will send a DELETE request to the Session URL, as per the Redfish spec. Internally, this will revoke the Keystone authorization token, essentially “logging the user out.” This is the intended method for ending a user session, however it is important to note the difference between how Keystone and Redfish handle session expiration.

Redfish Sessions are designed to expire after a period of inactivity, while Keystone authorization tokens are designed to expire at a specific time (e.g. an hour or two after creation). We do not intend to mimic Redfish Session expiration, since we feel the added overhead and code complexity is not worth the minimal benefit this detail would provide. Auth tokens are ephemeral in nature, and it is up to the user to recognize this and account for the case of unexpected expiration, whether we implement this detail or not.

The authentication process for users of HTTP Basic Auth will be simple, as this strategy is standards-based (see [RFC7617]). The user will provide base64-encoded credentials with every request to a Redfish endpoint that expects a user to be authorized. Since Ironic supports basic authentication, implementing this will simply be a matter of passing the user’s credentials through the pre-existing basic auth middleware. Additionally, if basic auth is in use, the SessionService will be disabled and unusable.

Identity

Since application credentials are scoped upon creation, obtaining the pieces of information that constitute a user’s identity should be a straightforward process using the existing Ironic policy code and the Keystone middleware. We will use this information to determine what data, actions, etc. the user has access to via the same rules and methods as the existing Ironic API.

It is important to note that with basic auth, such policy-based access restrictions are essentially non-existent. If a user can log in, they will have access to all available data. However, since our basic auth strategy is Ironic’s basic auth, any extension to Ironic’s basic auth capability would in turn be an extension to the capability of this feature.

Provisioning Tools

The node provisioning tools that will be implemented here shall be functionally identical to existing Bare Metal endpoints, as shown here. The internal logic for achieving this functionality shall mirror that of the actual Ironic API as closely as possible; in theory the only difference should be in how requests by the user and responses to the user are formatted.

Emulated Redfish URI

Equivalent Ironic URI

[GET] /redfish/v1/SystemService/Systems

[GET] /v1/nodes

[GET] /redfish/v1/SystemService/Systems/{uuid}

[GET] /v1/nodes/{uuid}

[POST] /redfish/v1/SystemService/Systems/{uuid}

/Actions/ComputerSystem.Reset

[PUT] /v1/nodes/{uuid}

/states/power

This intermediary will abide by version 1.0.0 of the Redfish spec [RFSHSPEC] and schema [RFSHSCHM] for maximum backwards compatibility with existing tools. More details regarding the planned functionality of these endpoints will be elaborated upon below in the REST API Impact section.

Alternatives

The type of BMC interface emulation we’re looking to implement here does already exist in sushy-tools [SUSHY] and VirtualBMC [VIRTBMC], which emulate Redfish and IPMI respectively. A previous spec was submitted by Tzu-Mainn Chen (tzumainn) which proposed the idea of a sushy-tools driver in Ironic to enable this functionality, but concerns about security, along with the potential value of this existing in Ironic proper have led to the proposal of this spec. [PREVSPEC]

We currently plan on implementing this as a separate WSGI service within the Ironic repository, however it is possible to have both the Ironic API and this Redfish proxy run under the same service. Since both are separate, independent WSGI apps, a WSGI dispatcher, such as the Werkzeug application dispatcher middleware [WSGIDISP] could be used to achieve this.

Data model impact

None.

State Machine Impact

None.

REST API impact

No changes will be made to the Ironic API proper, rather, a new WSGI service hosting a new API will be created as described below. End-users shall be able to interact with this API as if it were a v1.0.0 Redfish endpoint (see [RFSHSPEC] and [RFSHSCHM]).

Since this is a new service, Ironic operators will need to account for the fact that it will need its own port and (if using Keystone) will need to be added as a new endpoint within Keystone. If this proves to be a significant enough inconvenience, however, it could be possible to launch both the Ironic API and this proxy within one service as described above under Alternatives.

Redfish API Versions:

  • GET /redfish

    • Returns the Redfish protocol version (v1). This will always return the same response shown below, as per the Redfish API spec. (section 6.2 of [RFSHSPEC])

    • Normal response code: 200 OK

    • Example response:

      {
          "v1": "/redfish/v1/"
      }
      

      Name

      Type

      Description

      v1

      string

      The URL of the Redfish v1 ServiceRoot.

  • GET /redfish/v1/

    • The Redfish service root URL, will return a Redfish ServiceRoot object containing information about what is available on the Redfish system.

    • Normal response code: 200 OK

    • Example response:

      {
          "@odata.type": "#ServiceRoot.v1_0_0.ServiceRoot",
          "Id": "IronicProxy",
          "Name": "Ironic Redfish Proxy",
          "RedfishVersion": "1.0.0",
          "Links": {
              "Sessions": {
                  "@odata.id": "/redfish/v1/SessionService/Sessions"
              }
          },
          "Systems": {
              "@odata.id": "/redfish/v1/Systems"
          },
          "SessionService": {
              "@odata.id": "/redfish/v1/SessionService"
          },
          "@odata.id": "/redfish/v1/"
      }
      

      Name

      Type

      Description

      @odata.type

      string

      The type of the emulated Redfish resource.

      @odata.id

      string

      A resource link.

      Id

      string

      The identifier for this specific resource.

      Name

      string

      The name of this specific ServiceRoot.

      Links

      object

      Contains objects that contain links to relevant resource collections.

      Systems

      object

      Contains a link to a collection of Systems resources.

      SessionService

      object

      Contains a link to the SessionsService resource.

      Sessions

      object

      Contains a link to a collection of Sessions resources.

      RedfishVersion

      string

      The version of this Redfish service.

Sessions

  • GET /redfish/v1/SessionService

    • Returns a Redfish SessionService object, containing information about how the SessionService and Session objects are configured.

      • If the underlying Ironic system is using HTTP basic auth, the SessionService will report itself to be disabled, and all Session- related functionality will be non-functional.

    • Normal response code: 200 OK

    • Error response codes: 404 Not Found, 500 Internal Server Error

      • 404 Not Found will be returned if the underlying Ironic system is not using Keystone authentication.

      • 500 Internal Server Error will be returned if the internal request to authenticate could not be fulfilled.

    • Example response:

      {
          "@odata.type": "#SessionService.v1_0_0.SessionService",
          "Id": "KeystoneAuthProxy",
          "Name": "Redfish Proxy for Keystone Authentication",
          "Status": {
              "State": "Enabled",
              "Health": "OK"
          },
          "ServiceEnabled": true,
          "SessionTimeout": 86400,
          "Sessions": {
              "@odata.id": "/redfish/v1/SessionService/Sessions"
          },
          "@odata.id": "/redfish/v1/SessionService"
      }
      

      Name

      Type

      Description

      @odata.type

      string

      The type of the emulated Redfish resource.

      @odata.id

      string

      A resource link.

      Id

      string

      The identifier for this specific resource.

      Name

      string

      The name of this specific resource.

      Status

      object

      An object containing service status info.

      State

      string

      The state of the service, one of either “Enabled” or “Disabled”.

      Health

      string

      The health of the service, typically “OK”. [1]

      ServiceEnabled

      bool

      Indicates whether the SessionService is enabled or not.

      SessionTimeout

      number

      The amount of time, in seconds, before a session expires due to inactivity. [2]

      Sessions

      object

      Contains a link to a collection of Session resources.

  • GET /redfish/v1/SessionService/Sessions

    • Returns a Redfish SessionCollection, containing a link to the Session being used to authenticate the request. Requires the user to provide valid authentication in the request header.

    • Normal response code: 200 OK

    • Error response codes: 401 Unauthorized, 404 Not Found, 500 Internal Server Error

      • 401 Unauthorized will be returned if authentication in the header field is either absent or invalid.

      • 404 Not Found will be returned if the underlying Ironic system is not using Keystone authentication.

      • 500 Internal Server Error will be returned if the internal request to authenticate could not be fulfilled.

    • Example response:

      {
          "@odata.type": "#SessionCollection.SessionCollection",
          "Name": "Ironic Proxy Session Collection",
          "Members@odata.count": 1,
          "Members": [
              {
                  "@odata.id": "/redfish/v1/SessionService/Sessions/ABC"
              }
          ],
          "@odata.id": "/redfish/v1/SessionService/Sessions"
      }
      

      Name

      Type

      Description

      @odata.type

      string

      The type of the emulated Redfish resource.

      @odata.id

      string

      A resource link.

      Name

      string

      The name of this specific resource.

      Members@odata.count

      number

      The number of Session interfaces present in the collection.

      Members

      array

      An array of objects that contain links to individual Session interfaces.

  • POST /redfish/v1/SessionService/Sessions

    • Requests Session authentication. A username and password is to be passed in the body, and upon success, the created Session object will be returned. Included in the headers of this response will be the authentication token in the X-Auth-Token header, and the link to the Session object in the Location header.

    • Normal response code: 201 Created

    • Error response codes: 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error

      • 400 Bad Request will be returned if the username/password fields are not present in the message body.

      • 401 Unauthorized will be returned if the credentials provided are invalid.

      • 404 Not Found will be returned if the underlying Ironic system is not using Keystone authentication.

      • 500 Internal Server Error will be returned if the internal request to authenticate could not be fulfilled.

    • Example Request:

      {
          "UserName": "85775665-c110-4b85-8989-e6162170b3ec",
          "Password": "its-a-secret-shhhhh"
      }
      

      Name

      Type

      Description

      UserName

      string

      The UUID of the Keystone application credential to be used for authentication.

      Password

      string

      The secret of said application credential.

    • Example Response:

      Location: /redfish/v1/SessionService/Sessions/identifier
      X-Auth-Token: super-duper-secret-aaaaaaaaaaaa
      
      {
          "@odata.id": "/redfish/v1/SessionService/Sessions/identifier",
          "@odata.type": "#Session.1.0.0.Session",
          "Id": "identifier",
          "Name": "user session",
          "UserName": "85775665-c110-4b85-8989-e6162170b3ec"
      }
      

      Name

      Type

      Description

      @odata.type

      string

      The type of the emulated Redfish resource.

      @odata.id

      string

      A resource link.

      Id

      string

      The identifier for this specific resource.

      Name

      string

      The name of this specific resource.

      UserName

      string

      The UUID of the application credential used for authentication.

  • GET /redfish/v1/SessionService/Sessions/{identifier}

    • Returns the Session with the identifier specified in the URL. Requires the user to provide valid authentication in the request header for the session they’re attempting to access.

    • Normal response code: 200 OK

    • Error response codes: 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error

      • 401 Unauthorized will be returned if authentication in the header field is either absent or invalid.

      • 403 Forbidden will be returned if authentication in the header field is valid but lacking proper authorization for the Session being accessed.

      • 404 Not Found will be returned if the identifier specified does not correspond to a legitimate Session ID or if the underlying Ironic system is not using Keystone authentication.

      • 500 Internal Server Error will be returned if the internal request to authenticate could not be fulfilled.

    • Example Response:

      {
          "@odata.id": "/redfish/v1/SessionService/Sessions/identifier",
          "@odata.type": "#Session.1.0.0.Session",
          "Id": "identifier",
          "Name": "user session",
          "UserName": "85775665-c110-4b85-8989-e6162170b3ec"
      }
      

      Name

      Type

      Description

      @odata.type

      string

      The type of the emulated Redfish resource.

      @odata.id

      string

      A resource link.

      Id

      string

      The identifier for this specific resource.

      Name

      string

      The name of this specific resource.

      UserName

      string

      The application credential used for authentication

  • DELETE /redfish/v1/SessionService/Sessions/{identifier}

    • Ends the session identified in the URL. Requires the user to provide valid authentication in the request header for the session they’re trying to end.

    • Normal response code: 204 No Content

    • Error response codes: 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error

      • 401 Unauthorized will be returned if authentication in the header field is either absent or invalid.

      • 403 Forbidden will be returned if authentication in the header field is valid but lacking proper authorization for the Session being accessed.

      • 404 Not Found will be returned if the identifier specified does not correspond to a legitimate Session ID or if the underlying Ironic system is not using Keystone authentication.

      • 500 Internal Server Error will be returned if the internal request to authenticate could not be fulfilled.

Node Management

  • GET /redfish/v1/Systems

    • Equivalent to baremetal node list, will return a collection of Redfish ComputerSystem interfaces that correspond to Ironic nodes. Requires the user to provide valid authentication in the request header for the resource they are trying to access.

    • Normal response code: 200 OK

    • Error response codes: 401 Unauthorized, 403 Forbidden, 500 Internal Server Error

      • 401 Unauthorized will be returned if the authentication in the header field is either absent or invalid.

      • 403 Forbidden will be returned if authentication in the header field is valid but lacking proper privileges for listing Bare Metal nodes.

      • 500 Internal Server Error will be returned if the internal request to the Bare Metal service could not be fulfilled.

    • Example Response:

      {
          "@odata.type": "#ComputerSystemCollection.ComputerSystemCollection",
          "Name": "Ironic Node Collection",
          "Members@odata.count": 2,
          "Members": [
              {
                  "@odata.id": "/redfish/v1/Systems/ABCDEFG"
              },
              {
                  "@odata.id": "/redfish/v1/Systems/HIJKLMNOP"
              }
          ],
          "@odata.id": "/redfish/v1/Systems"
      }
      

      Name

      Type

      Description

      @odata.type

      string

      The type of the emulated Redfish resource.

      @odata.id

      string

      A resource link.

      Name

      string

      The name of this specific resource.

      Members@odata.count

      number

      The number of System interfaces present in the collection.

      Members

      array

      An array of objects that contain links to individual System interfaces.

  • GET /redfish/v1/Systems/{node_ident}

    • Equivalent to baremetal node show, albeit with fewer details. Will return a Redfish System resource containing basic info, power info, and the location of the power control interface. Requires the user to provide valid authentication for the resource they are trying to access.

    • Normal response code: 200 OK

    • Error response codes: 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error

      • 401 Unauthorized will be returned if the authentication in the header field is either absent or invalid.

      • 403 Forbidden will be returned if authentication in the header field is valid but lacking proper privileges for the Bare Metal node being accessed.

      • 404 Not Found will be returned if the identifier specified does not correspond to a legitimate node UUID.

      • 500 Internal Server Error will be returned if the internal request to the Bare Metal service could not be fulfilled.

    • Example Response:

      {
          "@odata.type": "#ComputerSystem.v1.0.0.ComputerSystem",
          "Id": "ABCDEFG",
          "Name": "Baremetal Host ABC",
          "Description": "It's a computer",
          "UUID": "ABCDEFG",
          "PowerState": "On",
          "Actions": {
              "#ComputerSystem.Reset": {
                  "target": "/redfish/v1/Systems/ABCDEFG/Actions/ComputerSystem.Reset",
                  "ResetType@Redfish.AllowableValues": [
                      "On",
                      "ForceOn",
                      "ForceOff",
                      "ForceRestart",
                      "GracefulRestart",
                      "GracefulShutdown"
                  ]
              }
          },
          "@odata.id": "/redfish/v1/Systems/ABCDEFG"
      }
      

      Name

      Type

      Description

      @odata.type

      string

      The type of the emulated Redfish resource.

      @odata.id

      string

      A resource link.

      Id

      string

      The identifier for this specific resource. Equal to the corresponding Ironic node UUID.

      Name

      string

      The name of this specific resource. Equal to the name of the corresponding Ironic node if set, otherwise equal to the node UUID.

      Description

      string

      If the Ironic node has a description set, it will be returned here. If not, this field will not be returned.

      UUID

      string

      The UUID of this resource.

      PowerState

      string

      The current state of the node/System in question, one of either “On”, “Off”, “Powering On”, or “Powering Off”.

      Actions

      object

      Contains the defined actions that can be executed on this system.

      #ComputerSystem. Reset

      object

      Contains information about the “Reset” action.

      target

      string

      The URI of the Reset action interface.

      ResetType@Redfish. AllowableValues

      array

      An array of strings containing all the valid options this action provides.

  • POST /redfish/v1/Systems/{node_ident}/Actions/ComputerSystem.Reset

    • Invokes a Reset action to change the power state of the node/System. The type of Reset action to take should be specified in the request body. Requires the user to provide valid authentication in the request header for the resource they are attempting to access.

    • Accepts the following values for ResetType in the body [3]:

      • “On” (soft power on)

      • “ForceOn” (hard power on)

      • “GracefulShutdown” (soft power off)

      • “ForceOff” (hard power off)

      • “GracefulRestart” (soft reboot)

      • “ForceRestart” (hard reboot)

    • Normal response code: 202 Accepted

    • Error response codes: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 NodeLocked/ClientError, 500 Internal Server Error, 503 NoFreeConductorWorkers (for more on codes 409 and 503, see the details for PUT requests to /v1/nodes/{ident}/states/power in [IRONCAPI]):

      • 400 Bad Request will be returned if the “ResetType” field is not found in the message body, or if the field has an invalid value.

      • 401 Unauthorized will be returned if the authentication in the header field is either absent or invalid.

      • 403 Forbidden will be returned if authentication in the header field is valid but lacking proper privileges to perform the specified action on the Bare Metal node being accessed.

      • 404 Not Found will be returned if the identifier specified does not correspond to a legitimate node UUID.

      • 409 NodeLocked/ClientError is an error code specified in the Bare Metal API call this request is proxied to. The body of a 409 response will be the same as that which was received from the Bare Metal API.

      • 500 Internal Server Error will be returned if the internal request to the Bare Metal service could not be fulfilled.

      • 503 NoFreeConductorWorkers is an error code specified in the Bare Metal API call this request is proxied to. The body of a 503 response will be the same as that which was received from the Bare Metal API.

    • Example Request:

      X-Auth-Token: super-duper-secret-aaaaaaaaaaaa
      
      {
          "ResetType": "ForceOff"
      }
      

    Name

    Type

    Description

    ResetType

    string

    The type of Reset action to take (see above)

Client (CLI) impact

None.

“openstack baremetal” CLI

Though this addition would include new REST API endpoints, this feature merely provides another way for users to access already existing features within the Ironic API, which are already accessible from the openstack baremetal CLI.

“openstacksdk”

None.

RPC API impact

None.

Driver API impact

None.

Nova driver impact

None.

Ramdisk impact

None.

Security impact

The main consideration when it comes to the security of this feature is the addition of a new means of accessing Ironic hardware. However, this should not pose much of a new concern when it comes to security, since authentication shall be implemented in the same way and using the same midddlewares as the existing Ironic API. Nevertheless, great care will be taken to make sure that said integration with the existing auth middleware is safe and secure.

To mitigate further risk, generated application credentials can and should be limited in scope to only allow access to the parts of the Ironic API required by this intermediary. We will also require all requests to be performed over HTTPS, since session tokens, application credential secrets, and (base64- encoded) HTTP basic auth credentials will be sent in plain text.

Other end user impact

This will give end users an alternative way of accessing power controls, one compatible with existing Redfish provisioning tools. This means in theory, the majority of users won’t be making API calls directly, instead utilizing pre-existing Redfish-compatible software, such as Redfishtool.

Scalability impact

None.

Performance Impact

Since this shall be implemented as a separate WSGI service, some additional overhead will be required, although the impact should be minor, as it will not require the running of any periodic tasks nor the execution of any extraneous database queries.

Additionally, it should be noted that running this proxy service is completely optional on the part of the Ironic system operator; if one does not wish to use it, its existence can simply be ignored.

Other deployer impact

This feature should have no impact on those who do not wish to use it, as it must be ran separately and can be ignored. To prevent it from being started accidentally, operators shall be able to explicitly disable it in the Ironic configuration file.

Those who wish to make use of this feature must keep in mind that since it is currently being implemented as a separate WSGI service, it shall require at minimum its own port to be ran on. This can be useful if one wishes to have the Redfish proxy service bound to a different port or a different host IP from the Ironic API; however, it will require a new endpoint to be added via Keystone (if using Keystone), and may potentially require extra nework configuration on the part of the system administrator.

Developer impact

This new service shall be implemented in Flask, as opposed to Pecan, which is what the Ironic API currently uses. As such, all code written for this new feature shall be well-documented in order to maximize its readability to any Ironic devs unfamiliar with Flask.

It has been mentioned by TheJulia that in future, the Ironic dev team may want to look into migrating the Ironic API to use Flask, and this addition to the codebase may prove useful to those tasked with said migration.

Finally, the Sessions feature does not exist in sushy-tools; since this spec includes a planned implementation of it, it could possibly be a useful addition there. This basic Redfish proxy can also be extended in future to provide access to even more parts of an Ironic system through a Redfish-like interface to those who would find such functionality useful.

Implementation

Assignee(s)

Primary assignee:
Sam Zuk (sam_z / szuk) <szuk@redhat.com>
Other contributors:
Tzu-Mainn Chen (tzumainn) <tzumainn@redhat.com>

Work Items

  • Create the necessary API endpoints

    • Implement the Redfish System -> Ironic Node proxy

    • Implement the Redfish Session -> Keystone authentication proxy

    • Write unit tests and functional tests to ensure proper functionality

  • Write documentation for how to use and configure this functionality, for users, administrators, and developers.

  • Test this feature on real hardware in a way that mimics expected use cases.

Dependencies

None.

Testing

Functional testing will be required to ensure requests made to these new proxy endpoints result in the correct behavior when ran on an actual Ironic setup. Furthermore, rigorous test cases should be written to make extremely sure that no unauthorized access to node APIs is possible.

Upgrades and Backwards Compatibility

N/A

Documentation Impact

Documentation will need to be provided for the new API endpoints, along with the necessary instructions for how to enable and configure this feature (for operators), along with additional information end users may require, such as how to work with authentication tokens.

References