# A few ground rules how these tests are basically formatted:
#
# Because role permissions cascade. admin has member, and reader. etc.
# it doesn't make sense to explicitly check if admin or member *CAN*
# read an endpoint. The reader check should validate that they can
# unless there is a specific somehow restricted endpoint. In those
# cases, explicit tests should be added, but we're not really aware
# of any at this time. The approach is otherwise a bit of a shotgun
# approach. We're attempting to test owner, lessee, and a third party
# project scoped admin token in an attempt to try and cover all of our
# cases and permutations.
#
# A few differences from the system scoped tests. Project scoped API
# requests should return different filtered views. This means we need
# to actually count when we're doing GET requests on main controller
# endpoints. Not a big deal, but it helps make sure things are behaving
# as expected.
#
# One note regarding return codes. Third party admin, should mainly get
# 404 return codes as opposed to 403. Because their view is filtered,
# They can't find the resources to attempt to edit. This is a huge
# distinction because we also don't want to leak that something exists
# from a security point of view. If we don't return 404, and they get 403,
# they can determine that something is special, something is different,
# and from there try to determine *what* it is. The key in their case
# is the ID values, but they don't know that from the outside.
# This is also why third party admins should get 200s and empty lists,
# again the database query should be filtered. Third party admin,
# in essence serves as the primary negative test.
#
# Conventions. This file uses *can* and *cannot* along with the
# personal, an owner or lessee of either, admin, member, or reader
# rights, along with a third party admin in the name to hopefully
# provide clear insight into *what* and *what is not* allowed.

values:
  skip_reason: "These are fake reference values for YAML templating"
  # Project scoped admin token
  owner_admin_headers: &owner_admin_headers
    X-Auth-Token: 'owner-admin-token'
    X-Roles: admin,manager,member,reader
    X-Project-Id: 70e5e25a-2ca2-4cb1-8ae8-7d8739cee205
  owner_manager_headers: &owner_manager_headers
    X-Auth-Token: 'owner-manager-token'
    X-Roles: manager,member,reader
    X-Project-Id: 70e5e25a-2ca2-4cb1-8ae8-7d8739cee205
  # Project scoped other member token.
  owner_member_headers: &owner_member_headers
    X-Auth-Token: 'owner-member-token'
    X-Roles: member,reader
    X-Project-Id: 70e5e25a-2ca2-4cb1-8ae8-7d8739cee205
  # Project scoped reader Token
  owner_reader_headers: &owner_reader_headers
    X-Auth-Token: 'owner-reader-token'
    X-Roles: reader
    X-Project-Id: 70e5e25a-2ca2-4cb1-8ae8-7d8739cee205
  lessee_admin_headers: &lessee_admin_headers
    X-Auth-Token: 'lessee-admin-token'
    X-Project-Id: f11853c7-fa9c-4db3-a477-c9d8e0dbbf13
    X-Roles: admin,manager,member,reader
  lessee_manager_headers: &lessee_manager_headers
    X-Auth-Token: 'lessee-manager-token'
    X-Project-Id: f11853c7-fa9c-4db3-a477-c9d8e0dbbf13
    X-Roles: manager,member,reader
  lessee_member_headers: &lessee_member_headers
    X-Auth-Token: 'lessee-member-token'
    X-Project-Id: f11853c7-fa9c-4db3-a477-c9d8e0dbbf13
    X-Roles: member,reader
  lessee_reader_headers: &lessee_reader_headers
    X-Auth-Token: 'lessee-reader-token'
    X-Project-Id: f11853c7-fa9c-4db3-a477-c9d8e0dbbf13
    X-Roles: reader
  third_party_admin_headers: &third_party_admin_headers
    X-Auth-Token: 'third-party-admin-token'
    X-Project-Id: ae64129e-b188-4662-b014-4127f4366ee6
    X-Roles: admin,manager,member,reader
  service_headers: &service_headers
    X-Auth-Token: 'service-token'
    X-Project-Id: ae64129e-b188-4662-b014-4127f4366ee6
    X-Roles: service
  service_headers_owner_project: &service_headers_owner_project
    X-Auth-Token: 'service-token'
    X-Project-Id: 70e5e25a-2ca2-4cb1-8ae8-7d8739cee205
    X-Roles: service
  owner_project_id: &owner_project_id 70e5e25a-2ca2-4cb1-8ae8-7d8739cee205
  lessee_project_id: &lessee_project_id f11853c7-fa9c-4db3-a477-c9d8e0dbbf13
  owned_node_ident: &owned_node_ident 1ab63b9e-66d7-4cd7-8618-dddd0f9f7881
  lessee_node_ident: &lessee_node_ident 38d5abed-c585-4fce-a57e-a2ffc2a2ec6f
# Nodes - https://docs.openstack.org/api-ref/baremetal/?expanded=#nodes-nodes

# Based on nodes_post_admin test.
owner_admin_cannot_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *owner_admin_headers
  body: &node_post_body
    name: node
    driver: fake-driverz
  assert_status: 403
  self_manage_nodes: False

owner_admin_can_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *owner_admin_headers
  body: *node_post_body
  assert_status: 503
  self_manage_nodes: True

service_nodes_cannot_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *service_headers
  body: *node_post_body
  assert_status: 403
  self_manage_nodes: False

service_nodes_can_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *service_headers
  body: *node_post_body
  assert_status: 503
  self_manage_nodes: True

owner_manager_cannot_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *owner_manager_headers
  body: *node_post_body
  assert_status: 403

lessee_admin_cannot_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *lessee_admin_headers
  body: *node_post_body
  assert_status: 403
  self_manage_nodes: False

lessee_admin_can_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *lessee_admin_headers
  body: *node_post_body
  assert_status: 403
  self_manage_nodes: False

lessee_manager_cannot_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *lessee_manager_headers
  body: *node_post_body
  assert_status: 403
  self_manage_nodes: False

lessee_manager_can_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *lessee_manager_headers
  body: *node_post_body
  assert_status: 403
  self_manage_nodes: True

third_party_admin_cannot_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *third_party_admin_headers
  body: *node_post_body
  assert_status: 403
  self_manage_nodes: False

third_party_admin_can_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *third_party_admin_headers
  body: *node_post_body
  assert_status: 503
  self_manage_nodes: True

# Based on nodes_post_member
owner_member_cannot_post_nodes:
  path: '/v1/nodes'
  method: post
  headers: *owner_member_headers
  body: *node_post_body
  assert_status: 403

# Based on nodes_post_reader
owner_reader_cannot_post_reader:
  path: '/v1/nodes'
  method: post
  headers: *owner_reader_headers
  body: *node_post_body
  assert_status: 403

# Based on nodes_get_admin
# TODO: Create 3 nodes, 2 owned, 1 leased where it is also owned.
owner_admin_can_get_node:
  path: '/v1/nodes'
  method: get
  headers: *owner_admin_headers
  assert_list_length:
    nodes: 2
  assert_status: 200

owner_manager_can_get_node:
  path: '/v1/nodes'
  method: get
  headers: *owner_manager_headers
  assert_list_length:
    nodes: 2
  assert_status: 200

owner_member_can_get_node:
  path: '/v1/nodes'
  method: get
  headers: *owner_member_headers
  assert_list_length:
    nodes: 2
  assert_status: 200

owner_reader_can_get_node:
  path: '/v1/nodes'
  method: get
  headers: *owner_reader_headers
  assert_list_length:
    nodes: 2
  assert_status: 200

lessee_admin_can_get_node:
  path: '/v1/nodes'
  method: get
  headers: *lessee_admin_headers
  assert_list_length:
      nodes: 1
  assert_status: 200

lessee_manager_can_get_node:
  path: '/v1/nodes'
  method: get
  headers: *lessee_manager_headers
  assert_list_length:
      nodes: 1
  assert_status: 200

lessee_member_can_get_node:
  path: '/v1/nodes'
  method: get
  headers: *lessee_member_headers
  assert_list_length:
      nodes: 1
  assert_status: 200

lessee_reader_can_get_node:
  path: '/v1/nodes'
  method: get
  headers: *lessee_reader_headers
  assert_list_length:
      nodes: 1
  assert_status: 200

# Tests that no nodes are associated and thus the API
# should return an empty list.
third_party_admin_cannot_get_node:
  path: '/v1/nodes'
  method: get
  headers: *third_party_admin_headers
  assert_list_length:
      nodes: 0
  assert_status: 200

# Based on nodes_get_node_admin

owner_reader_can_get_their_node:
  path: '/v1/nodes/{owner_node_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

owner_reader_cannot_get_other_node:
  # Not the owner's node, one they cannot
  # see.
  path: '/v1/nodes/{node_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 404

lessee_reader_can_get_their_node:
  path: '/v1/nodes/{lessee_node_ident}'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

lessee_reader_cant_get_other_node:
  # Not the lessee's node, one which
  # exists but that they cannot see.
  path: '/v1/nodes/{node_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 404

third_party_admin_cant_get_node:
  path: '/v1/nodes/{node_ident}'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

# Node body filter thresholds before detailed listing
# Represents checks for baremetal:node:get:filter_threshold
# which means anyone who is NOT a SYSTEM_READER by default
# will have additional checks examine if they can view fields.

owner_reader_can_get_restricted_fields:
  path: '/v1/nodes/{owner_node_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  assert_dict_contains:
    last_error: 'meow'
    reservation: 'lolcats'
    driver_internal_info:
      private_state: "secret value"
    driver_info:
      foo: "bar"
      fake_password: "******"

lessee_reader_cannot_get_restricted_fields:
  path: '/v1/nodes/{lessee_node_ident}'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200
  assert_dict_contains:
    last_error: "** Value Redacted - Requires baremetal:node:get:last_error permission. **"
    reservation: "** Redacted - requires baremetal:node:get:reservation permission. **"
    driver_internal_info:
      content: '** Redacted - Requires baremetal:node:get:driver_internal_info permission. **'
    driver_info:
      content: '** Redacted - requires baremetal:node:get:driver_info permission. **'

owner_reader_can_get_detail:
  path: '/v1/nodes/detail'
  method: get
  headers: *owner_reader_headers
  assert_list_length:
      nodes: 2
  assert_status: 200

lessee_reader_can_get_detail:
  path: '/v1/nodes/detail'
  method: get
  headers: *lessee_reader_headers
  assert_list_length:
      nodes: 1
  assert_status: 200

third_party_admin_cannot_get_detail:
  path: '/v1/nodes/detail'
  method: get
  headers: *third_party_admin_headers
  assert_list_length:
      nodes: 0
  assert_status: 200

# Node /extra is baremetal:node:update_extra

owner_admin_can_patch_node_extra:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_admin_headers
  body: &extra_patch
    - op: replace
      path: /extra
      value: {'test': 'testing'}
  assert_status: 503

owner_manager_can_patch_node_extra:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *extra_patch
  assert_status: 503

owner_member_can_patch_node_extra:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_member_headers
  body: *extra_patch
  assert_status: 503

owner_reader_cannot_patch_node_extra:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_reader_headers
  body: *extra_patch
  assert_status: 403

lessee_admin_can_patch_node_extra:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_admin_headers
  body: *extra_patch
  assert_status: 503

lessee_manager_can_patch_node_extra:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_manager_headers
  body: *extra_patch
  assert_status: 503

lessee_member_can_patch_node_extra:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_member_headers
  body: *extra_patch
  assert_status: 503

lessee_reader_cannot_patch_node_extra:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_reader_headers
  body: *extra_patch
  assert_status: 403

third_party_admin_cannot_patch_node_extra:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *third_party_admin_headers
  body: *extra_patch
  assert_status: 404

owner_admin_can_change_drivers:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_admin_headers
  body:
    - op: replace
      path: /driver
      value: fake-hardware
    - op: replace
      path: /power_interface
      value: fake
  assert_status: 503

owner_manager_can_change_drivers:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_manager_headers
  body:
    - op: replace
      path: /driver
      value: fake-hardware
    - op: replace
      path: /power_interface
      value: fake
  assert_status: 503

owner_member_can_patch_all_the_things:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_member_headers
  body: &patch_all_the_things
    - op: replace
      path: /instance_info
      value: {'test': 'testing'}
    - op: replace
      path: /driver_info
      value: {'test': 'testing'}
    - op: replace
      path: /properties
      value: {'test': 'testing'}
    - op: replace
      path: /network_data
      value:
        links: []
        networks: []
        services: []
    - op: replace
      path: /name
      value: 'meow-node-1'
    - op: replace
      path: /retired
      value: true
    - op: replace
      path: /retired_reason
      value: "43"
  assert_status: 503

# FIXME(TheJulia): This should be with member privileges below.
owner_member_can_change_lessee:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_member_headers
  assert_status: 503
  body:
    - op: replace
      path: /lessee
      value: "198566a5-a609-4463-9800-e8920be7c2fa"

