Files
openstack-api-simulator/tools/os_api_inventory/catalog.py
T

1068 lines
42 KiB
Python

"""Canonical OpenStack service metadata + API-ref-style resource expansions.
Used by generate_packs.py to emit contracts/openstack/<series> packs.
Paths follow OpenStack API-ref conventions (Dalmatian baseline).
"""
from __future__ import annotations
from typing import Any
# name, type, port, version_path, default_mv, max_mv
SERVICES_META: list[tuple[str, str, int, str, str | None, str | None]] = [
("keystone", "identity", 5000, "/v3/", None, None),
("nova", "compute", 8774, "/v2.1/", "2.1", "2.96"),
("neutron", "network", 9696, "/v2.0/", None, None),
("glance", "image", 9292, "/v2/", None, None),
("cinder", "volumev3", 8776, "/v3/", "3.0", "3.70"),
("placement", "placement", 8003, "/", "1.0", "1.39"),
("heat", "orchestration", 8004, "/v1/", None, None),
("heat-cfn", "cloudformation", 8000, "/v1/", None, None),
("swift", "object-store", 8080, "/v1/", None, None),
("ironic", "baremetal", 6385, "/", "1.1", "1.90"),
("octavia", "load-balancer", 9876, "/v2/", None, None),
("barbican", "key-manager", 9311, "/v1/", None, None),
("manila", "sharev2", 8786, "/v2/", "2.0", "2.82"),
("designate", "dns", 9001, "/v2/", None, None),
("magnum", "container-infra", 9511, "/v1/", None, None),
("zun", "container", 9517, "/v1/", None, None),
("trove", "database", 8779, "/v1.0/", None, None),
("mistral", "workflowv2", 8989, "/v2/", None, None),
("aodh", "alarming", 8042, "/v2/", None, None),
("cloudkitty", "rating", 8889, "/v1/", None, None),
("freezer", "backup", 9090, "/v2/", None, None),
("blazar", "reservation", 1234, "/v1/", None, None),
("vitrage", "rca", 8999, "/", None, None),
("masakari", "instance-ha", 15868, "/v1/", None, None),
("tacker", "nfv-orchestration", 9890, "/", None, None),
("adjutant", "admin-logic", 5050, "/", None, None),
# Present on docs.openstack.org/2024.2/api (Dalmatian) index.
("watcher", "infra-optim", 9322, "/v1/", None, None),
("zaqar", "messaging", 8888, "/v2/", None, None),
]
SERIES: list[tuple[str, int]] = [
("yoga", 6),
("antelope", 7),
("caracal", 8),
("dalmatian", 9),
]
def _crud(
resource: str,
path: str,
key: str,
*,
detail: bool = True,
actions: list[str] | None = None,
nested: list[tuple[str, str, str]] | None = None,
) -> list[dict[str, Any]]:
"""Expand a resource into list/detail/create/show/update/delete + actions/nested."""
from app.openstack.singular import singular as _singularize
singular = _singularize(key)
ops: list[dict[str, Any]] = [
{
"operation_id": f"{resource}_list",
"method": "GET",
"path": path,
"resource_type": resource,
"collection_key": key,
"kind": "collection",
"status_code": 200,
},
{
"operation_id": f"{resource}_create",
"method": "POST",
"path": path,
"resource_type": resource,
"collection_key": key,
"item_key": singular,
"kind": "collection",
"status_code": 201,
"create_status": 201,
},
{
"operation_id": f"{resource}_show",
"method": "GET",
"path": f"{path}/{{id}}",
"resource_type": resource,
"collection_key": key,
"item_key": singular,
"kind": "item",
"status_code": 200,
},
{
"operation_id": f"{resource}_update",
"method": "PUT",
"path": f"{path}/{{id}}",
"resource_type": resource,
"collection_key": key,
"item_key": singular,
"kind": "item",
"status_code": 200,
},
{
"operation_id": f"{resource}_patch",
"method": "PATCH",
"path": f"{path}/{{id}}",
"resource_type": resource,
"collection_key": key,
"item_key": singular,
"kind": "item",
"status_code": 200,
},
{
"operation_id": f"{resource}_delete",
"method": "DELETE",
"path": f"{path}/{{id}}",
"resource_type": resource,
"collection_key": key,
"kind": "item",
"status_code": 204,
},
]
if detail:
ops.append(
{
"operation_id": f"{resource}_list_detail",
"method": "GET",
"path": f"{path}/detail",
"resource_type": resource,
"collection_key": key,
"kind": "detail",
"status_code": 200,
}
)
for action in actions or []:
ops.append(
{
"operation_id": f"{resource}_action_{action.replace('-', '_')}",
"method": "POST",
"path": f"{path}/{{id}}/action",
"resource_type": resource,
"collection_key": key,
"item_key": singular,
"kind": "action",
"action_name": action,
"status_code": 202,
}
)
# Prefer a single shared action endpoint once; expand only unique action names
# are stored as metadata — runtime uses one POST .../action route.
for nested_type, nested_path, nested_key in nested or []:
ops.extend(_crud(nested_type, nested_path, nested_key, detail=False, actions=None))
return ops
def _get(
path: str, op_id: str, resource: str, key: str | None = None, **extra: Any
) -> dict[str, Any]:
return {
"operation_id": op_id,
"method": "GET",
"path": path,
"resource_type": resource,
"collection_key": key,
"kind": "custom",
"status_code": 200,
**extra,
}
def _post(
path: str, op_id: str, resource: str, key: str | None = None, status: int = 201, **extra: Any
) -> dict[str, Any]:
return {
"operation_id": op_id,
"method": "POST",
"path": path,
"resource_type": resource,
"collection_key": key,
"kind": "custom",
"status_code": status,
**extra,
}
def keystone_ops() -> list[dict[str, Any]]:
ops: list[dict[str, Any]] = [
_get("/v3", "keystone_v3_root", "version", requires_project=False),
_post(
"/v3/auth/tokens",
"keystone_auth_tokens",
"token",
status=201,
requires_auth=False,
requires_project=False,
),
_get("/v3/auth/tokens", "keystone_validate_token", "token", requires_project=False),
_get("/v3/auth/catalog", "keystone_catalog", "catalog", requires_project=False),
]
for res, path, key in [
("domain", "/v3/domains", "domains"),
("project", "/v3/projects", "projects"),
("user", "/v3/users", "users"),
("group", "/v3/groups", "groups"),
("role", "/v3/roles", "roles"),
("region", "/v3/regions", "regions"),
("service", "/v3/services", "services"),
("endpoint", "/v3/endpoints", "endpoints"),
("credential", "/v3/credentials", "credentials"),
("policy", "/v3/policies", "policies"),
]:
ops.extend(_crud(res, path, key, detail=False))
ops.extend(
_crud(
"application_credential",
"/v3/users/{user_id}/application_credentials",
"application_credentials",
detail=False,
)
)
ops.extend(
[
_get(
"/v3/role_assignments",
"keystone_role_assignments",
"role_assignment",
"role_assignments",
),
_put(
"/v3/projects/{project_id}/users/{user_id}/roles/{role_id}",
"keystone_grant_project_role",
"role_assignment",
),
_delete_op(
"/v3/projects/{project_id}/users/{user_id}/roles/{role_id}",
"keystone_revoke_project_role",
"role_assignment",
),
_get(
"/v3/projects/{project_id}/users/{user_id}/roles",
"keystone_list_project_user_roles",
"role",
"roles",
),
_get(
"/v3/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles",
"keystone_inherit_roles",
"role",
"roles",
),
_get("/v3/limits", "keystone_limits", "limit", "limits"),
_get(
"/v3/registered_limits",
"keystone_registered_limits",
"registered_limit",
"registered_limits",
),
]
)
return ops
def _put(path: str, op_id: str, resource: str, key: str | None = None) -> dict[str, Any]:
return {
"operation_id": op_id,
"method": "PUT",
"path": path,
"resource_type": resource,
"collection_key": key,
"kind": "custom",
"status_code": 204,
}
def _delete_op(path: str, op_id: str, resource: str) -> dict[str, Any]:
return {
"operation_id": op_id,
"method": "DELETE",
"path": path,
"resource_type": resource,
"kind": "custom",
"status_code": 204,
}
def nova_ops() -> list[dict[str, Any]]:
server_actions = [
"os-start",
"os-stop",
"reboot",
"rebuild",
"resize",
"confirmResize",
"revertResize",
"pause",
"unpause",
"suspend",
"resume",
"shelve",
"shelveOffload",
"unshelve",
"lock",
"unlock",
"rescue",
"unrescue",
"createImage",
"createBackup",
"addFloatingIp",
"removeFloatingIp",
"addSecurityGroup",
"removeSecurityGroup",
"changePassword",
"evacuate",
"migrate",
"liveMigrate",
"resetState",
"os-getConsoleOutput",
"os-getVNCConsole",
"remote-consoles",
"trigger_crash_dump",
]
ops = _crud(
"server",
"/v2.1/servers",
"servers",
actions=server_actions,
nested=[
(
"volume_attachment",
"/v2.1/servers/{server_id}/os-volume_attachments",
"volumeAttachments",
),
(
"interface_attachment",
"/v2.1/servers/{server_id}/os-interface",
"interfaceAttachments",
),
("instance_action", "/v2.1/servers/{server_id}/os-instance-actions", "instanceActions"),
("server_metadata", "/v2.1/servers/{server_id}/metadata", "metadata"),
("server_tag", "/v2.1/servers/{server_id}/tags", "tags"),
(
"server_security_group",
"/v2.1/servers/{server_id}/os-security-groups",
"security_groups",
),
],
)
# Deduplicate action endpoints to a single POST route (schema engine handles body key)
ops = [o for o in ops if o.get("kind") != "action"]
ops.append(
{
"operation_id": "server_action",
"method": "POST",
"path": "/v2.1/servers/{id}/action",
"resource_type": "server",
"collection_key": "servers",
"kind": "action",
"status_code": 202,
"action_name": "*",
}
)
ops.extend(_crud("flavor", "/v2.1/flavors", "flavors"))
ops.extend(_crud("keypair", "/v2.1/os-keypairs", "keypairs", detail=False))
# keypairs use name as id
ops.extend(_crud("aggregate", "/v2.1/os-aggregates", "aggregates", detail=False))
ops.extend(_crud("server_group", "/v2.1/os-server-groups", "server_groups", detail=False))
ops.extend(
[
_get("/v2.1", "nova_versions", "version", requires_project=False),
_get("/v2.1/os-hypervisors", "hypervisor_list", "hypervisor", "hypervisors"),
_get("/v2.1/os-hypervisors/detail", "hypervisor_detail", "hypervisor", "hypervisors"),
_get("/v2.1/os-hypervisors/{id}", "hypervisor_show", "hypervisor", "hypervisors"),
_get(
"/v2.1/os-availability-zone", "az_list", "availability_zone", "availabilityZoneInfo"
),
_get(
"/v2.1/os-availability-zone/detail",
"az_detail",
"availability_zone",
"availabilityZoneInfo",
),
_get("/v2.1/os-services", "compute_services", "service", "services"),
_get("/v2.1/limits", "compute_limits", "limit", "limits"),
_get("/v2.1/os-quota-sets/{id}", "quota_set_show", "quota_set", "quota_set"),
_put("/v2.1/os-quota-sets/{id}", "quota_set_update", "quota_set", "quota_set"),
_get("/v2.1/os-quota-sets/{id}/detail", "quota_set_detail", "quota_set", "quota_set"),
_get("/v2.1/os-migrations", "migrations_list", "migration", "migrations"),
_get("/v2.1/os-networks", "nova_networks", "network", "networks"),
_get("/v2.1/os-tenant-networks", "nova_tenant_networks", "network", "networks"),
_get(
"/v2.1/os-security-groups",
"nova_security_groups",
"security_group",
"security_groups",
),
_get("/v2.1/os-floating-ips", "nova_floating_ips", "floating_ip", "floating_ips"),
_get(
"/v2.1/os-instance_usage_audit_log",
"instance_usage_audit",
"instance_usage_audit_log",
"instance_usage_audit_logs",
),
_get(
"/v2.1/os-assisted-volume-snapshots",
"assisted_volume_snapshots",
"assisted_volume_snapshot",
"snapshots",
),
_post(
"/v2.1/os-server-external-events",
"server_external_events",
"server_external_event",
"events",
status=200,
),
_get("/v2.1/servers/{server_id}/diagnostics", "server_diagnostics", "server"),
_get(
"/v2.1/servers/{server_id}/os-instance-actions/{request_id}",
"instance_action_show",
"instance_action",
"instanceAction",
),
_post(
"/v2.1/servers/{server_id}/remote-consoles",
"remote_console_create",
"remote_console",
"remote_console",
status=200,
),
_get(
"/v2.1/flavors/{id}/os-extra_specs",
"flavor_extra_specs",
"flavor_extra_spec",
"extra_specs",
),
_get("/v2.1/os-simple-tenant-usage", "simple_tenant_usage", "usage", "tenant_usages"),
_get("/v2.1/os-hosts", "os_hosts", "host", "hosts"),
# Additional Compute API-ref surface (Dalmatian).
_get("/v2.1/extensions", "nova_extensions", "extension", "extensions"),
_get("/v2.1/extensions/{id}", "nova_extension_show", "extension"),
*_crud("agent", "/v2.1/os-agents", "agents", detail=False),
*_crud(
"flavor_extra_spec",
"/v2.1/flavors/{flavor_id}/os-extra_specs",
"extra_specs",
detail=False,
),
*_crud(
"server_migration",
"/v2.1/servers/{server_id}/migrations",
"migrations",
detail=False,
),
*_crud("console", "/v2.1/servers/{server_id}/consoles", "consoles", detail=False),
_get(
"/v2.1/os-console-auth-tokens/{id}", "console_auth_token_show", "console_auth_token"
),
_get("/v2.1/servers/{server_id}/topology", "server_topology", "server"),
_get("/v2.1/servers/{server_id}/os-server-password", "server_password_show", "server"),
_delete_op(
"/v2.1/servers/{server_id}/os-server-password", "server_password_clear", "server"
),
_get("/v2.1/os-server-groups/{id}", "server_group_show", "server_group"),
]
)
return ops
def neutron_ops() -> list[dict[str, Any]]:
ops: list[dict[str, Any]] = [
_get("/v2.0", "neutron_versions", "version", requires_project=False)
]
for res, path, key in [
("network", "/v2.0/networks", "networks"),
("subnet", "/v2.0/subnets", "subnets"),
("port", "/v2.0/ports", "ports"),
("router", "/v2.0/routers", "routers"),
("floatingip", "/v2.0/floatingips", "floatingips"),
("security_group", "/v2.0/security-groups", "security_groups"),
("security_group_rule", "/v2.0/security-group-rules", "security_group_rules"),
("address_scope", "/v2.0/address-scopes", "address_scopes"),
("address_group", "/v2.0/address-groups", "address_groups"),
("subnetpool", "/v2.0/subnetpools", "subnetpools"),
("qos_policy", "/v2.0/qos/policies", "policies"),
("trunk", "/v2.0/trunks", "trunks"),
("rbac_policy", "/v2.0/rbac-policies", "rbac_policies"),
("metering_label", "/v2.0/metering/metering-labels", "metering_labels"),
("metering_label_rule", "/v2.0/metering/metering-label-rules", "metering_label_rules"),
("firewall_group", "/v2.0/fwaas/firewall_groups", "firewall_groups"),
("firewall_policy", "/v2.0/fwaas/firewall_policies", "firewall_policies"),
("firewall_rule", "/v2.0/fwaas/firewall_rules", "firewall_rules"),
("vpn_service", "/v2.0/vpn/vpnservices", "vpnservices"),
("ipsec_site_connection", "/v2.0/vpn/ipsec-site-connections", "ipsec_site_connections"),
("ike_policy", "/v2.0/vpn/ikepolicies", "ikepolicies"),
("ipsec_policy", "/v2.0/vpn/ipsecpolicies", "ipsecpolicies"),
("vpn_endpoint_group", "/v2.0/vpn/endpoint-groups", "endpoint_groups"),
("bgpvpn", "/v2.0/bgpvpn/bgpvpns", "bgpvpns"),
("bgp_speaker", "/v2.0/bgp-speakers", "bgp_speakers"),
("bgp_peer", "/v2.0/bgp-peers", "bgp_peers"),
("log", "/v2.0/log/logs", "logs"),
("ndp_proxy", "/v2.0/ndp_proxies", "ndp_proxies"),
("local_ip", "/v2.0/local_ips", "local_ips"),
("segment", "/v2.0/segments", "segments"),
("network_segment_range", "/v2.0/network_segment_ranges", "network_segment_ranges"),
("service_profile", "/v2.0/service_profiles", "service_profiles"),
("neutron_flavor", "/v2.0/flavors", "flavors"),
(
"default_security_group_rule",
"/v2.0/default-security-group-rules",
"default_security_group_rules",
),
("lbaas_loadbalancer", "/v2.0/lbaas/loadbalancers", "loadbalancers"),
("lbaas_listener", "/v2.0/lbaas/listeners", "listeners"),
("lbaas_pool", "/v2.0/lbaas/pools", "pools"),
]:
ops.extend(_crud(res, path, key, detail=False))
ops.extend(
[
_get("/v2.0/agents", "neutron_agents", "agent", "agents"),
_get("/v2.0/agents/{id}", "neutron_agent_show", "agent"),
_get("/v2.0/qos/rule-types", "qos_rule_types", "qos_rule_type", "rule_types"),
_get(
"/v2.0/network-ip-availabilities",
"network_ip_availabilities",
"network_ip_availability",
"network_ip_availabilities",
),
_get(
"/v2.0/auto-allocated-topology",
"auto_allocated_topology",
"auto_allocated_topology",
"auto_allocated_topology",
),
_get("/v2.0/quotas", "neutron_quota_list", "quota", "quotas"),
_get("/v2.0/quotas/{id}", "neutron_quota_show", "quota"),
_put("/v2.0/quotas/{id}", "neutron_quota_update", "quota"),
_delete_op("/v2.0/quotas/{id}", "neutron_quota_delete", "quota"),
_put("/v2.0/routers/{id}/add_router_interface", "router_add_interface", "router"),
_put("/v2.0/routers/{id}/remove_router_interface", "router_remove_interface", "router"),
_put("/v2.0/routers/{id}/add_extraroutes", "router_add_extraroutes", "router"),
_put("/v2.0/routers/{id}/remove_extraroutes", "router_remove_extraroutes", "router"),
*_crud(
"conntrack_helper",
"/v2.0/routers/{router_id}/conntrack_helpers",
"conntrack_helpers",
detail=False,
),
*_crud(
"qos_bandwidth_limit_rule",
"/v2.0/qos/policies/{policy_id}/bandwidth_limit_rules",
"bandwidth_limit_rules",
detail=False,
),
*_crud(
"qos_dscp_marking_rule",
"/v2.0/qos/policies/{policy_id}/dscp_marking_rules",
"dscp_marking_rules",
detail=False,
),
*_crud(
"qos_minimum_bandwidth_rule",
"/v2.0/qos/policies/{policy_id}/minimum_bandwidth_rules",
"minimum_bandwidth_rules",
detail=False,
),
*_crud(
"trunk_subport", "/v2.0/trunks/{trunk_id}/add_subports", "sub_ports", detail=False
),
*_crud(
"floatingip_port_forwarding",
"/v2.0/floatingips/{floatingip_id}/port_forwardings",
"port_forwardings",
detail=False,
),
*_crud(
"local_ip_association",
"/v2.0/local_ips/{local_ip_id}/port_associations",
"port_associations",
detail=False,
),
*_crud(
"bgpvpn_network_association",
"/v2.0/bgpvpn/bgpvpns/{bgpvpn_id}/network_associations",
"network_associations",
detail=False,
),
*_crud(
"bgpvpn_router_association",
"/v2.0/bgpvpn/bgpvpns/{bgpvpn_id}/router_associations",
"router_associations",
detail=False,
),
]
)
return ops
def glance_ops() -> list[dict[str, Any]]:
ops = [_get("/v2", "glance_versions", "version", requires_project=False)]
ops.extend(_crud("image", "/v2/images", "images", detail=False))
ops.extend(
[
_put("/v2/images/{id}/file", "image_upload", "image"),
_get("/v2/images/{id}/file", "image_download", "image"),
*_crud("metadef_namespace", "/v2/metadefs/namespaces", "namespaces", detail=False),
*_crud("task", "/v2/tasks", "tasks", detail=False),
_get("/v2/info/import", "glance_import_info", "info_import", "import-methods"),
_get("/v2/info/stores", "glance_stores", "info_store", "stores"),
_get("/v2/schemas/image", "glance_schema_image", "schema"),
_get("/v2/schemas/images", "glance_schema_images", "schema"),
_post("/v2/images/{id}/actions/deactivate", "image_deactivate", "image", status=204),
_post("/v2/images/{id}/actions/reactivate", "image_reactivate", "image", status=204),
*_crud("image_member", "/v2/images/{image_id}/members", "members", detail=False),
*_crud("image_tag", "/v2/images/{image_id}/tags", "tags", detail=False),
]
)
return ops
def cinder_ops() -> list[dict[str, Any]]:
ops = [_get("/v3", "cinder_versions", "version", requires_project=False)]
for res, path, key in [
("volume", "/v3/volumes", "volumes"),
("snapshot", "/v3/snapshots", "snapshots"),
("backup", "/v3/backups", "backups"),
("volume_type", "/v3/types", "volume_types"),
("qos_spec", "/v3/qos-specs", "qos_specs"),
("group", "/v3/groups", "groups"),
("group_snapshot", "/v3/group_snapshots", "group_snapshots"),
("consistencygroup", "/v3/consistencygroups", "consistencygroups"),
("attachment", "/v3/attachments", "attachments"),
("transfer", "/v3/volume-transfers", "transfers"),
("message", "/v3/messages", "messages"),
("cluster", "/v3/clusters", "clusters"),
]:
ops.extend(_crud(res, path, key))
# project-scoped aliases
ops.extend(_crud("volume_tenant", "/v3/{project_id}/volumes", "volumes"))
ops.extend(
[
{
"operation_id": "volume_action",
"method": "POST",
"path": "/v3/volumes/{id}/action",
"resource_type": "volume",
"kind": "action",
"status_code": 202,
"action_name": "*",
},
_get("/v3/os-services", "cinder_services", "service", "services"),
_get("/v3/limits", "cinder_limits", "limit", "limits"),
_get("/v3/os-quota-sets/{id}", "cinder_quota_show", "quota_set", "quota_set"),
_get(
"/v3/resource_filters",
"cinder_resource_filters",
"resource_filter",
"resource_filters",
),
_get("/v3/scheduler-stats/get_pools", "cinder_pools", "pool", "pools"),
]
)
return ops
def placement_ops() -> list[dict[str, Any]]:
ops = [
_get("/", "placement_root", "version", requires_project=False),
]
for res, path, key in [
("resource_provider", "/resource_providers", "resource_providers"),
("resource_class", "/resource_classes", "resource_classes"),
("trait", "/traits", "traits"),
]:
ops.extend(_crud(res, path, key, detail=False))
ops.extend(
[
_get("/allocations/{consumer_uuid}", "allocation_show", "allocation", "allocations"),
_put("/allocations/{consumer_uuid}", "allocation_set", "allocation"),
_delete_op("/allocations/{consumer_uuid}", "allocation_delete", "allocation"),
_get(
"/allocation_candidates",
"allocation_candidates",
"allocation_candidate",
"allocation_requests",
),
_get("/usages", "usages", "usage", "usages"),
_get(
"/resource_providers/{id}/inventories", "rp_inventories", "inventory", "inventories"
),
_put("/resource_providers/{id}/inventories", "rp_inventories_set", "inventory"),
_get("/resource_providers/{id}/aggregates", "rp_aggregates", "aggregate", "aggregates"),
_get("/resource_providers/{id}/traits", "rp_traits", "trait", "traits"),
_get("/resource_providers/{id}/usages", "rp_usages", "usage", "usages"),
_get(
"/resource_providers/{id}/allocations",
"rp_allocations",
"allocation",
"allocations",
),
]
)
return ops
def heat_ops() -> list[dict[str, Any]]:
ops = [_get("/v1", "heat_versions", "version", requires_project=False)]
base = "/v1/{tenant_id}"
ops.extend(_crud("stack", f"{base}/stacks", "stacks", detail=False))
ops.extend(
[
_get(f"{base}/stacks/detail", "stack_list_detail", "stack", "stacks"),
_get(
f"{base}/stacks/{{stack_name}}/{{stack_id}}", "stack_show_by_name", "stack", "stack"
),
_delete_op(
f"{base}/stacks/{{stack_name}}/{{stack_id}}", "stack_delete_by_name", "stack"
),
*_crud(
"stack_resource",
f"{base}/stacks/{{stack_name}}/{{stack_id}}/resources",
"resources",
detail=False,
),
*_crud(
"stack_event",
f"{base}/stacks/{{stack_name}}/{{stack_id}}/events",
"events",
detail=False,
),
*_crud("software_config", f"{base}/software_configs", "software_configs", detail=False),
*_crud(
"software_deployment",
f"{base}/software_deployments",
"software_deployments",
detail=False,
),
_get(
f"{base}/resource_types", "heat_resource_types", "resource_type", "resource_types"
),
_get(f"{base}/services", "heat_services", "service", "services"),
_post(f"{base}/stacks/preview", "stack_preview", "stack", "stack", status=200),
_post(f"{base}/validate", "template_validate", "template", status=200),
]
)
return ops
def heat_cfn_ops() -> list[dict[str, Any]]:
return [
*_crud("stack", "/stacks", "Stacks", detail=False),
_get("/v1", "heat_cfn_versions", "version", requires_project=False),
_post("/", "heat_cfn_query", "stack", status=200, requires_project=False),
]
def swift_ops() -> list[dict[str, Any]]:
return [
_get("/info", "swift_info", "info", requires_auth=False, requires_project=False),
_get("/v1/{account}", "swift_account_get", "account", requires_project=False),
_post("/v1/{account}", "swift_account_post", "account", status=204),
_get("/v1/{account}/{container}", "swift_container_get", "container"),
_put("/v1/{account}/{container}", "swift_container_put", "container"),
_delete_op("/v1/{account}/{container}", "swift_container_delete", "container"),
_get("/v1/{account}/{container}/{object}", "swift_object_get", "object"),
_put("/v1/{account}/{container}/{object}", "swift_object_put", "object"),
_delete_op("/v1/{account}/{container}/{object}", "swift_object_delete", "object"),
_post("/v1/{account}/{container}/{object}", "swift_object_post", "object", status=202),
]
def ironic_ops() -> list[dict[str, Any]]:
ops = [_get("/v1", "ironic_versions", "version", requires_project=False)]
for res, path, key in [
("node", "/v1/nodes", "nodes"),
("port", "/v1/ports", "ports"),
("portgroup", "/v1/portgroups", "portgroups"),
("chassis", "/v1/chassis", "chassis"),
("allocation", "/v1/allocations", "allocations"),
("deploy_template", "/v1/deploy_templates", "deploy_templates"),
("volume_connector", "/v1/volume/connectors", "connectors"),
("volume_target", "/v1/volume/targets", "targets"),
]:
ops.extend(_crud(res, path, key, detail=False))
ops.extend(
[
_get("/v1/drivers", "ironic_drivers", "driver", "drivers"),
_get("/v1/drivers/{name}", "ironic_driver_show", "driver"),
_get("/v1/conductors", "ironic_conductors", "conductor", "conductors"),
_put("/v1/nodes/{id}/states/provision", "node_provision_state", "node"),
_put("/v1/nodes/{id}/states/power", "node_power_state", "node"),
_put("/v1/nodes/{id}/states/raid", "node_raid_state", "node"),
_get("/v1/nodes/{id}/states", "node_states", "node"),
_get("/v1/nodes/{id}/vendor_passthru", "node_vendor_passthru", "node"),
{
"operation_id": "node_action",
"method": "POST",
"path": "/v1/nodes/{id}/vifs",
"resource_type": "node",
"kind": "action",
"status_code": 204,
},
]
)
return ops
def octavia_ops() -> list[dict[str, Any]]:
ops = [_get("/v2", "octavia_versions", "version", requires_project=False)]
for res, path, key in [
("loadbalancer", "/v2/lbaas/loadbalancers", "loadbalancers"),
("listener", "/v2/lbaas/listeners", "listeners"),
("pool", "/v2/lbaas/pools", "pools"),
("healthmonitor", "/v2/lbaas/healthmonitors", "healthmonitors"),
("l7policy", "/v2/lbaas/l7policies", "l7policies"),
("flavor", "/v2/lbaas/flavors", "flavors"),
("flavorprofile", "/v2/lbaas/flavorprofiles", "flavorprofiles"),
("amphora", "/v2/octavia/amphorae", "amphorae"),
("quota", "/v2/lbaas/quotas", "quotas"),
("provider", "/v2/lbaas/providers", "providers"),
]:
ops.extend(_crud(res, path, key, detail=False))
ops.extend(_crud("member", "/v2/lbaas/pools/{pool_id}/members", "members", detail=False))
ops.extend(_crud("l7rule", "/v2/lbaas/l7policies/{l7policy_id}/rules", "rules", detail=False))
ops.append(
{
"operation_id": "loadbalancer_failover",
"method": "PUT",
"path": "/v2/lbaas/loadbalancers/{id}/failover",
"resource_type": "loadbalancer",
"kind": "action",
"status_code": 202,
}
)
return ops
def _simple_service_ops(
resources: list[tuple[str, str, str]],
*,
version_get: tuple[str, str] | None = None,
extras: list[dict[str, Any]] | None = None,
) -> list[dict[str, Any]]:
ops: list[dict[str, Any]] = []
if version_get:
ops.append(_get(version_get[0], version_get[1], "version", requires_project=False))
for res, path, key in resources:
ops.extend(_crud(res, path, key, detail=False))
ops.extend(extras or [])
return ops
def build_all_operations() -> dict[str, list[dict[str, Any]]]:
return {
"keystone": keystone_ops(),
"nova": nova_ops(),
"neutron": neutron_ops(),
"glance": glance_ops(),
"cinder": cinder_ops(),
"placement": placement_ops(),
"heat": heat_ops(),
"heat-cfn": heat_cfn_ops(),
"swift": swift_ops(),
"ironic": ironic_ops(),
"octavia": octavia_ops(),
"barbican": _simple_service_ops(
[
("secret", "/v1/secrets", "secrets"),
("container", "/v1/containers", "containers"),
("order", "/v1/orders", "orders"),
("secret_store", "/v1/secret-stores", "secret_stores"),
],
version_get=("/v1", "barbican_versions"),
),
"manila": _simple_service_ops(
[
("share", "/v2/shares", "shares"),
("share_snapshot", "/v2/snapshots", "snapshots"),
("share_network", "/v2/share-networks", "share_networks"),
("share_type", "/v2/types", "share_types"),
("share_server", "/v2/share-servers", "share_servers"),
("security_service", "/v2/security-services", "security_services"),
("share_group", "/v2/share-groups", "share_groups"),
("share_replica", "/v2/share-replicas", "share_replicas"),
],
version_get=("/v2", "manila_versions"),
extras=[
{
"operation_id": "share_action",
"method": "POST",
"path": "/v2/shares/{id}/action",
"resource_type": "share",
"kind": "action",
"status_code": 202,
"action_name": "*",
}
],
),
"designate": _simple_service_ops(
[
("zone", "/v2/zones", "zones"),
("recordset", "/v2/zones/{zone_id}/recordsets", "recordsets"),
("tld", "/v2/tlds", "tlds"),
("blacklist", "/v2/blacklists", "blacklists"),
("pool", "/v2/pools", "pools"),
("service_status", "/v2/service_statuses", "service_statuses"),
],
version_get=("/v2", "designate_versions"),
),
"magnum": _simple_service_ops(
[
("cluster", "/v1/clusters", "clusters"),
("clustertemplate", "/v1/clustertemplates", "clustertemplates"),
("certificate", "/v1/certificates", "certificates"),
("nodegroup", "/v1/clusters/{cluster_id}/nodegroups", "nodegroups"),
],
version_get=("/v1", "magnum_versions"),
),
"zun": _simple_service_ops(
[
("container", "/v1/containers", "containers"),
("image", "/v1/images", "images"),
("capsule", "/v1/capsules", "capsules"),
("host", "/v1/hosts", "hosts"),
("service", "/v1/services", "services"),
],
version_get=("/v1", "zun_versions"),
extras=[
{
"operation_id": "container_action",
"method": "POST",
"path": "/v1/containers/{id}/start",
"resource_type": "container",
"kind": "action",
"status_code": 202,
},
{
"operation_id": "container_stop",
"method": "POST",
"path": "/v1/containers/{id}/stop",
"resource_type": "container",
"kind": "action",
"status_code": 202,
},
],
),
"trove": _simple_service_ops(
[
("instance", "/v1.0/instances", "instances"),
("datastore", "/v1.0/datastores", "datastores"),
("backup", "/v1.0/backups", "backups"),
("configuration", "/v1.0/configurations", "configurations"),
("cluster", "/v1.0/clusters", "clusters"),
],
version_get=("/v1.0", "trove_versions"),
),
"mistral": _simple_service_ops(
[
("workflow", "/v2/workflows", "workflows"),
("execution", "/v2/executions", "executions"),
("action", "/v2/actions", "actions"),
("workbook", "/v2/workbooks", "workbooks"),
("cron_trigger", "/v2/cron_triggers", "cron_triggers"),
("task", "/v2/tasks", "tasks"),
],
version_get=("/v2", "mistral_versions"),
),
"aodh": _simple_service_ops(
[
("alarm", "/v2/alarms", "alarms"),
("alarm_history", "/v2/alarms/{alarm_id}/history", "alarm_history"),
("quota", "/v2/quotas", "quotas"),
],
version_get=("/v2", "aodh_versions"),
),
"cloudkitty": _simple_service_ops(
[
("hashmap_service", "/v1/rating/module_config/hashmap/services", "services"),
("hashmap_field", "/v1/rating/module_config/hashmap/fields", "fields"),
("report_summary", "/v1/report/summary", "summary"),
("dataframes", "/v1/storage/dataframes", "dataframes"),
],
version_get=("/v1", "cloudkitty_versions"),
),
"freezer": _simple_service_ops(
[
("job", "/v2/jobs", "jobs"),
("client", "/v2/clients", "clients"),
("backup", "/v2/backups", "backups"),
("session", "/v2/sessions", "sessions"),
("action", "/v2/actions", "actions"),
],
version_get=("/v2", "freezer_versions"),
),
"blazar": _simple_service_ops(
[
("lease", "/leases", "leases"),
("host", "/os-hosts", "hosts"),
("floatingip", "/floatingips", "floatingips"),
],
version_get=("/v1", "blazar_versions"),
),
"vitrage": _simple_service_ops(
[
("topology", "/v1/topology", "topology"),
("alarm", "/v1/alarm", "alarms"),
("resource", "/v1/resources", "resources"),
("template", "/v1/template", "templates"),
("event", "/v1/event", "events"),
],
),
"masakari": _simple_service_ops(
[
("segment", "/v1/segments", "segments"),
("host", "/v1/segments/{segment_id}/hosts", "hosts"),
("notification", "/v1/notifications", "notifications"),
],
version_get=("/v1", "masakari_versions"),
),
"tacker": _simple_service_ops(
[
("vnf", "/v1.0/vnfs", "vnfs"),
("vnfd", "/v1.0/vnfds", "vnfds"),
("vim", "/v1.0/vims", "vims"),
("vnf_package", "/vnfpkgm/v1/vnf_packages", "vnf_packages"),
("vnf_instance", "/vnflcm/v1/vnf_instances", "vnf_instances"),
],
),
"adjutant": _simple_service_ops(
[
("task", "/v1/tasks", "tasks"),
("token", "/v1/tokens", "tokens"),
("notification", "/v1/notifications", "notifications"),
("status", "/v1/status", "status"),
],
),
# https://docs.openstack.org/2024.2/api/ — Infrastructure Optimization + Messaging
"watcher": _simple_service_ops(
[
("audit_template", "/v1/audit_templates", "audit_templates"),
("audit", "/v1/audits", "audits"),
("action_plan", "/v1/action_plans", "action_plans"),
("action", "/v1/actions", "actions"),
("goal", "/v1/goals", "goals"),
("strategy", "/v1/strategies", "strategies"),
("scoring_engine", "/v1/scoring_engines", "scoring_engines"),
("service", "/v1/services", "services"),
],
version_get=("/v1", "watcher_versions"),
),
"zaqar": _simple_service_ops(
[
("queue", "/v2/queues", "queues"),
("subscription", "/v2/queues/{queue_name}/subscriptions", "subscriptions"),
("claim", "/v2/queues/{queue_name}/claims", "claims"),
("message", "/v2/queues/{queue_name}/messages", "messages"),
],
version_get=("/v2", "zaqar_versions"),
extras=[
_get("/v2/health", "zaqar_health", "health", requires_project=False),
_get("/v2/ping", "zaqar_ping", "ping", requires_auth=False, requires_project=False),
],
),
}