lessee_admin_cannot_change_lessee:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_admin_headers
  assert_status: 403
  body:
    - op: replace
      path: /lessee
      value: "1234"

lessee_manager_cannot_change_lessee:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_manager_headers
  assert_status: 403
  body:
    - op: replace
      path: /lessee
      value: "1234"

lessee_admin_cannot_change_owner:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_admin_headers
  body:
    - op: replace
      path: /owner
      value: "1234"
  assert_status: 403

lessee_manager_cannot_change_owner:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_manager_headers
  body:
    - op: replace
      path: /owner
      value: "1234"
  assert_status: 403

owner_admin_can_change_lessee:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_admin_headers
  body:
    - op: replace
      path: /lessee
      value: "1234"
  assert_status: 503

owner_manager_can_change_lessee:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_manager_headers
  body:
    - op: replace
      path: /lessee
      value: "1234"
  assert_status: 503

owner_admin_cannot_change_owner:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_admin_headers
  body:
    - op: replace
      path: /owner
      value: "1234"
  assert_status: 403

owner_manager_cannot_change_owner:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_manager_headers
  body:
    - op: replace
      path: /owner
      value: "1234"
  assert_status: 403

# This is not an explicitly restricted item, it falls
# to generalized update capability, which oddly makes
# a lot of sense in this case. It is a flag to prevent
# accidental erasure/removal of the node.

lessee_member_can_set_protected:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_member_headers
  body:
    - op: replace
      path: /protected
      value: true
  assert_status: 503

lessee_member_cannot_patch_instance_info:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_member_headers
  body:
    - op: replace
      path: /instance_info
      value: {'test': 'testing'}
  assert_status: 403

lessee_member_cannot_patch_driver_info:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_member_headers
  body:
    - op: replace
      path: /driver_info
      value: {'test': 'testing'}
  assert_status: 403

lessee_member_cannot_patch_properties:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_member_headers
  body:
    - op: replace
      path: /properties
      value: {'test': 'testing'}
  assert_status: 403

lessee_member_cannot_patch_network_data:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_member_headers
  body:
    - op: replace
      path: /network_data
      value:
        links: []
        networks: []
        services: []
  assert_status: 403

lessee_member_cannot_patch_name:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_member_headers
  body:
    - op: replace
      path: /name
      value: 'meow-node-1'
  assert_status: 403

lessee_member_cannot_patch_retired:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_member_headers
  body:
    - op: replace
      path: /retired
      value: true
    - op: replace
      path: /retired_reason
      value: "43"
  assert_status: 403

owner_admin_can_patch_node_instance_info:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_admin_headers
  body: &instance_info_patch
    - op: replace
      path: /instance_info
      value: {'test': 'testing'}
  assert_status: 503

owner_manager_can_patch_node_instance_info:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *instance_info_patch
  assert_status: 503

owner_member_can_patch_node_instance_info:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_member_headers
  body: *instance_info_patch
  assert_status: 503

owner_reader_can_patch_node_instance_info:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_reader_headers
  body: *instance_info_patch
  assert_status: 403

lessee_admin_can_patch_node_instance_info:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_admin_headers
  body: *instance_info_patch
  assert_status: 503

lessee_manager_can_patch_node_instance_info:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_manager_headers
  body: *instance_info_patch
  assert_status: 503

lessee_member_cannot_patch_node_instance_info:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_member_headers
  body: *instance_info_patch
  assert_status: 403

lessee_reader_can_patch_node_instance_info:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *lessee_reader_headers
  body: *instance_info_patch
  assert_status: 403

third_party_admin_cannot_patch_node_instance_info:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *third_party_admin_headers
  body: *instance_info_patch
  assert_status: 404

owner_admin_cannot_delete_nodes:
  path: '/v1/nodes/{owner_node_ident}'
  method: delete
  headers: *owner_admin_headers
  assert_status: 403
  self_manage_nodes: False

owner_admin_can_delete_nodes:
  path: '/v1/nodes/{owner_node_ident}'
  method: delete
  headers: *owner_admin_headers
  assert_status: 503
  self_manage_nodes: True

service_cannot_delete_owner_admin_nodes:
  path: '/v1/nodes/{owner_node_ident}'
  method: delete
  headers: *service_headers
  assert_status: 404

service_can_delete_nodes_in_own_project:
  path: '/v1/nodes/{owner_node_ident}'
  method: delete
  headers: *service_headers_owner_project
  assert_status: 403

owner_manager_cannot_delete_nodes:
  path: '/v1/nodes/{owner_node_ident}'
  method: delete
  headers: *owner_manager_headers
  assert_status: 403

lessee_admin_cannot_delete_nodes:
  path: '/v1/nodes/{lessee_node_ident}'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_delete_nodes:
  path: '/v1/nodes/{lessee_node_ident}'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 403

third_party_admin_cannot_delete_nodes:
  path: '/v1/nodes/{owner_node_ident}'
  method: delete
  headers: *third_party_admin_headers
  assert_status: 404

# TODO(TheJulia): Specific field restrictions based on permissions,
# are in the spec, but still need to be implemented test wise.
# We should likely do that *AS* we put that code in.

# Node Management - https://docs.openstack.org/api-ref/baremetal/?expanded=#node-management-nodes
# NOTE(TheJulia): Most management methods call into the conductor as they
# require a task, which means they generally return 503 when the conductor
# is mocked.

owner_admin_can_validate_node:
  path: '/v1/nodes/{owner_node_ident}/validate'
  method: get
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_validate_node:
  path: '/v1/nodes/{owner_node_ident}/validate'
  method: get
  headers: *owner_manager_headers
  assert_status: 503

lessee_admin_can_validate_node:
  path: '/v1/nodes/{lessee_node_ident}/validate'
  method: get
  headers: *lessee_admin_headers
  assert_status: 503

lessee_manager_can_validate_node:
  path: '/v1/nodes/{lessee_node_ident}/validate'
  method: get
  headers: *lessee_manager_headers
  assert_status: 503

owner_member_can_validate_node:
  path: '/v1/nodes/{owner_node_ident}/validate'
  method: get
  headers: *owner_member_headers
  assert_status: 503

lessee_member_cannot_validate_node:
  path: '/v1/nodes/{lessee_node_ident}/validate'
  method: get
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_validate_node:
  path: '/v1/nodes/{owner_node_ident}/validate'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

owner_admin_can_set_maintenance:
  path: '/v1/nodes/{owner_node_ident}/maintenance'
  method: put
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_set_maintenance:
  path: '/v1/nodes/{owner_node_ident}/maintenance'
  method: put
  headers: *owner_manager_headers
  assert_status: 503

# should we really allow this? they could desync with nova if they can do this...
lessee_admin_can_set_maintenance:
  path: '/v1/nodes/{lessee_node_ident}/maintenance'
  method: put
  headers: *lessee_admin_headers
  assert_status: 503

lessee_manager_can_set_maintenance:
  path: '/v1/nodes/{lessee_node_ident}/maintenance'
  method: put
  headers: *lessee_manager_headers
  assert_status: 503

owner_member_can_set_maintenance:
  path: '/v1/nodes/{owner_node_ident}/maintenance'
  method: put
  headers: *owner_member_headers
  assert_status: 503

lessee_member_cannot_set_maintenance:
  path: '/v1/nodes/{lessee_node_ident}/maintenance'
  method: put
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_set_maintenance:
  path: '/v1/nodes/{owner_node_ident}/maintenance'
  method: put
  headers: *third_party_admin_headers
  assert_status: 404

owner_admin_can_unset_maintenance:
  path: '/v1/nodes/{owner_node_ident}/maintenance'
  method: delete
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_unset_maintenance:
  path: '/v1/nodes/{owner_node_ident}/maintenance'
  method: delete
  headers: *owner_manager_headers
  assert_status: 503

lessee_admin_can_unset_maintenance:
  path: '/v1/nodes/{lessee_node_ident}/maintenance'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 503

lessee_manager_can_unset_maintenance:
  path: '/v1/nodes/{lessee_node_ident}/maintenance'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 503

owner_member_can_unset_maintnenance:
  path: '/v1/nodes/{owner_node_ident}/maintenance'
  method: delete
  headers: *owner_member_headers
  assert_status: 503

lessee_member_cannot_unset_maintenance:
  path: '/v1/nodes/{lessee_node_ident}/maintenance'
  method: delete
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_unset_maintenance:
  path: '/v1/nodes/{node_ident}/maintenance'
  method: delete
  headers: *third_party_admin_headers
  assert_status: 404

# Get/set supported boot devices

owner_admin_can_set_boot_device:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device'
  method: put
  headers: *owner_admin_headers
  body: &boot_device_body
    boot_device: pxe
  assert_status: 503

owner_manager_can_set_boot_device:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device'
  method: put
  headers: *owner_manager_headers
  body: *boot_device_body
  assert_status: 503

lessee_admin_cannot_set_boot_device:
  path: '/v1/nodes/{lessee_node_ident}/management/boot_device'
  method: put
  headers: *lessee_admin_headers
  body: *boot_device_body
  assert_status: 403

lessee_manager_cannot_set_boot_device:
  path: '/v1/nodes/{lessee_node_ident}/management/boot_device'
  method: put
  headers: *lessee_manager_headers
  body: *boot_device_body
  assert_status: 403

owner_member_cannot_set_boot_device:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device'
  method: put
  headers: *owner_member_headers
  body: *boot_device_body
  assert_status: 403

lessee_member_cannot_set_boot_device:
  path: '/v1/nodes/{lessee_node_ident}/management/boot_device'
  method: put
  headers: *lessee_member_headers
  body: *boot_device_body
  assert_status: 403

third_party_admin_cannot_set_boot_device:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device'
  method: put
  headers: *third_party_admin_headers
  body: *boot_device_body
  assert_status: 404

owner_admin_can_get_boot_device:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device'
  method: get
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_get_boot_device:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device'
  method: get
  headers: *owner_manager_headers
  assert_status: 503

# FIXME(TheJulia): This should be lessee admin headers below.
lessee_admin_cannot_get_boot_device:
  path: '/v1/nodes/{lessee_node_ident}/management/boot_device'
  method: get
  headers: *lessee_admin_headers
  assert_status: 403

owner_member_cannot_get_boot_device:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device'
  method: get
  headers: *owner_member_headers
  assert_status: 403

lessee_member_cannot_get_boot_device:
  path: '/v1/nodes/{lessee_node_ident}/management/boot_device'
  method: get
  headers: *lessee_member_headers
  assert_status: 403

owner_reader_cannot_get_boot_device:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device'
  method: get
  headers: *owner_reader_headers
  assert_status: 403

lessee_reader_cannot_get_boot_device:
  path: '/v1/nodes/{lessee_node_ident}/management/boot_device'
  method: get
  headers: *lessee_reader_headers
  assert_status: 403

third_party_admin_cannot_get_boot_device:
  path: '/v1/nodes/{node_ident}/management/boot_device'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

owner_admin_can_get_supported_boot_devices:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device/supported'
  method: get
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_get_supported_boot_devices:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device/supported'
  method: get
  headers: *owner_manager_headers
  assert_status: 503

owner_member_cannot_get_supported_boot_devices:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device/supported'
  method: get
  headers: *owner_member_headers
  assert_status: 403

lessee_admin_cannot_get_supported_boot_devices:
  path: '/v1/nodes/{lessee_node_ident}/management/boot_device/supported'
  method: get
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_get_supported_boot_devices:
  path: '/v1/nodes/{lessee_node_ident}/management/boot_device/supported'
  method: get
  headers: *lessee_manager_headers
  assert_status: 403

third_party_admin_cannot_get_supported_boot_devices:
  path: '/v1/nodes/{owner_node_ident}/management/boot_device/supported'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

# Non masking interrupt

owner_admin_can_send_non_masking_interrupt:
  path: '/v1/nodes/{owner_node_ident}/management/inject_nmi'
  method: put
  headers: *owner_admin_headers
  body: {}
  assert_status: 503

owner_manager_can_send_non_masking_interrupt:
  path: '/v1/nodes/{owner_node_ident}/management/inject_nmi'
  method: put
  headers: *owner_manager_headers
  body: {}
  assert_status: 503

lessee_admin_cannot_send_non_masking_interrupt:
  path: '/v1/nodes/{lessee_node_ident}/management/inject_nmi'
  method: put
  headers: *lessee_admin_headers
  body: {}
  assert_status: 403

lessee_manager_cannot_send_non_masking_interrupt:
  path: '/v1/nodes/{lessee_node_ident}/management/inject_nmi'
  method: put
  headers: *lessee_manager_headers
  body: {}
  assert_status: 403

third_party_admin_cannot_send_non_masking_interrupt:
  path: '/v1/nodes/{node_ident}/management/inject_nmi'
  method: put
  headers: *third_party_admin_headers
  body: {}
  assert_status: 404

# States

owner_reader_get_states:
  path: '/v1/nodes/{owner_node_ident}/states'
  method: get
  headers: *owner_admin_headers
  assert_status: 200

lessee_reader_get_states:
  path: '/v1/nodes/{lessee_node_ident}/states'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_part_admin_cannot_get_states:
  path: '/v1/nodes/{node_ident}/states'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

# Power states

owner_admin_can_put_power_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/power'
  method: put
  headers: *owner_admin_headers
  body: &power_body
    target: "power on"
  assert_status: 503

owner_manager_can_put_power_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/power'
  method: put
  headers: *owner_manager_headers
  body: *power_body
  assert_status: 503

lessee_admin_can_put_power_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/power'
  method: put
  headers: *lessee_admin_headers
  body: *power_body
  assert_status: 503

lessee_manager_can_put_power_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/power'
  method: put
  headers: *lessee_manager_headers
  body: *power_body
  assert_status: 503

owner_member_can_put_power_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/power'
  method: put
  headers: *owner_member_headers
  body: *power_body
  assert_status: 503

lessee_member_can_put_power_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/power'
  method: put
  headers: *lessee_member_headers
  body: *power_body
  assert_status: 503

owner_reader_cannot_put_power_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/power'
  method: put
  headers: *owner_reader_headers
  body: *power_body
  assert_status: 403

lessee_reader_cannot_put_power_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/power'
  method: put
  headers: *lessee_reader_headers
  body: *power_body
  assert_status: 403

third_party_admin_cannot_put_power_state_change:
  path: '/v1/nodes/{node_ident}/states/power'
  method: put
  headers: *third_party_admin_headers
  body: *power_body
  assert_status: 404

# Boot mode state

owner_admin_can_put_boot_mode_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/boot_mode'
  method: put
  headers: *owner_admin_headers
  body: &boot_mode_body
    target: "uefi"
  assert_status: 503

owner_manager_can_put_boot_mode_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/boot_mode'
  method: put
  headers: *owner_manager_headers
  body: *boot_mode_body
  assert_status: 503

lessee_admin_can_put_boot_mode_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/boot_mode'
  method: put
  headers: *lessee_admin_headers
  body: *boot_mode_body
  assert_status: 503

lessee_manager_can_put_boot_mode_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/boot_mode'
  method: put
  headers: *lessee_manager_headers
  body: *boot_mode_body
  assert_status: 503

owner_member_can_put_boot_mode_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/boot_mode'
  method: put
  headers: *owner_member_headers
  body: *boot_mode_body
  assert_status: 503

lessee_member_can_put_boot_mode_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/boot_mode'
  method: put
  headers: *lessee_member_headers
  body: *boot_mode_body
  assert_status: 503

owner_reader_cannot_put_boot_mode_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/boot_mode'
  method: put
  headers: *owner_reader_headers
  body: *boot_mode_body
  assert_status: 403

lessee_reader_cannot_put_boot_mode_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/boot_mode'
  method: put
  headers: *lessee_reader_headers
  body: *boot_mode_body
  assert_status: 403

third_party_admin_cannot_put_boot_mode_state_change:
  path: '/v1/nodes/{node_ident}/states/boot_mode'
  method: put
  headers: *third_party_admin_headers
  body: *boot_mode_body
  assert_status: 404

# Secure Boot state

owner_admin_can_put_secure_boot_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/secure_boot'
  method: put
  headers: *owner_admin_headers
  body: &secure_boot_body
    target: "true"
  assert_status: 503

owner_manager_can_put_secure_boot_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/secure_boot'
  method: put
  headers: *owner_manager_headers
  body: *secure_boot_body
  assert_status: 503

lessee_admin_can_put_secure_boot_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/secure_boot'
  method: put
  headers: *lessee_admin_headers
  body: *secure_boot_body
  assert_status: 503

lessee_manager_can_put_secure_boot_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/secure_boot'
  method: put
  headers: *lessee_manager_headers
  body: *secure_boot_body
  assert_status: 503

owner_member_can_put_secure_boot_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/secure_boot'
  method: put
  headers: *owner_member_headers
  body: *secure_boot_body
  assert_status: 503

lessee_member_can_put_secure_boot_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/secure_boot'
  method: put
  headers: *lessee_member_headers
  body: *secure_boot_body
  assert_status: 503

owner_reader_cannot_put_secure_boot_state_change:
  path: '/v1/nodes/{owner_node_ident}/states/secure_boot'
  method: put
  headers: *owner_reader_headers
  body: *secure_boot_body
  assert_status: 403

lessee_reader_cannot_put_secure_boot_state_change:
  path: '/v1/nodes/{lessee_node_ident}/states/secure_boot'
  method: put
  headers: *lessee_reader_headers
  body: *secure_boot_body
  assert_status: 403

third_party_admin_cannot_put_secure_boot_state_change:
  path: '/v1/nodes/{node_ident}/states/secure_boot'
  method: put
  headers: *third_party_admin_headers
  body: *secure_boot_body
  assert_status: 404

# Provision states

owner_admin_can_change_provision_state:
  path: '/v1/nodes/{owner_node_ident}/states/provision'
  method: put
  headers: *owner_admin_headers
  body: &provision_body
    target: deploy
  assert_status: 503

owner_manager_can_change_provision_state:
  path: '/v1/nodes/{owner_node_ident}/states/provision'
  method: put
  headers: *owner_manager_headers
  body: *provision_body
  assert_status: 503

owner_member_can_change_provision_state:
  path: '/v1/nodes/{owner_node_ident}/states/provision'
  method: put
  headers: *owner_member_headers
  body: *provision_body
  assert_status: 503

lessee_admin_can_change_provision_state:
  path: '/v1/nodes/{lessee_node_ident}/states/provision'
  method: put
  headers: *lessee_admin_headers
  body: *provision_body
  assert_status: 503

lessee_manager_can_change_provision_state:
  path: '/v1/nodes/{lessee_node_ident}/states/provision'
  method: put
  headers: *lessee_manager_headers
  body: *provision_body
  assert_status: 503

lessee_member_cannot_change_provision_state:
  path: '/v1/nodes/{lessee_node_ident}/states/provision'
  method: put
  headers: *lessee_member_headers
  body: *provision_body
  assert_status: 403

third_party_admin_cannot_change_provision_state:
  path: '/v1/nodes/{owner_node_ident}/states/provision'
  method: put
  headers: *lessee_member_headers
  body: *provision_body
  assert_status: 404

service_can_change_provision_state_for_own_nodes:
  path: '/v1/nodes/{owner_node_ident}/states/provision'
  method: put
  headers: *service_headers_owner_project
  body: *provision_body
  assert_status: 503

service_cannot_change_provision_state:
  path: '/v1/nodes/{owner_node_ident}/states/provision'
  method: put
  headers: *service_headers
  body: *provision_body
  assert_status: 404

# The following tests fail on lock checking, which is fine,
# as it demonstrates we're past API RBAC policy checking...
# And these checks center around secondary policies, so the
# what we send is more important.
owner_member_can_set_provision_state_clean:
  path: '/v1/nodes/{owner_node_ident}/states/provision'
  method: put
  headers: *owner_member_headers
  body: &provision_body_clean_steps
    target: clean
    clean_steps:
      - interface: deploy
        step: update_firmware
        args:
          foo: bar
        priority: 99
  assert_status: 409

owner_reader_cannot_set_provision_state_clean:
  path: '/v1/nodes/{owner_node_ident}/states/provision'
  method: put
  headers: *owner_reader_headers
  body: *provision_body_clean_steps
  assert_status: 403

lessee_admin_can_set_provision_state_clean:
  path: '/v1/nodes/{lessee_node_ident}/states/provision'
  method: put
  headers: *lessee_admin_headers
  body: *provision_body_clean_steps
  assert_status: 409

lessee_member_cannot_set_provision_state_clean:
  path: '/v1/nodes/{lessee_node_ident}/states/provision'
  method: put
  headers: *lessee_member_headers
  body: *provision_body_clean_steps
  assert_status: 403

owner_member_can_set_provision_state_service:
  path: '/v1/nodes/{owner_node_ident}/states/provision'
  method: put
  headers: *owner_member_headers
  body: &provision_body_service_steps
    target: service
    clean_steps:
      - interface: deploy
        step: update_firmware
        args:
          foo: bar
        priority: 99
  assert_status: 409

owner_reader_cannot_set_provision_state_service:
  path: '/v1/nodes/{owner_node_ident}/states/provision'
  method: put
  headers: *owner_reader_headers
  body: *provision_body_service_steps
  assert_status: 403

lessee_admin_can_set_provision_state_service:
  path: '/v1/nodes/{lessee_node_ident}/states/provision'
  method: put
  headers: *lessee_admin_headers
  body: *provision_body_service_steps
  assert_status: 409

lessee_member_cannot_set_provision_state_service:
  path: '/v1/nodes/{lessee_node_ident}/states/provision'
  method: put
  headers: *lessee_member_headers
  body: *provision_body_service_steps
  assert_status: 403

# Raid configuration

owner_admin_can_set_raid_config:
  path: '/v1/nodes/{owner_node_ident}/states/raid'
  method: put
  headers: *owner_admin_headers
  body: &raid_body
    target_raid_config:
      logical_disks:
        - size_gb: 500
          is_root_volume: true
          raid_level: 1
  assert_status: 503

owner_manager_can_set_raid_config:
  path: '/v1/nodes/{owner_node_ident}/states/raid'
  method: put
  headers: *owner_manager_headers
  body: *raid_body
  assert_status: 503

lessee_admin_cannot_set_raid_config:
  path: '/v1/nodes/{lessee_node_ident}/states/raid'
  method: put
  headers: *lessee_admin_headers
  body: *raid_body
  assert_status: 403

lessee_manager_cannot_set_raid_config:
  path: '/v1/nodes/{lessee_node_ident}/states/raid'
  method: put
  headers: *lessee_manager_headers
  body: *raid_body
  assert_status: 403

owner_member_can_set_raid_config:
  path: '/v1/nodes/{lessee_node_ident}/states/raid'
  method: put
  headers: *owner_member_headers
  body: *raid_body
  assert_status: 503

service_owner_can_set_raid_config:
  path: '/v1/nodes/{lessee_node_ident}/states/raid'
  method: put
  headers: *service_headers_owner_project
  body: *raid_body
  assert_status: 503

lessee_member_cannot_set_raid_config:
  path: '/v1/nodes/{lessee_node_ident}/states/raid'
  method: put
  headers: *lessee_member_headers
  body: *raid_body
  assert_status: 403

third_party_admin_cannot_set_raid_config:
  path: '/v1/nodes/{lessee_node_ident}/states/raid'
  method: put
  headers: *third_party_admin_headers
  body: *raid_body
  assert_status: 404

service_cannot_set_raid_config:
  path: '/v1/nodes/{lessee_node_ident}/states/raid'
  method: put
  headers: *service_headers
  body: *raid_body
  assert_status: 404


# Console

owner_admin_can_get_console:
  path: '/v1/nodes/{owner_node_ident}/states/console'
  method: get
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_get_console:
  path: '/v1/nodes/{owner_node_ident}/states/console'
  method: get
  headers: *owner_manager_headers
  assert_status: 503

owner_service_can_get_console:
  path: '/v1/nodes/{owner_node_ident}/states/console'
  method: get
  headers: *service_headers_owner_project
  assert_status: 503

lessee_admin_cannot_get_console:
  path: '/v1/nodes/{lessee_node_ident}/states/console'
  method: get
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_get_console:
  path: '/v1/nodes/{lessee_node_ident}/states/console'
  method: get
  headers: *lessee_manager_headers
  assert_status: 403

owner_member_can_get_console:
  path: '/v1/nodes/{owner_node_ident}/states/console'
  method: get
  headers: *owner_member_headers
  assert_status: 503

lessee_member_cannot_get_console:
  path: '/v1/nodes/{lessee_node_ident}/states/console'
  method: get
  headers: *lessee_member_headers
  assert_status: 403

owner_reader_cannot_get_console:
  path: '/v1/nodes/{owner_node_ident}/states/console'
  method: get
  headers: *owner_reader_headers
  assert_status: 403

lessee_reader_cannot_get_console:
  path: '/v1/nodes/{lessee_node_ident}/states/console'
  method: get
  headers: *lessee_reader_headers
  assert_status: 403

third_party_admin_cannot_get_console:
  path: '/v1/nodes/{lessee_node_ident}/states/console'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

owner_admin_can_set_console:
  path: '/v1/nodes/{owner_node_ident}/states/console'
  method: put
  headers: *owner_admin_headers
  body: &console_body_put
    enabled: true
  assert_status: 503

owner_manager_can_set_console:
  path: '/v1/nodes/{owner_node_ident}/states/console'
  method: put
  headers: *owner_manager_headers
  body: *console_body_put
  assert_status: 503

lessee_admin_cannot_set_console:
  path: '/v1/nodes/{lessee_node_ident}/states/console'
  method: put
  headers: *lessee_admin_headers
  body: *console_body_put
  assert_status: 403

lessee_manager_cannot_set_console:
  path: '/v1/nodes/{lessee_node_ident}/states/console'
  method: put
  headers: *lessee_manager_headers
  body: *console_body_put
  assert_status: 403

owner_member_can_set_console:
  path: '/v1/nodes/{owner_node_ident}/states/console'
  method: put
  headers: *owner_member_headers
  body: *console_body_put
  assert_status: 503

lessee_member_cannot_set_console:
  path: '/v1/nodes/{lessee_node_ident}/states/console'
  method: put
  headers: *lessee_member_headers
  body: *console_body_put
  assert_status: 403

owner_service_can_set_console:
  path: '/v1/nodes/{owner_node_ident}/states/console'
  method: put
  headers: *service_headers_owner_project
  body: *console_body_put
  assert_status: 503

service_cannot_set_console:
  path: '/v1/nodes/{owner_node_ident}/states/console'
  method: put
  headers: *service_headers
  body: *console_body_put
  assert_status: 404

# Vendor Passthru - https://docs.openstack.org/api-ref/baremetal/?expanded=#node-vendor-passthru-nodes

# owner/lessee vendor passthru methods inaccessible

# Based on nodes_vendor_passthru_methods_*

owner_admin_cannot_get_vendor_passthru_methods:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru/methods'
  method: get
  headers: *owner_admin_headers
  assert_status: 403

owner_manager_cannot_get_vendor_passthru_methods:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru/methods'
  method: get
  headers: *owner_manager_headers
  assert_status: 403

owner_service_cannot_get_vendor_passthru_methods:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru/methods'
  method: get
  headers: *service_headers_owner_project
  assert_status: 403

owner_member_cannot_get_vendor_passthru_methods:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru/methods'
  method: get
  headers: *owner_member_headers
  assert_status: 403

owner_reader_cannot_get_vendor_passthru_methods:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru/methods'
  method: get
  headers: *owner_reader_headers
  assert_status: 403

lessee_admin_cannot_get_vendor_passthru_methods:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru/methods'
  method: get
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_get_vendor_passthru_methods:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru/methods'
  method: get
  headers: *lessee_manager_headers
  assert_status: 403

lessee_member_cannot_get_vendor_passthru_methods:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru/methods'
  method: get
  headers: *lessee_member_headers
  assert_status: 403

lessee_reader_cannot_get_vendor_passthru_methods:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru/methods'
  method: get
  headers: *lessee_reader_headers
  assert_status: 403

# Get vendor passthru method tests
owner_admin_cannot_get_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: get
  headers: *owner_admin_headers
  assert_status: 403

owner_manager_cannot_get_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: get
  headers: *owner_manager_headers
  assert_status: 403

owner_service_cannot_get_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: get
  headers: *service_headers_owner_project
  assert_status: 403

owner_member_cannot_get_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: get
  headers: *owner_member_headers
  assert_status: 403

owner_reader_cannot_get_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: get
  headers: *owner_reader_headers
  assert_status: 403

lessee_admin_cannot_get_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: get
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_get_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: get
  headers: *lessee_manager_headers
  assert_status: 403

lessee_member_cannot_get_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: get
  headers: *lessee_member_headers
  assert_status: 403

lessee_reader_cannot_get_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: get
  headers: *lessee_reader_headers
  assert_status: 403

# Post vendor passthru method tests

owner_admin_cannot_post_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: post
  headers: *owner_admin_headers
  assert_status: 403

owner_manager_cannot_post_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: post
  headers: *owner_manager_headers
  assert_status: 403

owner_service_cannot_post_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: post
  headers: *service_headers_owner_project
  assert_status: 403

owner_member_cannot_post_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: post
  headers: *owner_member_headers
  assert_status: 403

owner_reader_cannot_post_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: post
  headers: *owner_reader_headers
  assert_status: 403

lessee_admin_cannot_post_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: post
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_post_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: post
  headers: *lessee_manager_headers
  assert_status: 403

lessee_member_cannot_post_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: post
  headers: *lessee_member_headers
  assert_status: 403

lessee_reader_cannot_post_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: post
  headers: *lessee_reader_headers
  assert_status: 403

# Put vendor passthru method tests

owner_admin_cannot_put_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: put
  headers: *owner_admin_headers
  assert_status: 403

owner_manager_cannot_put_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: put
  headers: *owner_manager_headers
  assert_status: 403

owner_service_cannot_put_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: put
  headers: *service_headers_owner_project
  assert_status: 403

owner_member_cannot_put_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: put
  headers: *owner_member_headers
  assert_status: 403

owner_reader_cannot_put_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: put
  headers: *owner_reader_headers
  assert_status: 403

lessee_admin_cannot_put_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: put
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_put_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: put
  headers: *lessee_manager_headers
  assert_status: 403

lessee_member_cannot_put_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: put
  headers: *lessee_member_headers
  assert_status: 403

lessee_reader_cannot_put_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: put
  headers: *lessee_reader_headers
  assert_status: 403

# Delete vendor passthru methods tests

owner_admin_cannot_delete_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: delete
  headers: *owner_admin_headers
  assert_status: 403

owner_manager_cannot_delete_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: delete
  headers: *owner_manager_headers
  assert_status: 403

owner_service_cannot_delete_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: delete
  headers: *service_headers_owner_project
  assert_status: 403

owner_member_cannot_delete_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: delete
  headers: *owner_member_headers
  assert_status: 403

owner_reader_cannot_delete_vendor_passthru:
  path: '/v1/nodes/{owner_node_ident}/vendor_passthru?method=test'
  method: delete
  headers: *owner_reader_headers
  assert_status: 403

lessee_admin_cannot_delete_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_delete_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 403

lessee_member_cannot_delete_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: delete
  headers: *lessee_member_headers
  assert_status: 403

lessee_reader_cannot_delete_vendor_passthru:
  path: '/v1/nodes/{lessee_node_ident}/vendor_passthru?method=test'
  method: delete
  headers: *lessee_reader_headers
  assert_status: 403

# Node Traits - https://docs.openstack.org/api-ref/baremetal/#node-traits-nodes

owner_reader_get_traits:
  path: '/v1/nodes/{owner_node_ident}/traits'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

owner_reader_get_traits_service:
  path: '/v1/nodes/{owner_node_ident}/traits'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200

lessee_reader_get_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_get_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

owner_admin_can_put_traits:
  path: '/v1/nodes/{owner_node_ident}/traits'
  method: put
  headers: *owner_admin_headers
  assert_status: 503
  body: &traits_body
    traits:
      - CUSTOM_TRAIT1
      - HW_CPU_X86_VMX

owner_manager_can_put_traits:
  path: '/v1/nodes/{owner_node_ident}/traits'
  method: put
  headers: *owner_manager_headers
  assert_status: 503
  body: *traits_body

owner_service_can_put_traits:
  path: '/v1/nodes/{owner_node_ident}/traits'
  method: put
  headers: *service_headers_owner_project
  assert_status: 503
  body: *traits_body

owner_member_cannot_put_traits:
  path: '/v1/nodes/{owner_node_ident}/traits'
  method: put
  headers: *owner_member_headers
  assert_status: 403
  body: *traits_body

lessee_admin_cannot_put_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits'
  method: put
  headers: *lessee_admin_headers
  assert_status: 403
  body: *traits_body

lessee_manager_cannot_put_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits'
  method: put
  headers: *lessee_manager_headers
  assert_status: 403
  body: *traits_body

lessee_member_cannot_put_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits'
  method: put
  headers: *lessee_member_headers
  assert_status: 403
  body: *traits_body

third_party_admin_cannot_put_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits'
  method: put
  headers: *third_party_admin_headers
  assert_status: 404
  body: *traits_body

third_party_admin_cannot_put_traits_service:
  path: '/v1/nodes/{lessee_node_ident}/traits'
  method: put
  headers: *service_headers
  assert_status: 404
  body: *traits_body

owner_admin_can_delete_traits:
  path: '/v1/nodes/{owner_node_ident}/traits/{trait}'
  method: delete
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_delete_traits:
  path: '/v1/nodes/{owner_node_ident}/traits/{trait}'
  method: delete
  headers: *owner_manager_headers
  assert_status: 503

owner_member_cannot_delete_traits:
  path: '/v1/nodes/{owner_node_ident}/traits/{trait}'
  method: delete
  headers: *owner_member_headers
  assert_status: 403

lessee_admin_cannot_delete_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits/{trait}'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_delete_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits/{trait}'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 403

lessee_member_cannot_delete_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits/{trait}'
  method: delete
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_delete_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits/{trait}'
  method: delete
  headers: *third_party_admin_headers
  assert_status: 404

owner_admin_can_put_custom_traits:
  path: '/v1/nodes/{owner_node_ident}/traits/CUSTOM_TRAIT2'
  method: put
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_put_custom_traits:
  path: '/v1/nodes/{owner_node_ident}/traits/CUSTOM_TRAIT2'
  method: put
  headers: *owner_manager_headers
  assert_status: 503

owner_member_cannot_put_custom_traits:
  path: '/v1/nodes/{owner_node_ident}/traits/CUSTOM_TRAIT2'
  method: put
  headers: *owner_member_headers
  assert_status: 403

lessee_admin_cannot_put_custom_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits/CUSTOM_TRAIT2'
  method: put
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_put_custom_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits/CUSTOM_TRAIT2'
  method: put
  headers: *lessee_manager_headers
  assert_status: 403

lessee_member_cannot_put_custom_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits/CUSTOM_TRAIT2'
  method: put
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_put_custom_traits:
  path: '/v1/nodes/{lessee_node_ident}/traits/CUSTOM_TRAIT2'
  method: put
  headers: *third_party_admin_headers
  assert_status: 404

# VIFS - https://docs.openstack.org/api-ref/baremetal/#vifs-virtual-interfaces-of-nodes
# TODO(TheJulia): VIFS will need fairly exhaustive testing given the use path.
# i.e. ensure user has rights to a vif and all.

# Based on nodes_vifs_* tests.

owner_reader_get_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs'
  method: get
  headers: *owner_reader_headers
  assert_status: 503

lessee_reader_get_vifs:
  path: '/v1/nodes/{lessee_node_ident}/vifs'
  method: get
  headers: *lessee_reader_headers
  assert_status: 503

third_party_admin_cannot_get_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

owner_admin_can_post_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs'
  method: post
  headers: *owner_admin_headers
  assert_status: 503
  body: &vif_body
    id: ee21d58f-5de2-4956-85ff-33935ea1ca00

service_can_post_vifs_for_own_project:
  path: '/v1/nodes/{owner_node_ident}/vifs'
  method: post
  headers: *service_headers_owner_project
  assert_status: 503
  body: *vif_body

service_cannot_post_vifs_for_other_project:
  path: '/v1/nodes/{owner_node_ident}/vifs'
  method: post
  headers: *service_headers
  # NOTE(TheJulia): This is a 404 because the node should not be visible.
  assert_status: 404
  body: *vif_body

owner_manager_can_post_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs'
  method: post
  headers: *owner_manager_headers
  assert_status: 503
  body: *vif_body

lessee_admin_can_post_vifs:
  path: '/v1/nodes/{lessee_node_ident}/vifs'
  method: post
  headers: *lessee_admin_headers
  assert_status: 503
  body: *vif_body

lessee_manager_can_post_vifs:
  path: '/v1/nodes/{lessee_node_ident}/vifs'
  method: post
  headers: *lessee_manager_headers
  assert_status: 503
  body: *vif_body

owner_member_can_post_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs'
  method: post
  headers: *owner_admin_headers
  assert_status: 503
  body: *vif_body

lessee_member_cannot_post_vifs:
  path: '/v1/nodes/{lessee_node_ident}/vifs'
  method: post
  headers: *lessee_member_headers
  assert_status: 403
  body: *vif_body

owner_reader_cannot_post_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs'
  method: post
  headers: *owner_reader_headers
  assert_status: 403
  body: *vif_body

lessee_reader_cannot_post_vifs:
  path: '/v1/nodes/{lessee_node_ident}/vifs'
  method: post
  headers: *lessee_reader_headers
  assert_status: 403
  body: *vif_body

third_party_admin_cannot_post_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs'
  method: post
  headers: *third_party_admin_headers
  assert_status: 404
  body: *vif_body

owner_admin_delete_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs/{vif_ident}'
  method: delete
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_delete_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs/{vif_ident}'
  method: delete
  headers: *owner_manager_headers
  assert_status: 503

lessee_admin_can_delete_vifs:
  path: '/v1/nodes/{lessee_node_ident}/vifs/{vif_ident}'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 503

lessee_manager_can_delete_vifs:
  path: '/v1/nodes/{lessee_node_ident}/vifs/{vif_ident}'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 503

owner_member_can_delete_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs/{vif_ident}'
  method: delete
  headers: *owner_member_headers
  assert_status: 503

lessee_member_cannot_delete_vifs:
  path: '/v1/nodes/{lessee_node_ident}/vifs/{vif_ident}'
  method: delete
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_delete_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs/{vif_ident}'
  method: delete
  headers: *third_party_admin_headers
  assert_status: 404

service_can_delete_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs/{vif_ident}'
  method: delete
  headers: *service_headers_owner_project
  assert_status: 503

service_cannot_delete_other_nodes_vifs:
  path: '/v1/nodes/{owner_node_ident}/vifs/{vif_ident}'
  method: delete
  headers: *service_headers
  assert_status: 404

# Indicators - https://docs.openstack.org/api-ref/baremetal/#indicators-management
owner_readers_can_get_indicators:
  path: '/v1/nodes/{owner_node_ident}/management/indicators'
  method: get
  headers: *owner_reader_headers
  assert_status: 503

lesse_readers_can_get_indicators:
  path: '/v1/nodes/{lessee_node_ident}/management/indicators'
  method: get
  headers: *lessee_reader_headers
  assert_status: 503

third_party_admin_cannot_get_indicators:
  path: '/v1/nodes/{owner_node_ident}/management/indicators'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

owner_reader_can_get_indicator_status:
  path: '/v1/nodes/{owner_node_ident}/management/indicators/{ind_component}/{ind_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  skip_reason: API appears to be broken and should be patched outside of this work.

lessee_reader_not_get_indicator_status:
  path: '/v1/nodes/{lessee_node_ident}/management/indicators/{ind_component}/{ind_ident}'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200
  skip_reason: API appears to be broken and should be patched outside of this work.

owner_member_can_set_indicator:
  path: '/v1/nodes/{owner_node_ident}/management/indicators/{ind_component}/{ind_ident}'
  method: put
  headers: *owner_member_headers
  assert_status: 503

lessee_member_cannot_set_indicator:
  path: '/v1/nodes/{lessee_node_ident}/management/indicators/{ind_component}/{ind_ident}'
  method: put
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_set_indicator:
  path: '/v1/nodes/{node_ident}/management/indicators/{ind_component}/{ind_ident}'
  method: put
  headers: *third_party_admin_headers
  assert_status: 404

# Portgroups -  https://docs.openstack.org/api-ref/baremetal/#portgroups-portgroups

# Based on portgroups_* tests

owner_reader_can_list_portgroups:
  path: '/v1/portgroups'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  assert_list_length:
    portgroups: 2

owner_service_can_list_portgroups:
  path: '/v1/portgroups'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200
  assert_list_length:
    portgroups: 2

lessee_reader_can_list_portgroups:
  path: '/v1/portgroups'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200
  assert_list_length:
    portgroups: 1

third_party_admin_cannot_list_portgroups:
  path: '/v1/portgroups'
  method: get
  headers: *third_party_admin_headers
  assert_status: 200
  assert_list_length:
    portgroups: 0

owner_reader_can_read_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

lessee_reader_can_read_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_read_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

# NB: Ports have to be posted with a node UUID to associate to,
# so that seems policy-check-able.
owner_admin_can_add_portgroup:
  path: '/v1/portgroups'
  method: post
  headers: *owner_admin_headers
  body: &owner_portgroup_body
    node_uuid: 1ab63b9e-66d7-4cd7-8618-dddd0f9f7881
  assert_status: 201

owner_service_can_add_portgroup:
  path: '/v1/portgroups'
  method: post
  headers: *service_headers_owner_project
  body: *owner_portgroup_body
  assert_status: 201

owner_manager_can_add_portgroup:
  path: '/v1/portgroups'
  method: post
  headers: *owner_manager_headers
  body: *owner_portgroup_body
  assert_status: 201

owner_member_cannot_add_portgroup:
  path: '/v1/portgroups'
  method: post
  headers: *owner_member_headers
  body: *owner_portgroup_body
  assert_status: 403

lessee_admin_cannot_add_portgroup:
  path: '/v1/portgroups'
  method: post
  headers: *lessee_admin_headers
  body: &lessee_portgroup_body
    node_uuid: 38d5abed-c585-4fce-a57e-a2ffc2a2ec6f
  assert_status: 403

lessee_manager_cannot_add_portgroup:
  path: '/v1/portgroups'
  method: post
  headers: *lessee_manager_headers
  body: *lessee_portgroup_body
  assert_status: 403

# TODO, likely will need separate port/port groups established for the tests

lessee_member_cannot_add_portgroup:
  path: '/v1/portgroups'
  method: post
  headers: *lessee_member_headers
  body: *lessee_portgroup_body
  assert_status: 403

third_party_admin_cannot_add_portgroup:
  path: '/v1/portgroups'
  method: post
  headers: *third_party_admin_headers
  body: *lessee_portgroup_body
  assert_status: 403

owner_admin_can_modify_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: patch
  headers: *owner_admin_headers
  body: &portgroup_patch_body
    - op: replace
      path: /extra
      value: {'test': 'testing'}
  assert_status: 503

owner_manager_can_modify_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *portgroup_patch_body
  assert_status: 503

owner_member_cannot_modify_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: patch
  headers: *owner_member_headers
  body: *portgroup_patch_body
  assert_status: 403

lessee_admin_cannot_modify_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}'
  method: patch
  headers: *lessee_admin_headers
  body: *portgroup_patch_body
  assert_status: 403

lessee_manager_cannot_modify_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}'
  method: patch
  headers: *lessee_manager_headers
  body: *portgroup_patch_body
  assert_status: 403

lessee_member_cannot_modify_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}'
  method: patch
  headers: *lessee_member_headers
  body: *portgroup_patch_body
  assert_status: 403

third_party_admin_cannot_modify_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}'
  method: patch
  headers: *third_party_admin_headers
  body: *portgroup_patch_body
  assert_status: 404

owner_admin_cannot_rehome_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: patch
  headers: *owner_admin_headers
  body: &other_node_portgroup_patch_body
    - op: replace
      path: /node_uuid
      value: 573208e5-cd41-4e26-8f06-ef44022b3793
  assert_status: 400

owner_manager_cannot_rehome_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *other_node_portgroup_patch_body
  assert_status: 400

owner_service_cannot_rehome_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: patch
  headers: *service_headers_owner_project
  body: *other_node_portgroup_patch_body
  assert_status: 400

owner_admin_can_delete_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: delete
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_delete_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: delete
  headers: *owner_manager_headers
  assert_status: 503

owner_member_cannot_delete_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: delete
  headers: *owner_member_headers
  assert_status: 403

owner_service_can_delete_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}'
  method: delete
  headers: *service_headers_owner_project
  assert_status: 503

lessee_admin_cannot_delete_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_delete_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 403

lessee_member_cannot_delete_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}'
  method: delete
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_delete_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}'
  method: delete
  headers: *third_party_admin_headers
  assert_status: 404

service_cannot_delete_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}'
  method: delete
  headers: *service_headers
  assert_status: 404

# Portgroups by node - https://docs.openstack.org/api-ref/baremetal/#listing-portgroups-by-node-nodes-portgroups

owner_reader_can_get_node_portgroups:
  path: '/v1/nodes/{owner_node_ident}/portgroups'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

lessee_reader_can_get_node_porgtroups:
  path: '/v1/nodes/{lessee_node_ident}/portgroups'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_get_portgroups:
  path: '/v1/nodes/{lessee_node_ident}/portgroups'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

service_cannot_get_portgroups:
  path: '/v1/nodes/{lessee_node_ident}/portgroups'
  method: get
  headers: *service_headers
  assert_status: 404


# Ports - https://docs.openstack.org/api-ref/baremetal/#ports-ports

# Based on ports_* tests

owner_reader_can_list_ports:
  path: '/v1/ports'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  # Two ports owned, one on the leased node. 1 invisible.
  assert_list_length:
    ports: 3

owner_service_can_list_ports:
  path: '/v1/ports'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200
  # Two ports owned, one on the leased node. 1 invisible.
  assert_list_length:
    ports: 3

lessee_reader_can_list_ports:
  path: '/v1/ports'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200
  assert_list_length:
    ports: 1

third_party_admin_cannot_list_ports:
  path: '/v1/ports'
  method: get
  headers: *third_party_admin_headers
  assert_status: 200
  assert_list_length:
    ports: 0

owner_reader_can_read_port:
  path: '/v1/ports/{owner_port_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

owner_service_can_read_port:
  path: '/v1/ports/{owner_port_ident}'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200

lessee_reader_can_read_port:
  path: '/v1/ports/{lessee_port_ident}'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_read_port:
  path: '/v1/ports/{other_port_ident}'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

# NB: Ports have to be posted with a node UUID to associate to,
# so that seems policy-check-able.
owner_admin_can_add_ports:
  path: '/v1/ports'
  method: post
  headers: *owner_admin_headers
  body: &owner_port_body
    node_uuid: 1ab63b9e-66d7-4cd7-8618-dddd0f9f7881
    address: 00:01:02:03:04:05
  assert_status: 503

owner_manager_can_add_ports:
  path: '/v1/ports'
  method: post
  headers: *owner_manager_headers
  body: *owner_port_body
  assert_status: 503

owner_admin_cannot_add_ports_to_other_nodes:
  path: '/v1/ports'
  method: post
  headers: *owner_admin_headers
  body: &other_node_add_port_body
    node_uuid: 573208e5-cd41-4e26-8f06-ef44022b3793
    address: 09:01:02:03:04:09
  assert_status: 403

owner_manager_cannot_add_ports_to_other_nodes:
  path: '/v1/ports'
  method: post
  headers: *owner_manager_headers
  body: *other_node_add_port_body
  assert_status: 403

owner_service_cannot_add_ports_to_other_nodes:
  path: '/v1/ports'
  method: post
  headers: *service_headers_owner_project
  body: *other_node_add_port_body
  assert_status: 403

owner_member_cannot_add_port:
  path: '/v1/ports'
  method: post
  headers: *owner_member_headers
  body: *owner_port_body
  assert_status: 403

lessee_admin_cannot_add_port:
  path: '/v1/ports'
  method: post
  headers: *lessee_admin_headers
  body: &lessee_port_body
    node_uuid: 38d5abed-c585-4fce-a57e-a2ffc2a2ec6f
    address: 00:01:02:03:04:05
  assert_status: 403

lessee_manager_cannot_add_port:
  path: '/v1/ports'
  method: post
  headers: *lessee_manager_headers
  body: *lessee_port_body
  assert_status: 403

lessee_member_cannot_add_port:
  path: '/v1/ports'
  method: post
  headers: *lessee_member_headers
  body: *lessee_port_body
  assert_status: 403

third_party_admin_cannot_add_port:
  path: '/v1/ports'
  method: post
  headers: *third_party_admin_headers
  body: *lessee_port_body
  assert_status: 403

service_can_add_port:
  path: '/v1/ports'
  method: post
  headers: *service_headers_owner_project
  body: *owner_port_body
  assert_status: 503

service_cannot_add_ports_to_other_project:
  path: '/v1/ports'
  method: post
  headers: *service_headers
  body: *owner_port_body
  assert_status: 403

owner_admin_can_modify_port:
  path: '/v1/ports/{owner_port_ident}'
  method: patch
  headers: *owner_admin_headers
  body: &port_patch_body
    - op: replace
      path: /extra
      value: {'test': 'testing'}
  assert_status: 503

owner_manager_can_modify_port:
  path: '/v1/ports/{owner_port_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *port_patch_body
  assert_status: 503

owner_service_can_modify_port:
  path: '/v1/ports/{owner_port_ident}'
  method: patch
  headers: *service_headers_owner_project
  body: *port_patch_body
  assert_status: 503

owner_member_cannot_modify_port:
  path: '/v1/ports/{owner_port_ident}'
  method: patch
  headers: *owner_member_headers
  body: *port_patch_body
  assert_status: 403

lessee_admin_cannot_modify_port:
  path: '/v1/ports/{lessee_port_ident}'
  method: patch
  headers: *lessee_admin_headers
  body: *port_patch_body
  assert_status: 403

lessee_manager_cannot_modify_port:
  path: '/v1/ports/{lessee_port_ident}'
  method: patch
  headers: *lessee_manager_headers
  body: *port_patch_body
  assert_status: 403

lessee_member_cannot_modify_port:
  path: '/v1/ports/{lessee_port_ident}'
  method: patch
  headers: *lessee_member_headers
  body: *port_patch_body
  assert_status: 403

third_party_admin_cannot_modify_port:
  path: '/v1/ports/{lessee_port_ident}'
  method: patch
  headers: *third_party_admin_headers
  body: *port_patch_body
  assert_status: 404

owner_admin_can_delete_port:
  path: '/v1/ports/{owner_port_ident}'
  method: delete
  headers: *owner_admin_headers
  assert_status: 503

owner_admin_cannot_rehome_port:
  path: '/v1/ports/{owner_port_ident}'
  method: patch
  headers: *owner_admin_headers
  body: &other_node_port_patch_body
    - op: replace
      path: /node_uuid
      value: 573208e5-cd41-4e26-8f06-ef44022b3793
  assert_status: 400

owner_manager_cannot_rehome_port:
  path: '/v1/ports/{owner_port_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *other_node_port_patch_body
  assert_status: 400

owner_service_cannot_rehome_port:
  path: '/v1/ports/{owner_port_ident}'
  method: patch
  headers: *service_headers_owner_project
  body: *other_node_port_patch_body
  assert_status: 400

owner_manager_can_delete_port:
  path: '/v1/ports/{owner_port_ident}'
  method: delete
  headers: *owner_manager_headers
  assert_status: 503

owner_service_can_delete_port:
  path: '/v1/ports/{owner_port_ident}'
  method: delete
  headers: *service_headers_owner_project
  assert_status: 503

owner_member_cannot_delete_port:
  path: '/v1/ports/{owner_port_ident}'
  method: delete
  headers: *owner_member_headers
  assert_status: 403

lessee_admin_cannot_delete_port:
  path: '/v1/ports/{lessee_port_ident}'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 403

lessee_manager_cannot_delete_port:
  path: '/v1/ports/{lessee_port_ident}'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 403

lessee_member_cannot_delete_port:
  path: '/v1/ports/{lessee_port_ident}'
  method: delete
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_delete_port:
  path: '/v1/ports/{lessee_port_ident}'
  method: delete
  headers: *third_party_admin_headers
  assert_status: 404

# Ports by node - https://docs.openstack.org/api-ref/baremetal/#listing-ports-by-node-nodes-ports

owner_reader_can_get_node_ports:
  path: '/v1/nodes/{owner_node_ident}/ports'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  assert_list_length:
    ports: 2

owner_service_can_get_node_ports:
  path: '/v1/nodes/{owner_node_ident}/ports'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200
  assert_list_length:
    ports: 2

lessee_reader_can_get_node_port:
  path: '/v1/nodes/{lessee_node_ident}/ports'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200
  assert_list_length:
    ports: 1

third_party_admin_cannot_get_ports:
  path: '/v1/nodes/{lessee_node_ident}/ports'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

service_cannot_get_ports:
  path: '/v1/nodes/{lessee_node_ident}/ports'
  method: get
  headers: *service_headers
  assert_status: 404

# Ports by portgroup - https://docs.openstack.org/api-ref/baremetal/#listing-ports-by-portgroup-portgroup-ports

# Based on portgroups_ports_get* tests

owner_reader_can_get_ports_by_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}/ports'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

owner_service_cam_get_ports_by_portgroup:
  path: '/v1/portgroups/{owner_portgroup_ident}/ports'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200

lessee_reader_can_get_ports_by_portgroup:
  path: '/v1/portgroups/{lessee_portgroup_ident}/ports'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_get_ports_by_portgroup:
  path: '/v1/portgroups/{other_portgroup_ident}/ports'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

service_cannot_get_ports_by_portgroup:
  path: '/v1/portgroups/{other_portgroup_ident}/ports'
  method: get
  headers: *service_headers
  assert_status: 404


# Volume(s) - https://docs.openstack.org/api-ref/baremetal/#volume-volume
# TODO(TheJulia): volumes will likely need some level of exhaustive testing.
# i.e. ensure that the volume is permissible. However this may not be possible
# here.

# Volume connectors

owner_reader_can_list_volume_connectors:
  path: '/v1/volume/connectors'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  assert_list_length:
    connectors: 2

lessee_reader_can_list_volume_connectors:
  path: '/v1/volume/connectors'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200
  assert_list_length:
    connectors: 1

third_party_admin_cannot_get_connector_list:
  path: '/v1/volume/connectors'
  method: get
  headers: *third_party_admin_headers
  assert_status: 200
  assert_list_length:
    connectors: 0

owner_admin_can_post_volume_connector:
  path: '/v1/volume/connectors'
  method: post
  headers: *owner_admin_headers
  assert_status: 201
  body: &volume_connector_body
    node_uuid: 1ab63b9e-66d7-4cd7-8618-dddd0f9f7881
    type: ip
    connector_id: 192.168.1.100

owner_manager_can_post_volume_connector:
  path: '/v1/volume/connectors'
  method: post
  headers: *owner_manager_headers
  assert_status: 201
  body: *volume_connector_body

owner_service_can_post_volume_connector:
  path: '/v1/volume/connectors'
  method: post
  headers: *service_headers_owner_project
  assert_status: 201
  body: *volume_connector_body

lessee_admin_cannot_post_volume_connector:
  path: '/v1/volume/connectors'
  method: post
  headers: *lessee_admin_headers
  assert_status: 403
  body: *volume_connector_body

lessee_manager_cannot_post_volume_connector:
  path: '/v1/volume/connectors'
  method: post
  headers: *lessee_manager_headers
  assert_status: 403
  body: *volume_connector_body

third_party_admin_cannot_post_volume_connector:
  path: '/v1/volume/connectors'
  method: post
  headers: *third_party_admin_headers
  assert_status: 403
  body: *volume_connector_body

service_admin_cannot_post_volume_connector:
  path: '/v1/volume/connectors'
  method: post
  headers: *service_headers
  assert_status: 403
  body: *volume_connector_body

owner_reader_can_get_volume_connector:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

lessee_reader_can_get_volume_connector:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_get_volume_connector:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

lessee_member_cannot_patch_volume_connectors_extra:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *lessee_member_headers
  body: &connector_patch_body
    - op: replace
      path: /extra
      value: {'test': 'testing'}
  assert_status: 403

owner_admin_can_patch_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *owner_admin_headers
  body: *connector_patch_body
  assert_status: 503

owner_manager_can_patch_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *connector_patch_body
  assert_status: 503

# FIXME This test is wrong, name is updated
lessee_admin_cannot_patch_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *owner_admin_headers
  body: *connector_patch_body
  assert_status: 503

lessee_manager_can_patch_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *connector_patch_body
  assert_status: 503

owner_member_can_patch_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *owner_member_headers
  body: *connector_patch_body
  assert_status: 503

lessee_member_cannot_patch_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *lessee_member_headers
  body: *connector_patch_body
  assert_status: 403

third_party_admin_cannot_patch_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *third_party_admin_headers
  body: *connector_patch_body
  assert_status: 404

owner_admin_cannot_rehome_volume_connector:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *owner_admin_headers
  body: &other_node_connector_patch_body
    - op: replace
      path: /node_uuid
      value: 573208e5-cd41-4e26-8f06-ef44022b3793
  assert_status: 400

owner_manager_cannot_rehome_volume_connector:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *other_node_connector_patch_body
  assert_status: 400

owner_service_cannot_rehome_volume_connector:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: patch
  headers: *service_headers_owner_project
  body: *other_node_connector_patch_body
  assert_status: 400

owner_admin_can_delete_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: delete
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_delete_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: delete
  headers: *owner_manager_headers
  assert_status: 503

owner_service_can_delete_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: delete
  headers: *service_headers_owner_project
  assert_status: 503

lessee_admin_can_delete_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 503

lessee_manager_can_delete_volume_connectors:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 503

third_party_admin_cannot_delete_volume_connector:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: delete
  headers: *third_party_admin_headers
  assert_status: 404

service_cannot_delete_volume_connector:
  path: '/v1/volume/connectors/{volume_connector_ident}'
  method: delete
  headers: *service_headers
  assert_status: 404

# Volume targets

# TODO(TheJulia): Create at least 3 targets.
owner_reader_can_get_targets:
  path: '/v1/volume/targets'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  assert_list_length:
    targets: 2

lesse_reader_can_get_targets:
  path: '/v1/volume/targets'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200
  assert_list_length:
    targets: 1

third_party_admin_cannot_get_target_list:
  path: '/v1/volume/targets'
  method: get
  headers: *third_party_admin_headers
  assert_status: 200
  assert_list_length:
    targets: 0

owner_reader_can_get_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  assert_dict_contains:
    # This helps assert that the field has been redacted.
    properties:
      redacted_contents: '** Value redacted: Requires permission baremetal:volume:view_target_properties access. Permission denied. **'

lessee_reader_can_get_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_get_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

owner_admin_create_volume_target:
  path: '/v1/volume/targets'
  method: post
  headers: *owner_admin_headers
  assert_status: 201
  body: &volume_target_body
    node_uuid: 1ab63b9e-66d7-4cd7-8618-dddd0f9f7881
    volume_type: iscsi
    boot_index: 2
    volume_id: 'test-id'

owner_service_create_volume_target:
  path: '/v1/volume/targets'
  method: post
  headers: *service_headers_owner_project
  assert_status: 201
  body: *volume_target_body

owner_manager_create_volume_target:
  path: '/v1/volume/targets'
  method: post
  headers: *owner_manager_headers
  assert_status: 201
  body:
    node_uuid: 1ab63b9e-66d7-4cd7-8618-dddd0f9f7881
    volume_type: iscsi
    boot_index: 3
    volume_id: 'test-id'

lessee_admin_create_volume_target:
  path: '/v1/volume/targets'
  method: post
  headers: *lessee_admin_headers
  assert_status: 201
  body:
    node_uuid: 38d5abed-c585-4fce-a57e-a2ffc2a2ec6f
    volume_type: iscsi
    boot_index: 2
    volume_id: 'test-id2'

lessee_manager_create_volume_target:
  path: '/v1/volume/targets'
  method: post
  headers: *owner_manager_headers
  assert_status: 201
  body:
    node_uuid: 38d5abed-c585-4fce-a57e-a2ffc2a2ec6f
    volume_type: iscsi
    boot_index: 2
    volume_id: 'test-id3'

third_party_admin_cannot_create_volume_target:
  path: '/v1/volume/targets'
  method: post
  headers: *third_party_admin_headers
  assert_status: 403
  body: *volume_target_body

owner_member_can_patch_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: patch
  body: &volume_target_patch
    - op: replace
      path: /extra
      value: {'test': 'testing'}
  headers: *owner_member_headers
  assert_status: 503

owner_service_can_patch_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: patch
  body: *volume_target_patch
  headers: *service_headers_owner_project
  assert_status: 503

lessee_admin_can_patch_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: patch
  body: *volume_target_patch
  headers: *lessee_admin_headers
  assert_status: 503

lessee_manager_can_patch_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: patch
  body: *volume_target_patch
  headers: *lessee_manager_headers
  assert_status: 503

lessee_member_cannot_patch_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: patch
  body: *volume_target_patch
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_patch_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: patch
  body: *volume_target_patch
  headers: *third_party_admin_headers
  assert_status: 404

service_cannot_patch_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: patch
  body: *volume_target_patch
  headers: *service_headers
  assert_status: 404

owner_admin_cannot_rehome_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: patch
  headers: *owner_admin_headers
  body: &other_node_target_patch_body
    - op: replace
      path: /node_uuid
      value: 573208e5-cd41-4e26-8f06-ef44022b3793
  assert_status: 400

owner_manager_cannot_rehome_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *other_node_target_patch_body
  assert_status: 400

owner_service_cannot_rehome_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: patch
  headers: *service_headers_owner_project
  body: *other_node_target_patch_body
  assert_status: 400

owner_admin_can_delete_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: delete
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_delete_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: delete
  headers: *owner_manager_headers
  assert_status: 503

owner_manager_can_delete_volume_target_service:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: delete
  headers: *service_headers_owner_project
  assert_status: 503

lessee_admin_can_delete_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 503

lessee_manager_can_delete_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 503

owner_member_cannot_delete_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: delete
  headers: *owner_member_headers
  assert_status: 403

lessee_member_cannot_delete_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: delete
  headers: *lessee_member_headers
  assert_status: 403

third_party_admin_cannot_delete_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: delete
  headers: *third_party_admin_headers
  assert_status: 404

service_cannot_delete_volume_target:
  path: '/v1/volume/targets/{volume_target_ident}'
  method: delete
  headers: *service_headers
  assert_status: 404

# Get Volumes by Node - https://docs.openstack.org/api-ref/baremetal/#listing-volume-resources-by-node-nodes-volume

owner_reader_can_get_volume_connectors:
  path: '/v1/nodes/{owner_node_ident}/volume/connectors'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

owner_service_can_get_volume_connectors:
  path: '/v1/nodes/{owner_node_ident}/volume/connectors'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200

lessee_reader_can_get_node_volume_connectors:
  path: '/v1/nodes/{lessee_node_ident}/volume/connectors'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_get_node_volume_connectors:
  path: '/v1/nodes/{lessee_node_ident}/volume/connectors'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

service_cannot_get_node_volume_connectors:
  path: '/v1/nodes/{lessee_node_ident}/volume/connectors'
  method: get
  headers: *service_headers
  assert_status: 404

owner_reader_can_get_node_volume_targets:
  path: '/v1/nodes/{owner_node_ident}/volume/targets'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

owner_service_can_read_get_node_volume_targets:
  path: '/v1/nodes/{owner_node_ident}/volume/targets'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200

lessee_reader_can_get_node_volume_targets:
  path: '/v1/nodes/{lessee_node_ident}/volume/targets'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_part_admin_cannot_read_node_volume_targets:
  path: '/v1/nodes/{lessee_node_ident}/volume/targets'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

service_cannot_read_node_volume_targets:
  path: '/v1/nodes/{lessee_node_ident}/volume/targets'
  method: get
  headers: *service_headers
  assert_status: 404

# Drivers - https://docs.openstack.org/api-ref/baremetal/#drivers-drivers

# This is a system scoped endpoint, everything should fail in this section.

owner_reader_cannot_get_drivers:
  path: '/v1/drivers'
  method: get
  headers: *owner_reader_headers
  assert_status: 500

lessee_reader_cannot_get_drivers:
  path: '/v1/drivers'
  method: get
  headers: *lessee_reader_headers
  assert_status: 500

third_party_admin_cannot_get_drivers:
  path: '/v1/drivers'
  method: get
  headers: *third_party_admin_headers
  assert_status: 500

service_cannot_get_drivers:
  path: '/v1/drivers'
  method: get
  headers: *service_headers
  assert_status: 500

# Driver vendor passthru - https://docs.openstack.org/api-ref/baremetal/#driver-vendor-passthru-drivers

# This is a system scoped endpoint, everything should fail in this section.

owner_reader_cannot_get_drivers_vendor_passthru:
  path: '/v1/drivers/{driver_name}/vendor_passthru/methods'
  method: get
  headers: *owner_reader_headers
  assert_status: 500

lessee_reader_cannot_get_drivers_vendor_passthru:
  path: '/v1/drivers/{driver_name}/vendor_passthru/methods'
  method: get
  headers: *lessee_reader_headers
  assert_status: 500

third_party_admin_cannot_get_drivers_vendor_passthru:
  path: '/v1/drivers/{driver_name}/vendor_passthru/methods'
  method: get
  headers: *third_party_admin_headers
  assert_status: 500

service_cannot_get_drivers_vendor_passthru:
  path: '/v1/drivers/{driver_name}/vendor_passthru/methods'
  method: get
  headers: *service_headers
  assert_status: 500

# Node Bios - https://docs.openstack.org/api-ref/baremetal/#node-bios-nodes

owner_reader_can_get_bios_setttings:
  path: '/v1/nodes/{owner_node_ident}/bios'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

lessee_reader_can_get_bios_settings:
  path: '/v1/nodes/{lessee_node_ident}/bios'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_get_bios_settings:
  path: '/v1/nodes/{owner_node_ident}/bios'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

service_can_get_bios_setttings_owner_project:
  path: '/v1/nodes/{owner_node_ident}/bios'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200

service_cannot_get_bios_setttings:
  path: '/v1/nodes/{owner_node_ident}/bios'
  method: get
  headers: *service_headers
  assert_status: 404

# Conductors - https://docs.openstack.org/api-ref/baremetal/#allocations-allocations

# This is a system scoped endpoint, everything should fail in this section.

owner_reader_cannot_get_conductors:
  path: '/v1/conductors'
  method: get
  headers: *owner_reader_headers
  assert_status: 403

lessee_reader_cannot_get_conductors:
  path: '/v1/conductors'
  method: get
  headers: *lessee_reader_headers
  assert_status: 403

third_party_admin_cannot_get_conductors:
  path: '/v1/conductors'
  method: get
  headers: *third_party_admin_headers
  assert_status: 403

# Allocations - https://docs.openstack.org/api-ref/baremetal/#allocations-allocations

# This is a system scoped endpoint, everything should fail in this section.

owner_reader_can_get_allocations:
  path: '/v1/allocations'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200
  assert_list_length:
    allocations: 1

lessee_reader_can_get_allocations:
  path: '/v1/allocations'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200
  assert_list_length:
    allocations: 1

owner_reader_can_get_their_allocation:
  path: '/v1/allocations/{owner_allocation}'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  assert_dict_contains:
    resource_class: CUSTOM_TEST

lessee_reader_can_get_their_allocation:
  path: '/v1/allocations/{lessee_allocation}'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200
  assert_dict_contains:
    resource_class: CUSTOM_LEASED

owner_admin_can_delete_their_allocation:
  path: '/v1/allocations/{owner_allocation}'
  method: delete
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_delete_their_allocation:
  path: '/v1/allocations/{owner_allocation}'
  method: delete
  headers: *owner_manager_headers
  assert_status: 503

lessee_admin_can_delete_their_allocation:
  path: '/v1/allocations/{lessee_allocation}'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 503

lessee_manager_can_delete_their_allocation:
  path: '/v1/allocations/{lessee_allocation}'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 503

owner_member_can_delete_their_allocation:
  path: '/v1/allocations/{owner_allocation}'
  method: delete
  headers: *owner_member_headers
  assert_status: 503

# Lessee in this case owns the allocation,
# Confusing right?!
lessee_member_can_delete_their_allocation:
  path: '/v1/allocations/{lessee_allocation}'
  method: delete
  headers: *lessee_member_headers
  assert_status: 503

owner_member_can_patch_allocation:
  path: '/v1/allocations/{owner_allocation}'
  method: patch
  headers: *owner_member_headers
  body: &allocation_patch
    - op: replace
      path: /extra
      value: {'test': 'testing'}
  assert_status: 200

lessee_member_can_patch_allocation:
  path: '/v1/allocations/{lessee_allocation}'
  method: patch
  headers: *lessee_member_headers
  body: *allocation_patch
  assert_status: 200

third_party_admin_can_get_allocations:
  path: '/v1/allocations'
  method: get
  headers: *third_party_admin_headers
  assert_status: 200
  assert_list_length:
    allocations: 0

third_party_admin_can_create_allocation:
  # This is distinctly different than most other behavior,
  # should be applied to filter this, however this is also handled
  # in the conductor, the only case where a user *should* be able
  # to pass a UUID directly in though is a special case which
  # should not be possible unless the user is the owner of the
  # owner or lessee of the node.
  path: '/v1/allocations'
  method: post
  headers: *third_party_admin_headers
  body: &allocation_body
    resource_class: CUSTOM_TEST
  assert_status: 503

third_party_admin_cannot_create_allocation_with_owner_node:
  path: '/v1/allocations'
  method: post
  headers: *third_party_admin_headers
  body:
    resource_class: CUSTOM_TEST
    node: 1ab63b9e-66d7-4cd7-8618-dddd0f9f7881
  assert_status: 400

third_party_admin_cannot_create_allocation_with_candidates_not_owned:
  path: '/v1/allocations'
  method: post
  headers: *third_party_admin_headers
  body:
    resource_class: CUSTOM_TEST
    candidate_nodes:
      - 1ab63b9e-66d7-4cd7-8618-dddd0f9f7881
      - 38d5abed-c585-4fce-a57e-a2ffc2a2ec6f
  assert_status: 400

owner_admin_can_create_allocation_with_their_uuid:
  # NOTE(TheJulia): Owner/Lessee are equivalent in
  # this context, so testing only one is fine.
  path: '/v1/allocations'
  method: post
  headers: *owner_admin_headers
  body:
    resource_class: CUSTOM_TEST
    node: 1ab63b9e-66d7-4cd7-8618-dddd0f9f7881
  assert_status: 503

owner_manager_can_create_allocation_with_their_uuid:
  path: '/v1/allocations'
  method: post
  headers: *owner_manager_headers
  body:
    resource_class: CUSTOM_TEST
    node: 1ab63b9e-66d7-4cd7-8618-dddd0f9f7881
  assert_status: 503

third_party_admin_cannot_read_an_allocation:
  path: '/v1/allocations/{lessee_allocation}'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

third_party_admin_cannot_patch_an_allocation:
  path: '/v1/allocations/{owner_allocation}'
  method: patch
  headers: *third_party_admin_headers
  body:
    - op: replace
      path: /extra
      value: {'test': 'testing'}
  assert_status: 404

third_party_admin_cannot_delete_an_allocation:
  path: '/v1/allocations/{owner_allocation}'
  method: delete
  headers: *third_party_admin_headers
  assert_status: 404

# Allocations ( Node level) - https://docs.openstack.org/api-ref/baremetal/#node-allocation-allocations-nodes

owner_reader_can_read_node_allocation:
  path: '/v1/nodes/{owner_node_ident}/allocation'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

lessee_reader_can_read_node_allocation:
  path: '/v1/nodes/{lessee_node_ident}/allocation'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_read_node_allocation:
  path: '/v1/nodes/{owner_node_ident}/allocation'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

owner_admin_can_delete_allocation:
  path: '/v1/nodes/{owner_node_ident}/allocation'
  method: delete
  headers: *owner_admin_headers
  assert_status: 503

owner_manager_can_delete_allocation:
  path: '/v1/nodes/{owner_node_ident}/allocation'
  method: delete
  headers: *owner_manager_headers
  assert_status: 503

lessee_admin_can_delete_allocation:
  path: '/v1/nodes/{allocated_node_ident}/allocation'
  method: delete
  headers: *lessee_admin_headers
  assert_status: 503

lessee_manager_not_delete_allocation:
  path: '/v1/nodes/{allocated_node_ident}/allocation'
  method: delete
  headers: *lessee_manager_headers
  assert_status: 503

third_party_admin_cannot_delete_allocation:
  path: '/v1/nodes/{allocated_node_ident}/allocation'
  method: delete
  headers: *third_party_admin_headers
  assert_status: 404

# Deploy Templates - https://docs.openstack.org/api-ref/baremetal/#deploy-templates-deploy-templates

# This is a system scoped endpoint, everything should fail in this section
# with a status of 500..

owner_reader_cannot_get_deploy_templates:
  path: '/v1/deploy_templates'
  method: get
  headers: *owner_reader_headers
  assert_status: 403

lessee_reader_cannot_get_deploy_templates:
  path: '/v1/deploy_templates'
  method: get
  headers: *lessee_reader_headers
  assert_status: 403

third_party_admin_cannot_get_deploy_templates:
  path: '/v1/deploy_templates'
  method: get
  headers: *third_party_admin_headers
  assert_status: 403

third_party_admin_cannot_post_deploy_template:
  path: '/v1/deploy_templates'
  method: post
  body: &deploy_template
    name: 'CUSTOM_TEST_TEMPLATE'
    steps:
      - interface: 'deploy'
        step: 'noop'
        args: {}
        priority: 0
  headers: *third_party_admin_headers
  assert_status: 403

service_cannot_get_deploy_templates:
  path: '/v1/deploy_templates'
  method: get
  headers: *service_headers
  assert_status: 403

service_cannot_post_deploy_template:
  path: '/v1/deploy_templates'
  method: post
  body: *deploy_template
  headers: *service_headers
  assert_status: 403

# Chassis endpoints - https://docs.openstack.org/api-ref/baremetal/#chassis-chassis

# This is a system scoped endpoint, everything should fail in this section.

owner_reader_cannot_access_chassis:
  path: '/v1/chassis'
  method: get
  headers: *owner_reader_headers
  assert_status: 500

lessee_reader_cannot_access_chassis:
  path: '/v1/chassis'
  method: get
  headers: *lessee_reader_headers
  assert_status: 500

third_party_admin_cannot_access_chassis:
  path: '/v1/chassis'
  method: get
  headers: *third_party_admin_headers
  assert_status: 500

third_party_admin_cannot_create_chassis:
  path: '/v1/chassis'
  method: post
  headers: *third_party_admin_headers
  body:
    description: 'test-chassis'
  assert_status: 500

service_cannot_access_chassis:
  path: '/v1/chassis'
  method: get
  headers: *service_headers
  assert_status: 500

service_cannot_create_chassis:
  path: '/v1/chassis'
  method: post
  headers: *service_headers
  body:
    description: 'test-chassis'
  assert_status: 500

# Node history entries

node_history_get_admin:
  path: '/v1/nodes/{owner_node_ident}/history'
  method: get
  headers: *owner_admin_headers
  assert_status: 200
  assert_list_length:
    history: 1

node_history_get_member:
  path: '/v1/nodes/{owner_node_ident}/history'
  method: get
  headers: *owner_member_headers
  assert_status: 200
  assert_list_length:
    history: 1

node_history_get_reader:
  path: '/v1/nodes/{owner_node_ident}/history'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  assert_list_length:
    history: 1

node_history_get_service:
  path: '/v1/nodes/{owner_node_ident}/history'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200
  assert_list_length:
    history: 1

node_history_get_service_cannot_be_retrieved:
  path: '/v1/nodes/{owner_node_ident}/history'
  method: get
  headers: *service_headers
  assert_status: 404

node_history_get_entry_admin:
  path: '/v1/nodes/{owner_node_ident}/history/{owned_history_ident}'
  method: get
  headers: *owner_admin_headers
  assert_status: 200

node_history_get_entry_member:
  path: '/v1/nodes/{owner_node_ident}/history/{owned_history_ident}'
  method: get
  headers: *owner_member_headers
  assert_status: 200

node_history_get_entry_reader:
  path: '/v1/nodes/{owner_node_ident}/history/{owned_history_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

lessee_node_history_get_admin:
  path: '/v1/nodes/{node_ident}/history'
  method: get
  headers: *lessee_admin_headers
  assert_status: 404

lessee_node_history_get_member:
  path: '/v1/nodes/{node_ident}/history'
  method: get
  headers: *lessee_member_headers
  assert_status: 404

lessee_node_history_get_reader:
  path: '/v1/nodes/{node_ident}/history'
  method: get
  headers: *lessee_reader_headers
  assert_status: 404

lessee_node_history_get_entry_admin:
  path: '/v1/nodes/{node_ident}/history/{lessee_history_ident}'
  method: get
  headers: *lessee_admin_headers
  assert_status: 404

lessee_history_get_entry_member:
  path: '/v1/nodes/{node_ident}/history/{lessee_history_ident}'
  method: get
  headers: *lessee_member_headers
  assert_status: 404

lessee_node_history_get_entry_reader:
  path: '/v1/nodes/{node_ident}/history/{lessee_history_ident}'
  method: get
  headers: *lessee_reader_headers
  assert_status: 404

owner_service_node_history_get_entry_reader:
  path: '/v1/nodes/{owner_node_ident}/history/{owned_history_ident}'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200

third_party_admin_cannot_get_node_history:
  path: '/v1/nodes/{owner_node_ident}'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

node_history_get_entry_third_party_admin:
  path: '/v1/nodes/{owner_node_ident}/history/{owned_history_ident}'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

node_history_get_entry_service:
  path: '/v1/nodes/{owner_node_ident}/history/{owned_history_ident}'
  method: get
  headers: *service_headers
  assert_status: 404

# Node inventory support

node_inventory_get_admin:
  path: '/v1/nodes/{owner_node_ident}/inventory'
  method: get
  headers: *owner_admin_headers
  assert_status: 200

node_inventory_get_member:
  path: '/v1/nodes/{owner_node_ident}/inventory'
  method: get
  headers: *owner_member_headers
  assert_status: 200

node_inventory_get_reader:
  path: '/v1/nodes/{owner_node_ident}/inventory'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

lessee_node_inventory_get_admin:
  path: '/v1/nodes/{node_ident}/inventory'
  method: get
  headers: *lessee_admin_headers
  assert_status: 404

lessee_node_inventory_get_member:
  path: '/v1/nodes/{node_ident}/inventory'
  method: get
  headers: *lessee_member_headers
  assert_status: 404

lessee_node_inventory_get_reader:
  path: '/v1/nodes/{node_ident}/inventory'
  method: get
  headers: *lessee_reader_headers
  assert_status: 404

# Shard support - system scoped req'd to set on a node or view via /v1/shards
shard_get_shards_disallowed:
  path: '/v1/shards'
  method: get
  headers: *owner_reader_headers
  assert_status: 403

shard_patch_set_node_shard_disallowed:
  path: '/v1/nodes/{owner_node_ident}'
  method: patch
  headers: *owner_admin_headers
  body:
    - op: replace
      path: /shard
      value: 'TestShard'
  assert_status: 403

# Create node with parent_node field

admin_can_create_node_with_parent:
  path: '/v1/nodes'
  method: post
  headers: *owner_admin_headers
  body:
    driver: fake
    parent_node: *owned_node_ident
  assert_status: 503

admin_cannot_create_node_with_non_existing_parent:
  path: '/v1/nodes'
  method: post
  headers: *owner_admin_headers
  body:
    driver: fake
    parent_node: 'f11853c7-fa9c-4db3-a477-c9d8e0dbbf13'
  assert_status: 400

admin_cannot_create_node_with_parent_they_cannot_see:
  path: '/v1/nodes'
  method: post
  headers: *owner_admin_headers
  body:
    driver: fake
    parent_node: '{node_ident}'
  assert_status: 400

# Update node parent_node field - baremetal:node:update:parent_node

parent_node_patch_by_admin:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *owner_admin_headers
  body: &patch_parent_node
    - op: replace
      path: /parent_node
      value: *owned_node_ident
  assert_status: 403

parent_node_patch_by_member:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *owner_member_headers
  body: *patch_parent_node
  assert_status: 403

parent_node_patch_by_reader:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *owner_reader_headers
  body: *patch_parent_node
  assert_status: 403

parent_node_patch_by_manager:
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *owner_manager_headers
  body: *patch_parent_node
  assert_status: 403

parent_node_patch_by_cannot_see_node:
  # Avoid exposing whether the node exists if not authorized
  path: '/v1/nodes/{lessee_node_ident}'
  method: patch
  headers: *owner_admin_headers
  body:
    - op: replace
      path: /parent_node
      value: 'f11853c7-fa9c-4db3-a477-c9d8e0dbbf13'
  assert_status: 403

parent_node_children_can_get_list_of_children:
  path: '/v1/nodes/{owner_node_ident}/children'
  method: get
  headers: *owner_reader_headers
  assert_status: 200
  assert_list_length:
    children: 1

lessee_cannot_get_a_nodes_children:
  path: '/v1/nodes/{owner_node_ident}/children'
  method: get
  headers: *lessee_reader_headers
  assert_status: 404

# Node Firmware

owner_reader_can_get_firmware_components:
  path: '/v1/nodes/{owner_node_ident}/firmware'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

lessee_reader_can_get_firmware_components:
  path: '/v1/nodes/{lessee_node_ident}/firmware'
  method: get
  headers: *lessee_reader_headers
  assert_status: 200

third_party_admin_cannot_get_firmware_components:
  path: '/v1/nodes/{owner_node_ident}/firmware'
  method: get
  headers: *third_party_admin_headers
  assert_status: 404

service_can_get_firmware_components_owner_project:
  path: '/v1/nodes/{owner_node_ident}/firmware'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200

service_cannot_get_firmware_components:
  path: '/v1/nodes/{owner_node_ident}/firmware'
  method: get
  headers: *service_headers
  assert_status: 404

# Runbooks - https://docs.openstack.org/api-ref/baremetal/#runbooks-templates

runbooks_post_admin:
  path: '/v1/runbooks'
  method: post
  body: &runbook_body
    name: 'CUSTOM_NAME'
    steps:
      - interface: 'raid'
        step: 'noop'
        args: {}
        order: 0
  headers: *owner_admin_headers
  assert_status: 201

runbooks_post_manager:
  path: '/v1/runbooks'
  method: post
  body: *runbook_body
  headers: *owner_manager_headers
  assert_status: 201

service_post_runbook:
  path: '/v1/runbooks'
  method: post
  body: *runbook_body
  headers: *service_headers_owner_project
  assert_status: 201

third_party_admin_post_runbook:
  path: '/v1/runbooks'
  method: post
  body: *runbook_body
  headers: *third_party_admin_headers
  assert_status: 201

runbooks_post_public_admin:
  path: '/v1/runbooks'
  method: post
  body: &runbook_body_public
    name: 'CUSTOM_NAME'
    public: true
    steps:
      - interface: 'raid'
        step: 'noop'
        args: {}
        order: 0
  headers: *owner_admin_headers
  assert_status: 400

runbooks_post_public_manager:
  path: '/v1/runbooks'
  method: post
  body: *runbook_body_public
  headers: *owner_manager_headers
  assert_status: 400

runbooks_post_public_service:
  path: '/v1/runbooks'
  method: post
  body: *runbook_body_public
  headers: *owner_admin_headers
  assert_status: 400

runbooks_patch_admin:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: &runbook_patch
    - op: replace
      path: /name
      value: 'CUSTOM_NAME'
  headers: *owner_admin_headers
  assert_status: 200

runbooks_patch_manager:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_patch
  headers: *owner_manager_headers
  assert_status: 200

service_patch_runbook:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_patch
  headers: *service_headers_owner_project
  assert_status: 200

project_admin_delete_runbook:
  path: '/v1/runbooks/{runbook_ident}'
  method: delete
  headers: *owner_admin_headers
  assert_status: 204

project_manager_delete_runbook:
  path: '/v1/runbooks/{runbook_ident}'
  method: delete
  headers: *owner_manager_headers
  assert_status: 204

service_get_runbooks:
  path: '/v1/runbooks'
  method: get
  headers: *service_headers_owner_project
  assert_status: 200

runbooks_project_admin:
  path: '/v1/runbooks'
  method: get
  headers: *owner_admin_headers
  assert_status: 200

runbooks_runbook_id_get_project_admin:
  path: '/v1/runbooks/{runbook_ident}'
  method: get
  headers: *owner_admin_headers
  assert_status: 200

project_admin_patch_runbook:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_patch
  headers: *owner_admin_headers
  assert_status: 200

runbooks_project_manager:
  path: '/v1/runbooks'
  method: get
  headers: *owner_manager_headers
  assert_status: 200

runbooks_runbook_id_get_project_manager:
  path: '/v1/runbooks/{runbook_ident}'
  method: get
  headers: *owner_manager_headers
  assert_status: 200

project_manager_patch_runbook:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_patch
  headers: *owner_manager_headers
  assert_status: 200

runbooks_project_member:
  path: '/v1/runbooks'
  method: get
  headers: *owner_member_headers
  assert_status: 200

runbooks_runbook_id_get_project_member:
  path: '/v1/runbooks/{runbook_ident}'
  method: get
  headers: *owner_member_headers
  assert_status: 200

runbooks_list_project_reader:
  path: '/v1/runbooks'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

runbooks_runbook_id_get_project_reader:
  path: '/v1/runbooks/{runbook_ident}'
  method: get
  headers: *owner_reader_headers
  assert_status: 200

runbooks_list_third_party_admin:
  path: '/v1/runbooks'
  method: get
  headers: *third_party_admin_headers
  assert_status: 200

project_reader_cannot_post_runbook:
  path: '/v1/runbooks'
  method: post
  body: *runbook_body
  headers: *owner_reader_headers
  assert_status: 403

project_reader_cannot_patch_runbook:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_patch
  headers: *owner_reader_headers
  assert_status: 403

project_reader_cannot_set_runbook_owner:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: &runbook_owner_patch
    - op: replace
      path: /owner
      value: 'new_owner'
  headers: *owner_reader_headers
  assert_status: 403

project_reader_cannot_set_runbook_public:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: &runbook_public_patch
    - op: replace
      path: /public
      value: true
  headers: *owner_reader_headers
  assert_status: 403

project_reader_cannot_delete_runbook:
  path: '/v1/runbooks/{runbook_ident}'
  method: delete
  headers: *owner_reader_headers
  assert_status: 403

project_member_cannot_post_runbook:
  path: '/v1/runbooks'
  method: post
  body: *runbook_body
  headers: *owner_member_headers
  assert_status: 403

project_member_cannot_patch_runbook:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_patch
  headers: *owner_member_headers
  assert_status: 403

project_member_cannot_set_runbook_owner:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_owner_patch
  headers: *owner_member_headers
  assert_status: 403

project_member_cannot_set_runbook_public:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_public_patch
  headers: *owner_member_headers
  assert_status: 403

project_member_cannot_delete_runbook:
  path: '/v1/runbooks/{runbook_ident}'
  method: delete
  headers: *owner_member_headers
  assert_status: 403

project_manager_cannot_set_runbook_owner:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_owner_patch
  headers: *owner_manager_headers
  assert_status: 403

project_manager_cannot_set_runbook_public:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_public_patch
  headers: *owner_manager_headers
  assert_status: 403

project_admin_cannot_set_runbook_owner:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_owner_patch
  headers: *owner_admin_headers
  assert_status: 403

project_admin_cannot_set_runbook_public:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_public_patch
  headers: *owner_admin_headers
  assert_status: 403

service_cannot_patch_runbook_owner:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_owner_patch
  headers: *service_headers_owner_project
  assert_status: 403

service_cannot_patch_runbook_public:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_public_patch
  headers: *service_headers_owner_project
  assert_status: 403

third_party_admin_cannot_patch_runbook_owner:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_owner_patch
  headers: *third_party_admin_headers
  assert_status: 403

third_party_admin_cannot_patch_runbook_public:
  path: '/v1/runbooks/{runbook_ident}'
  method: patch
  body: *runbook_public_patch
  headers: *third_party_admin_headers
  assert_status: 403
