增强型 Tacker 策略使用指南¶
概述¶
默认的 Tacker API 策略仅支持用户是否可以访问 API,但不确定用户是否可以访问 API 调用所操作的资源。
增强型 Tacker 策略使用户能够基于用户和 VNF 信息,对 API 资源进行更细粒度的访问控制。
本文档描述了如何在 Tacker 中使用增强型 Tacker 策略。
增强型 Tacker 属性介绍¶
增强型 Tacker 策略目前支持三种增强属性:区域 (area)、厂商 (vendor) 和租户 (tenant)。
区域 (area):区域属性是区域-区域对。此属性的值是格式为 “area@region” 的字符串。此属性描述了 VIM 或 VNF 所在的区域。
厂商 (vendor):厂商属性是厂商名称。它在 VNF 包的定义文件中定义。VNF 从 VNF 包获取此属性。
租户 (tenant):租户属性是租户名称。此属性描述了 CNF 的命名空间以及 VNF 的项目名称。
启用增强型 Tacker 策略¶
增强型 Tacker 策略默认在 Tacker 中禁用。要使其生效,用户需要在 tacker.conf 中找到 enhanced_tacker_policy 并将其值更改为 True。如果未找到,请自行添加。
$ vi /etc/tacker/tacker.conf
...
[oslo_policy]
enhanced_tacker_policy = True
...
配置增强型策略规则¶
oslo.policy 支持将 API 属性与对象属性进行比较的功能。基于此功能,增强型 Tacker 策略目前支持三种增强型 tacker 属性:区域、厂商和租户。
"get_vim" : "area:%(area)s"
"os_nfv_orchestration_api:vnf_packages:show" : "vendor:%(vendor)s"
"os_nfv_orchestration_api:vnf_instances:show" : "tenant:%(tenant)s"
以区域属性为例,冒号前的区域字符串是 API 属性,即 API 用户的区域。它与对象(在本例中为 VNF 实例)的区域进行比较。更确切地说,它与数据库中该对象的区域字段进行比较。如果两个值相等,则授予权限。
有关本使用指南中使用的策略规则配置,请参阅附录中的 示例 policy.yaml 文件 章节。
创建具有特殊角色的用户¶
用户需要定义具有以下命名规则的特殊角色,以表示对相应资源具有访问权限的用户。例如,具有 VENDOR_company-a 角色的用户有权访问其厂商属性为 company-a 的资源。这是因为在实现中,Tacker 会根据以下转换规则将特殊角色转换为用户属性进行属性比较。
特殊角色的命名规则¶
增强型 Tacker 策略为特殊角色定义了以下命名规则。管理员用户需要根据这些命名规则创建特殊角色,否则 Tacker 将无法正确地将这些特殊角色转换为用户属性。
角色名称由三部分组成:前缀 + “_” + [属性值/特殊值]
支持的前缀、属性值和特殊值如下表所示
前缀
属性值
特殊值
示例
AREA
区域值
VENDOR
厂商值
all
VENDOR_company_a, VENDOR_all
TENANT
租户值
all
TENANT_default, TENANT_all
注意
由于“all”被视为特殊值,因此资源的上述属性不能使用“all”作为属性值。如果资源属性错误地设置为“all”,则只有具有管理员角色或特殊角色的用户才能访问该资源,其他用户无法访问它。
转换规则¶
在 Tacker 实现中,Tacker 将这些特殊角色转换为 API 属性并将其提供给 Tacker 策略。转换遵循以下规则
对于普通属性值,它们将直接转换为用户属性值。
前缀
属性名称
示例(特殊角色 -> 用户属性值)
AREA
area
AREA_tokyo@japan -> {“area”: [”tokyo@japan”]}
VENDOR
供应商
VENDOR_company-a -> {“vendor”: [“company-a”]}
TENANT
tenant
TENANT_default -> {“tenant”: [“default”]}
对于增强型 Tacker 策略中的特殊值,资源的相应属性值将被分配给用户。
前缀
属性名称
特殊值
示例(资源属性 -> 用户属性)
AREA
area
{“area”: “tokyo@japan”} -> {“area”: [”tokyo@japan”]}
AREA
area
相同区域值
{"area": "tokyo@japan"} -> {"area": ["tokyo@japan"]}不同区域值
any -> {"area": []}VENDOR
供应商
all
{“vendor”: “vendor_company-a”} -> {“vendor”: [“company-a”]}
TENANT
tenant
all
{“tenant”: “default”} -> {“tenant”: [“default”]}
创建具有特殊角色的用户¶
在本用户指南中,用户使用管理员用户创建三个终端用户
user-a使用特殊角色作为实验组。user-b不使用特殊角色作为对照组。user-manager具有特殊角色和manager角色作为管理器。
创建用户¶
创建
user-a用户$ openstack user create --project nfv --password devstack user-a +---------------------+----------------------------------+ | Field | Value | +---------------------+----------------------------------+ | default_project_id | ebbc6cf1a03d49918c8e408535d87268 | | domain_id | default | | enabled | True | | id | e0c0212d3a21473da9a9828bb73000fe | | name | user-a | | options | {} | | password_expires_at | None | +---------------------+----------------------------------+
创建
user-b用户$ openstack user create --project nfv --password devstack user-b +---------------------+----------------------------------+ | Field | Value | +---------------------+----------------------------------+ | default_project_id | ebbc6cf1a03d49918c8e408535d87268 | | domain_id | default | | enabled | True | | id | d08df8befcfb4d0eb8acd3a88aa62641 | | name | user-b | | options | {} | | password_expires_at | None | +---------------------+----------------------------------+
创建
user-manager用户$ openstack user create --project nfv --password devstack user-manager +---------------------+----------------------------------+ | Field | Value | +---------------------+----------------------------------+ | default_project_id | ebbc6cf1a03d49918c8e408535d87268 | | domain_id | default | | enabled | True | | id | ccc5c486a6504918b776a2de8f34deb9 | | name | user-manager | | options | {} | | password_expires_at | None | +---------------------+----------------------------------+
创建角色¶
创建
AREA_tokyo@japan角色$ openstack role create AREA_tokyo@japan +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | None | | domain_id | None | | id | 81bd97ee20ef420482b34669cbffe9fd | | name | AREA_tokyo@japan | | options | {} | +-------------+----------------------------------+
创建
AREA_all@all角色$ openstack role create AREA_all@all +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | None | | domain_id | None | | id | 9cbb968d907a4dab8be1af081a9a15fa | | name | AREA_all@all | | options | {} | +-------------+----------------------------------+
创建
VENDOR_company-a角色$ openstack role create VENDOR_company-a +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | None | | domain_id | None | | id | b4fabd4bed784f60a8b07bd5f3a91a4a | | name | VENDOR_company-a | | options | {} | +-------------+----------------------------------+
创建
VENDOR_all角色$ openstack role create VENDOR_all +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | None | | domain_id | None | | id | aa9fe93854724cd7880d3974dd0e89ef | | name | VENDOR_all | | options | {} | +-------------+----------------------------------+
创建
TENANT_tenant-a角色$ openstack role create TENANT_tenant-a +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | None | | domain_id | None | | id | e6535546ea42472eb923300617532ad1 | | name | TENANT_tenant-a | | options | {} | +-------------+----------------------------------+
创建
TENANT_all角色$ openstack role create TENANT_all +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | None | | domain_id | None | | id | d420e279711d49fb8a2f211d816507ec | | name | TENANT_all | | options | {} | +-------------+----------------------------------+
创建
manager角色$ openstack role create manager +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | None | | domain_id | None | | id | d4bc947fca0f41368ade7173a9f0f9cb | | name | manager | | options | {} | +-------------+----------------------------------+
注意
在 2023.2 及更高版本中,manager 角色在 keystone 侧默认创建。如果它已经创建,则无需手动创建它。
将角色分配给用户-项目对¶
将
AREA_tokyo@japan、VENDOR_company-a和TENANT_tenant-a分配给user-a$ openstack role add --user user-a --project nfv AREA_tokyo@japan $ openstack role add --user user-a --project nfv VENDOR_company-a $ openstack role add --user user-a --project nfv TENANT_tenant-a
验证
user-a的角色分配$ openstack role assignment list --user user-a --project nfv --names +------------------+----------------+-------+-------------+--------+--------+-----------+ | Role | User | Group | Project | Domain | System | Inherited | +------------------+----------------+-------+-------------+--------+--------+-----------+ | VENDOR_company-a | user-a@Default | | nfv@Default | | | False | | AREA_tokyo@japan | user-a@Default | | nfv@Default | | | False | | TENANT_tenant-a | user-a@Default | | nfv@Default | | | False | +------------------+----------------+-------+-------------+--------+--------+-----------+
将 reader 分配给
user-b$ openstack role add --user user-b --project nfv reader
验证
user-b的角色分配$ openstack role assignment list --user user-b --project nfv --names +--------+----------------+-------+-------------+--------+--------+-----------+ | Role | User | Group | Project | Domain | System | Inherited | +--------+----------------+-------+-------------+--------+--------+-----------+ | reader | user-b@Default | | nfv@Default | | | False | +--------+----------------+-------+-------------+--------+--------+-----------+
将
AREA_all@all、VENDOR_all、TENANT_all和manager分配给user-manager$ openstack role add --user user-manager --project nfv AREA_all@all $ openstack role add --user user-manager --project nfv VENDOR_all $ openstack role add --user user-manager --project nfv TENANT_all $ openstack role add --user user-manager --project nfv manager
验证
user-manager的角色分配$ openstack role assignment list --user user-manager --project nfv --names +---------------+----------------------+-------+-------------+--------+--------+-----------+ | Role | User | Group | Project | Domain | System | Inherited | +---------------+----------------------+-------+-------------+--------+--------+-----------+ | VENDOR_all | user-manager@Default | | nfv@Default | | | False | | TENANT_all | user-manager@Default | | nfv@Default | | | False | | AREA_all@all | user-manager@Default | | nfv@Default | | | False | | manager | user-manager@Default | | nfv@Default | | | False | +---------------+----------------------+-------+-------------+--------+--------+-----------+
创建具有增强型 Tacker 属性的资源¶
本节描述了如何创建具有增强型 tacker 属性的资源,并提供示例。
使用区域属性注册 VIM¶
在注册 VIM 时,用户可以为 VIM 指定区域属性。这可以通过将区域属性放入 VIM 配置文件中的 extra 字段来实现。请参阅 VIM 管理,了解如何注册 VIM。VIM 配置文件的 project_name 用作实例化 VNF 的租户属性。
警告
强烈建议将执行 VIM 注册的用户与调用 VNF LCM API 的用户隔离。否则,用户可以通过覆盖来忽略区域属性。
使用区域属性
tokyo@japan注册 OpenStack VIM。OpenStack VIM 的示例
vim_config.yaml文件auth_url: 'http://192.168.56.10/identity/v3' username: 'vim-user' password: 'devstack' project_name: 'tenant-a' project_domain_name: 'default' user_domain_name: 'default' cert_verify: 'True' extra: area: tokyo@japan
注意
VIM 配置文件中指定的项目和 VIM 用户必须事先创建并分配成员角色给 VIM 用户。
$ openstack project create tenant-a --domain default $ openstack user create --project tenant-a --password devstack vim-user $ openstack role add --user vim-user --project tenant-a member
注册 OpenStack VIM
$ openstack vim register --config-file ./vim_config.yaml \ --description 'openstack vim in nfv' openstack-tokyo@japan +----------------+-----------------------------------------------------+ | Field | Value | +----------------+-----------------------------------------------------+ | auth_cred | { | | | "username": "vim-user", | | | "user_domain_name": "default", | | | "cert_verify": "True", | | | "project_id": null, | | | "project_name": "tenant-a", | | | "project_domain_name": "default", | | | "auth_url": "http://192.168.56.10/identity/v3", | | | "key_type": "barbican_key", | | | "secret_uuid": "***", | | | "password": "***" | | | } | | auth_url | http://192.168.56.10/identity/v3 | | created_at | 2023-12-12 06:49:16.994225 | | description | openstack vim in nfv | | extra | area=tokyo@japan | | id | b266493d-1782-4b4e-9c92-65b0946fe81c | | is_default | False | | name | openstack-tokyo@japan | | placement_attr | { | | | "regions": [ | | | "RegionOne" | | | ] | | | } | | project_id | ebbc6cf1a03d49918c8e408535d87268 | | status | ACTIVE | | type | openstack | | updated_at | None | | vim_project | { | | | "name": "tenant-a", | | | "project_domain_name": "default" | | | } | +----------------+-----------------------------------------------------+
使用区域属性
osaka@japan注册 OpenStack VIM。OpenStack VIM 的示例
vim_config.yaml文件auth_url: 'http://192.168.56.10/identity/v3' username: 'vim-user' password: 'devstack' project_name: 'tenant-a' project_domain_name: 'default' user_domain_name: 'default' cert_verify: 'True' extra: area: osaka@japan
注册 OpenStack VIM
$ openstack vim register --config-file ./vim_config.yaml \ --description 'openstack vim in nfv' openstack-osaka@japan +----------------+-----------------------------------------------------+ | Field | Value | +----------------+-----------------------------------------------------+ | auth_cred | { | | | "username": "vim-user", | | | "user_domain_name": "default", | | | "cert_verify": "True", | | | "project_id": null, | | | "project_name": "tenant-a", | | | "project_domain_name": "default", | | | "auth_url": "http://192.168.56.10/identity/v3", | | | "key_type": "barbican_key", | | | "secret_uuid": "***", | | | "password": "***" | | | } | | auth_url | http://192.168.56.10/identity/v3 | | created_at | 2023-12-12 06:55:57.154779 | | description | openstack vim in nfv | | extra | area=osaka@japan | | id | e0941ab7-dd35-4d08-80ea-1264c75050f4 | | is_default | False | | name | openstack-osaka@japan | | placement_attr | { | | | "regions": [ | | | "RegionOne" | | | ] | | | } | | project_id | ebbc6cf1a03d49918c8e408535d87268 | | status | ACTIVE | | type | openstack | | updated_at | None | | vim_project | { | | | "name": "tenant-a", | | | "project_domain_name": "default" | | | } | +----------------+-----------------------------------------------------+
使用区域属性
tokyo@japan注册 Kubernetes VIM。Kubernetes VIM 的示例
vim_config_k8s.yaml文件auth_url: "https://192.168.56.10:6443" bearer_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IkdVazBPakx4Q2NsUjJjNHhsZFdaaXJMSHVQMUo4NkdMS0toamlSaENiVFUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tazhzdmltIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJhNTIzYzFhMi1jYmU5LTQ1Y2YtYTc5YS00ZDA4MDYwZDE3NmEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpkZWZhdWx0In0.BpKAAQLjXMIpJIjqQDsGtyh1a-Ij8e-YOVRv0md_iOGXd1KLR-qreM6xA-Ni8WFILzq3phaZU6npET8PlfhQ6csF5u20OT2SoZ7iAotHXpCcYkRdrUd2oO5KxSFTkOhasaN1pQ3pZyaFYUZbwwmLK3I31rG4Br2VbZQ7Qu8wFOXUK-syBGF48vIPZ5JQ3K00KNxpuEcGybMK5LtdSKZ25Ozp_I2oqm3KBZMPMfWwaUnvuRnyly13tsiXudPt_9H78AxLubMo3rcvECJU2y_zZLiavcZKXAz-UmHulxtz_XZ80hMu-XOpYWEYrOB0Lt0hB59ZoY1y3OvJElTfPyrwWw" ssl_ca_cert: "-----BEGIN CERTIFICATE----- MIIDBTCCAe2gAwIBAgIIa76wZDxLNAowDQYJKoZIhvcNAQELBQAwFTETMBEGA1UE AxMKa3ViZXJuZXRlczAeFw0yMzExMDYwMDA3MzBaFw0zMzExMDMwMDEyMzBaMBUx EzARBgNVBAMTCmt1YmVybmV0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQDd0LBXGxVexr09mVFNSXWQq3TN66IIcXCBAMbIWI4EiQ8Y0zI4hSwADdK2 ltYSdWw7wq3/YTFHK8/YTY7Jvd9/k3UJrqkZ6kBtL20pJUPXNJVLE/hRzsqEnHHv cfqYZTHvTY4g7qNcMOcfl/oDUGUMfpQT2gs6xoNl0WX/1+QeQbadx1kWaD2Ii45F d8TR+c4wccxNaLArk3ok4h1PNeAwra4mRmBHQQ2wFjkTYGl4+ss3v1yoUJkrQjXL RgzLufeXaz8eRTi36HkjudGKfS3OnUeke3uBN7usW58FFJ8TdKOhuoguRm53kj6+ TwXtZCOPzn4gNxq6xJE1Xj2hwFfpAgMBAAGjWTBXMA4GA1UdDwEB/wQEAwICpDAP BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRdmQ4r63pXBHIO8ODqxROE7x+aizAV BgNVHREEDjAMggprdWJlcm5ldGVzMA0GCSqGSIb3DQEBCwUAA4IBAQBeQ/9+bzRe qbA02MfYnN3vycGhDObcAoiDIMIutojFTpx4hGZjqVgTRpLH5ReddwR4kkxn3NRg weCVkNkhzyGze64nb11qZG71olaOQRMYzyN2hYfmbq7MXSvmJQQYIr1OewaRk+xl TyG1XRXoD2IEaHEvG0+pQJlDerd5Z6S1fkPaKZtcRbM/E6y5VXMV6hegN4MwHZSI Ll1uEBTxUzzTm3dnl1KL8GDg05ajoYcyL3X/0aWsb/MFhtIlXe2CMxu5qUkLBhzy fCfX4cZpI5KFxMgdmAEoaGbNy7iqsGrLFtEmub2gdEBIVNr7vgOk4OeQ9Uodj6K7 jK97z+cupc5G -----END CERTIFICATE-----" project_name: "default" type: "kubernetes" extra: use_helm: true area: tokyo@japan
注册 Kubernetes VIM
$ openstack vim register --config-file ./vim_k8s_config.yaml \ --description 'kubernetes vim in nfv' \ kubernetes-tokyo@japan --fit-width +----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Field | Value | +----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | auth_cred | { | | | "bearer_token": "***", | | | "ssl_ca_cert": "b'gAAAAABleAUrM8oGbXIoXuHIe3WXU0AXqqe0UdOD9hPECuKMum_7dZwjMx_Xtd6pVMIKXoraXr_x-n1P6wPahwz2V7zt5Mpiy3guplnlfb8qwyUT51yS3JkgEvykXRIwIWvJKBFr2LKU4qGBqmyml8C-ZM7qFN_U9ctyzw53dw0c1Sq7ma19gsUM2Ehbfylz3B4zV_t2aY- | | | 0a7sA8FBwM_mkmOeL2DjOmHn39TAUeT59zshJSGaKafvGdUb2YOdXp4k6vVB4UR09GmIOlRuFAPfM5_0EhFPQ9Ys1jn-1Q4KCBWXt68yHOoUaepe_zEmLfCn0lAAXdYAjALnymZ8q4xpLI1oY8NsPAM7inMo9NGSGW6Gtb1JegMcYL5-xGjKUfHMKOF5gcndKMNSvkcCEMVcJ6bvheE6eFluFA5QQLLshl- | | | wYU7eSlM9mapGzlwuCv5QLafuvttiOSn0tgDf3PFuMF9K1BN1Pao-2_A6QwmLqEOwoShUJbD8d7J3ZZykTaBgNOVQSK6IzQKxGZ0ajSqZhPPFrbSYMuTmXCcmGz-G71tPcupSohsf9DNmIVrb8Ylwz50oHr4mB_hrN1LxuUOh-27nawPFwhdeF0_ebqJesjWbYQea6M2JLcHcZs8lrk6w7f4PZN8FFdGa- | | | s_oOCdxHtM4A4ZQQEDi9IpPc-ekXtxqax5T_8Fve8kBneixYguc9oFffHF195L-0aAJwoo2d5TOYuU2-fhxfGwsfcThGcHpNL3M-giGPGveqgUpc-YoW2HmXtyE0dent_Xc8HFklBfKVNIs2ckP8zgBqx_4h0U09WCsLNKvghXtJy27j0lzo5u5QnIzb7xJjaBcZAAoSsmJvbWlDmcMNENHXKmrzv0qz5uHJ05PBU | | | L7xInxSOfqEPjRK5FccBzpZ9FgWlALvnW7E37PmWrPJyx1g0-rAsOXthFad9Pz3CLQExbly5Z4lQkdqh4YgCbnERL0052_EAILsf9ou-67CHYLcAosZvnU5T2tBTYYUxJWujoJD95OrG9fj-XY7rkAElUe5bIfFj2yf7Kp8jKjaTeXDFZIu5dA9Qk5LPqfxhxSEbL83pmjbuXydO7dXBzmqsameJ0Ju0CmUvsn1rg | | | QjCW899ckRIZH8IvsJM_kVpGoS9m8hnoJwilhuvvAMNQiZqb8qgwb4ooYRryxFOO-6xOaT3joYWryVpeYp9Enmu1LlRPOaV1_Te4f84JK5PYdyJ03- | | | KchdiylzSQQsWqs285ZxCssjr_FmSfAs0bf8YnBfbhLmYxgCpopyTuqbPTZf2yqZAlzyhEZf02lzFeJQTETjNyG4HUkQV1yEagoUWbxeozSPaJpatm3D3Bf1Sr-Q_8TspgXZYy9Wws1Ig3aCzs1AW7EczwJFnlBrYlNr1WoTWgk87_ElfyLxuuXfn3Ks- | | | BVzHnciBWjOwmP0CTCJB1MBpARxuqms0KyrxXKJvQbfW9VmQ4kvbrHW227g_SEen1WVfrp27hmJ4wk9WwzrnVGfg8STKHvKW-AoNdpRvuXD07Hjzl1bQaZ0Oee6ngmkPQgCF4N1Sx1vidX-Hg=='", | | | "auth_url": "https://192.168.56.10:6443", | | | "username": "None", | | | "key_type": "barbican_key", | | | "secret_uuid": "***" | | | } | | auth_url | https://192.168.56.10:6443 | | created_at | 2023-12-12 07:00:59.413587 | | description | kubernetes vim in nfv | | extra | area=tokyo@japan, use_helm=True | | id | e5f9e74b-7c58-4316-8523-3617a704d5dc | | is_default | False | | name | kubernetes-tokyo@japan | | placement_attr | { | | | "regions": [ | | | "default", | | | "kube-node-lease", | | | "kube-public", | | | "kube-system" | | | ] | | | } | | project_id | ebbc6cf1a03d49918c8e408535d87268 | | status | ACTIVE | | type | kubernetes | | updated_at | None | | vim_project | { | | | "name": "default" | | | } | +----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
使用厂商属性创建 VNF 包¶
VNF 包资源的厂商属性来自 VNF 包的 Definitions/vnfd_top.yaml 中定义的 provider 字段。要使用指定的厂商属性创建 VNF 包,用户需要修改 provider 属性为厂商。请参阅 VNF 包,了解如何制作 zip 文件和创建 VNF 包。本章节仅提供 VNF 包中需要修改的配置文件的示例。
将
Definitions/vnfd_top.yaml中的 provider 设置为company-a。tosca_definitions_version: tosca_simple_yaml_1_2 description: Sample VNF imports: - etsi_nfv_sol001_common_types.yaml - etsi_nfv_sol001_vnfd_types.yaml - sample_vnfd_types.yaml - sample_vnfd_df_simple.yaml topology_template: inputs: selected_flavour: type: string description: VNF deployment flavour selected by the consumer. It is provided in the API node_templates: VNF: type: company.provider.VNF properties: flavour_id: { get_input: selected_flavour } descriptor_id: c1bb0ce7-ebca-4fa7-95ed-4840d70a1175 provider: company-a product_name: Sample VNF software_version: "1.0" descriptor_version: "1.0" vnfm_info: - Tacker requirements: #- virtual_link_external # mapped in lower-level templates #- virtual_link_internal # mapped in lower-level templates
将
Definitions/vnfd_types.yaml中的 provider 设置为company-a。tosca_definitions_version: tosca_simple_yaml_1_2 description: VNF type definition imports: - etsi_nfv_sol001_common_types.yaml - etsi_nfv_sol001_vnfd_types.yaml node_types: company.provider.VNF: derived_from: tosca.nodes.nfv.VNF properties: ... provider: type: string constraints: [valid_values: ["company-a"]] default: "company-a" ...
创建和实例化具有厂商、区域和租户属性的 VNF¶
使用厂商属性创建 VNF¶
VNF 的厂商属性来自 VNF 包的 provider 属性。因此,用户只需要使用具有指定 provider 属性的 VNF 包来创建具有指定厂商属性的 VNF。
以下是使用指定厂商属性创建 VNF 的示例。
使用 vnfd_id 创建 VNF
$ openstack vnflcm create <vnfd_id>
在具有区域和租户属性的 VIM 上实例化 VNF¶
VNF 的区域和租户属性来自使用的 VIM。换句话说,您需要指定要在其中实例化 VNF 的区域和租户的 VIM。
对于 VNF LCM API 版本 1,请参阅 使用 v1 Tacker 进行 VNF 生命周期管理 以实例化 VNF。以下是 <param-file> 的两个示例。
如果 <param-file> 包含
vimConnectionInfo参数,则区域和租户属性来自其中的 vim。{ "flavourId": "simple", "vimConnectionInfo": [ { "id": "e24f9796-a8e9-4cb0-85ce-5920dcddafa1", "vimId": "9f2bac4c-2d17-4269-8164-93d4e875f101", "vimType": "ETSINFV.OPENSTACK_KEYSTONE.V_2" } ] }
如果 <param-file> 不包含
vimConnectionInfo参数,则使用默认 VIM,并且区域和租户属性来自默认 VIM。{ "flavourId": "simple" }
对于 VNF LCM API 版本 2,请参阅 使用 v2 Tacker 进行 VNF 生命周期管理 以实例化 VNF。以下是 <param-file> 的两个示例。
如果 <param-file> 的
vimConnectionInfo参数中的 vim 是 DB 中的现有 vim,则实例化 VNF 的区域和租户属性来自此 vim。{ "flavourId": "simple", "vimConnectionInfo": { "vim1": { "id": "725f625e-f6b7-4bcd-b1b7-7184039fde45" "vimId": "9f2bac4c-2d17-4269-8164-93d4e875f101", "vimType": "ETSINFV.OPENSTACK_KEYSTONE.V_3" } } }
如果 <param-file> 的
vimConnectionInfo参数中的 vim 不存在于 DB 中,则用户需要在vimConnectionInfo参数中指定区域和租户属性。租户属性使用accessInfo中的project。{ "flavourId": "simple", "vimConnectionInfo": { "vim1": { "accessInfo": { "password": "devstack", "project": "tenant-a", "projectDomain": "Default", "region": "RegionOne", "userDomain": "Default", "username": "vim-user" }, "interfaceInfo": { "endpoint": "https:///identity/v3" }, "vimId": "03e608b2-e7d4-44fa-bd84-74fb24be3ed5", "vimType": "ETSINFV.OPENSTACK_KEYSTONE.V_3", "extra": {"area": "tokyo@japan"} } } }
使用租户属性实例化 CNF¶
在实例化 CNF 时,CNF 的租户属性由 <param-file> 的 additionalParams 字段中的命名空间指定。
{
"flavourId": "simple",
"vimConnectionInfo": [
{
"id": "b1bb0ce7-ebca-4fa7-95ed-4840d70a1177",
"vimId": "43a2c212-8a6b-468f-a51f-c912fdd722fe",
"vimType": "kubernetes"
}
],
"additionalParams": {
"lcm-kubernetes-def-files": [
"Files/kubernetes/deployment.yaml",
"Files/kubernetes/namespace.yaml"
],
"namespace": "tenant-a"
}
}
支持增强型 Tacker 策略的 API 的使用¶
本节以 VIM 管理 API 为例,介绍支持增强型 Tacker 策略的 API 调用。您可以在 支持增强型 Tacker 策略的 Tacker API 中找到支持增强型 Tacker 策略的 API 列表以及每个 API 支持的增强型 tacker 属性。
获取单个资源¶
具有特殊角色的用户有权访问相应的资源。例如,具有 user-a 角色 AREA_tokyo@japan 的用户有权访问区域属性为 tokyo@japan 的 VIM。不具有 AREA_tokyo@japan 角色的 user-b 用户无权访问区域属性为 tokyo@japan 的 VIM。这里以显示 VIM 为例。
user-a 显示区域属性为 tokyo@japan 的 VIM,并且成功。
$ openstack vim show 9f2bac4c-2d17-4269-8164-93d4e875f101
+----------------+-----------------------------------------------------+
| Field | Value |
+----------------+-----------------------------------------------------+
| auth_cred | { |
| | "username": "vim-user", |
| | "user_domain_name": "default", |
| | "cert_verify": "True", |
| | "project_id": null, |
| | "project_name": "tenant-a", |
| | "project_domain_name": "default", |
| | "auth_url": "http://192.168.56.10/identity/v3", |
| | "key_type": "barbican_key", |
| | "secret_uuid": "***", |
| | "password": "***" |
| | } |
| auth_url | http://192.168.56.10/identity/v3 |
| created_at | 2024-01-05 02:10:30 |
| description | openstack vim in nfv |
| extra | area=tokyo@japan |
| id | 9f2bac4c-2d17-4269-8164-93d4e875f101 |
| is_default | True |
| name | openstack-tokyo@japan |
| placement_attr | { |
| | "regions": [ |
| | "RegionOne" |
| | ] |
| | } |
| project_id | 711fcdc235bf4095bb83fe368a4f95a6 |
| status | ACTIVE |
| type | openstack |
| updated_at | 2024-01-05 03:11:24 |
| vim_project | { |
| | "name": "tenant-a", |
| | "project_domain_name": "default" |
| | } |
+----------------+-----------------------------------------------------+
user-b 显示区域属性为 tokyo@japan 的 VIM,并且失败。
$ openstack vim show 9f2bac4c-2d17-4269-8164-93d4e875f101
Unable to find vim with name '9f2bac4c-2d17-4269-8164-93d4e875f101'
用户可以使用 manager 角色来区分参考 API 和操作 API。这是 oslo.policy 的现有功能,这里只是一个建议的使用场景。
user-a 没有 manager 角色,因此无法删除 VIM。
$ openstack vim delete 9f2bac4c-2d17-4269-8164-93d4e875f101
Unable to delete the below vim(s):
Cannot delete 9f2bac4c-2d17-4269-8164-93d4e875f101: Unable to find vim with name '9f2bac4c-2d17-4269-8164-93d4e875f101'
user-manager 具有 manager 角色,可以删除 VIM。
$ openstack vim delete 9f2bac4c-2d17-4269-8164-93d4e875f101
All specified vim(s) deleted successfully
注意
请注意,目前,“openstack vim show/set/delete”命令由于以下错误而无法正常工作。
下面的 API 本身工作正常。
GET /v1.0/vims/{vim_id}
PUT /v1.0/vims/{vim_id}
Delete /v1.0/vims/{vim_id}
列出资源¶
对于列出资源的 API,增强的 Tacker Policy 充当过滤器。也就是说,列表操作仅列出用户具有权限的资源。这里以列出 VIM 为例。
user-a 仅有权访问区域属性为 tokyo@japan 的 VIM。因此,user-a 只能列出区域属性为 tokyo@japan 的 VIM。
$ openstack vim list
+--------------------------------------+------------------------+----------------------------------+------------+------------+--------+
| ID | Name | Tenant_id | Type | Is Default | Status |
+--------------------------------------+------------------------+----------------------------------+------------+------------+--------+
| 43a2c212-8a6b-468f-a51f-c912fdd722fe | kubernetes-tokyo@japan | 711fcdc235bf4095bb83fe368a4f95a6 | kubernetes | False | ACTIVE |
| 9f2bac4c-2d17-4269-8164-93d4e875f101 | openstack-tokyo@japan | 711fcdc235bf4095bb83fe368a4f95a6 | openstack | False | ACTIVE |
+--------------------------------------+------------------------+----------------------------------+------------+------------+--------+
user-b 没有访问任何具有该区域属性的 VIM 的权限,因此在执行列出 VIM 操作时,列表为空。
$ openstack vim list
(No output.)
user-manager 有权访问所有资源。它可以列出所有资源。
$ openstack vim list
+--------------------------------------+------------------------+----------------------------------+------------+------------+--------+
| ID | Name | Tenant_id | Type | Is Default | Status |
+--------------------------------------+------------------------+----------------------------------+------------+------------+--------+
| 43a2c212-8a6b-468f-a51f-c912fdd722fe | kubernetes-tokyo@japan | 711fcdc235bf4095bb83fe368a4f95a6 | kubernetes | False | ACTIVE |
| 9f2bac4c-2d17-4269-8164-93d4e875f101 | openstack-tokyo@japan | 711fcdc235bf4095bb83fe368a4f95a6 | openstack | False | ACTIVE |
| c100874d-26f6-4b34-b0eb-55bfaba926aa | openstack-osaka@japan | 711fcdc235bf4095bb83fe368a4f95a6 | openstack | False | ACTIVE |
+--------------------------------------+------------------------+----------------------------------+------------+------------+--------+
限制¶
由于在 Tacker 的早期版本中创建的资源可能没有增强的策略属性,如果策略规则将增强的策略属性用作比较属性,则此规则将阻止用户访问缺少这些属性的资源,因为比较结果始终为 false。
附录¶
支持增强 Tacker Policy 的 Tacker API¶
下表列出了支持增强 Tacker Policy 的 API,以及每个 API 支持的增强 tacker 属性。
操作 |
API |
支持区域 |
支持厂商 |
支持租户 |
|---|---|---|---|---|
VIM-List |
GET /v1.0/vims |
是 |
否 |
否 |
VIM-Show |
GET /v1.0/vims/{vim_id} |
是 |
否 |
否 |
VIM-Update |
PUT /v1.0/vims/{vim_id} |
是 |
否 |
否 |
VIM-Delete |
Delete /v1.0/vims/{vim_id} |
是 |
否 |
否 |
PKG-List |
GET /vnfpkgm/v1/vnf_packages |
否 |
是(1) |
否 |
PKG-Show |
GET /vnfpkgm/v1/vnf_packages/{vnfPkgId} |
否 |
是(1) |
否 |
PKG-Update |
PATCH /vnfpkgm/v1/vnf_packages/{vnfPkgId} |
否 |
是 |
否 |
PKG-Delete |
DELETE /vnfpkgm/v1/vnf_packages/{vnfPkgId} |
否 |
是 |
否 |
PKG-Read-vnfd |
GET /vnfpkgm/v1/vnf_packages/{vnfPkgId}/vnfd |
否 |
是 |
否 |
PKG-Fetch |
GET /vnfpkgm/v1/vnf_packages/{vnfPkgId}/package_content |
否 |
是 |
否 |
PKG-Upload-content |
PUT /vnfpkgm/v1/vnf_packages/{vnfPkgId}/package_content |
否 |
是 |
否 |
PKG-Artifacts |
GET /vnfpkgm/v1/vnf_packages/{vnfPkgId}/artifacts/{artifactPath} |
否 |
是 |
否 |
LCM-List |
GET /vnflcm/v1/vnf_instances |
是(2) |
是 |
是(3) |
LCM-Create |
POST /vnflcm/v1/vnf_instances |
否 |
是 |
否 |
LCM-Show |
GET /vnflcm/v1/vnf_instances/{vnfInstanceId} |
是(2) |
是 |
是(3) |
LCM-Update |
PATCH /vnflcm/v1/vnf_instances/{vnfInstanceId} |
是 |
是 |
是 |
LCM-Delete |
DELETE /vnflcm/v1/vnf_instances/{vnfInstanceId} |
否 |
是 |
否 |
LCM-Instantiate |
POST /vnflcm/v1/vnf_instances/{vnfInstanceId}/instantiate |
否 |
是 |
否 |
LCM-Scale |
POST /vnflcm/v1/vnf_instances/{vnfInstanceId}/scale |
是 |
是 |
是 |
LCM-Terminate |
POST /vnflcm/v1/vnf_instances/{vnfInstanceId}/terminate |
是 |
是 |
是 |
LCM-Heal |
POST /vnflcm/v1/vnf_instances/{vnfInstanceId}/heal |
是 |
是 |
是 |
LCM-Change-Connectivity |
POST /vnflcm/v1/vnf_instances/{vnfInstanceId}/change_ext_conn |
是 |
是 |
是 |
LCM-ListV2 |
GET /vnflcm/v2/vnf_instances |
是(3) |
是 |
是(3) |
LCM-CreateV2 |
POST /vnflcm/v2/vnf_instances |
否 |
是 |
否 |
LCM-ShowV2 |
GET /vnflcm/v2/vnf_instances/{vnfInstanceId} |
是(3) |
是 |
是(3) |
LCM-UpdateV2 |
PATCH /vnflcm/v2/vnf_instances/{vnfInstanceId} |
是 |
是 |
是 |
LCM-DeleteV2 |
DELETE /vnflcm/v2/vnf_instances/{vnfInstanceId} |
否 |
是 |
否 |
LCM-InstantiateV2 |
POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/instantiate |
否 |
是 |
否 |
LCM-ScaleV2 |
POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/scale |
是 |
是 |
是 |
LCM-TerminateV2 |
POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/terminate |
是 |
是 |
是 |
LCM-HealV2 |
POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/heal |
是 |
是 |
是 |
LCM-Change-ConnectivityV2 |
POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/change_ext_conn |
是 |
是 |
是 |
LCM-Change-VnfPkgV2 |
POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/change_vnfpkg |
是 |
是 |
是 |
当状态不是ONBOARDED时,此项将被忽略。
当状态为NOT_INSTANTIATED时,使用默认 VIM。
当状态为NOT_INSTANTIATED时,此项将被忽略。
示例 policy.yaml 文件¶
# Decides what is required for the 'is_admin:True' check to succeed.
"context_is_admin": "role:admin"
# Default rule for most non-Admin APIs.
"admin_or_owner": "is_admin:True or project_id:%(project_id)s"
# Default rule for most Admin APIs.
"admin_only": "is_admin:True"
# Default rule for sharing vims.
"shared": "field:vims:shared=True"
# Default rule for most non-Admin APIs.
"default": "rule:admin_or_owner"
# For manager
"manager_and_owner": "role:manager and project_id:%(project_id)s"
# For user
"owner": "project_id:%(project_id)s"
# VIM resource attributes compare rule.
"vim_attrs_cmp": "area:%(area)s"
# Register a VIM.
# Post /v1.0/vims
"create_vim": "rule:manager_and_owner or role:admin"
# List VIMs or show a VIM.
# GET /v1.0/vims
# GET /v1.0/vims/{vim_id}
"get_vim": "rule:vim_attrs_cmp or role:admin"
# Update a VIM.
# PUT /v1.0/vims/{vim_id}
"update_vim": "rule:vim_attrs_cmp and rule:manager_and_owner or role:admin"
# Delete a VIM.
# DELETE /v1.0/vims/{vim_id}
"delete_vim": "rule:vim_attrs_cmp and rule:manager_and_owner or role:admin"
# vnf_packages resource attributes compare rule.
"vnf_pkg_attrs_cmp": "vendor:%(vendor)s"
# Creates a VNF package.
# POST /vnf_packages
"os_nfv_orchestration_api:vnf_packages:create": "rule:admin_or_owner"
# Show a VNF package.
# GET /vnf_packages/{vnf_package_id}
"os_nfv_orchestration_api:vnf_packages:show": "rule:vnf_pkg_attrs_cmp and rule:owner or role:admin"
# List all VNF packages.
# GET /vnf_packages/
"os_nfv_orchestration_api:vnf_packages:index": "rule:vnf_pkg_attrs_cmp and rule:owner or role:admin"
# Delete a VNF package.
# DELETE /vnf_packages/{vnf_package_id}
"os_nfv_orchestration_api:vnf_packages:delete": "rule:vnf_pkg_attrs_cmp and rule:manager_and_owner or role:admin"
# Fetch the contents of an on-boarded VNF Package.
# GET /vnf_packages/{vnf_package_id}/package_content
"os_nfv_orchestration_api:vnf_packages:fetch_package_content": "rule:vnf_pkg_attrs_cmp and rule:owner or role:admin"
# Upload a VNF package content.
# PUT /vnf_packages/{vnf_package_id}/package_content
"os_nfv_orchestration_api:vnf_packages:upload_package_content": "rule:vnf_pkg_attrs_cmp or role:admin"
# Upload a VNF package content from URI.
# POST /vnf_packages/{vnf_package_id}/package_content/upload_from_uri
"os_nfv_orchestration_api:vnf_packages:upload_from_uri": "rule:admin_or_owner"
# Update information of VNF package.
# PATCH /vnf_packages/{vnf_package_id}
"os_nfv_orchestration_api:vnf_packages:patch": "rule:vnf_pkg_attrs_cmp and rule:manager_and_owner or role:admin"
# Read the content of the VNFD within a VNF package.
# GET /vnf_packages/{vnf_package_id}/vnfd
"os_nfv_orchestration_api:vnf_packages:get_vnf_package_vnfd": "rule:vnf_pkg_attrs_cmp and rule:owner or role:admin"
# Read the content of the artifact within a VNF package.
# GET /vnf_packages/{vnfPkgId}/artifacts/{artifactPath}
"os_nfv_orchestration_api:vnf_packages:fetch_artifact": "rule:vnf_pkg_attrs_cmp and rule:owner or role:admin"
# vnflcm create attributes compare rule.
"vnflcm_create_attrs_cmp": "vendor:%(vendor)s"
# vnflcm instantiate attributes compare rule.
"vnflcm_inst_attrs_cmp": "vendor:%(vendor)s"
# vnflcm delete attributes compare rule.
"vnflcm_delete_attrs_cmp": "vendor:%(vendor)s"
# vnflcm resource attributes compare rule.
"vnflcm_attrs_cmp": "area:%(area)s and vendor:%(vendor)s and tenant:%(tenant)s"
# Get API Versions.
# GET /vnflcm/v1/api_versions
"os_nfv_orchestration_api:vnf_instances:api_versions": "@"
# Create VNF instance.
# POST /vnflcm/v1/vnf_instances
"os_nfv_orchestration_api:vnf_instances:create": "rule:vnflcm_create_attrs_cmp and rule:manager_and_owner or role:admin"
# Instantiate VNF instance.
# POST /vnflcm/v1/vnf_instances/{vnfInstanceId}/instantiate
"os_nfv_orchestration_api:vnf_instances:instantiate": "rule:vnflcm_inst_attrs_cmp and rule:manager_and_owner or role:admin"
# Query an Individual VNF instance.
# GET /vnflcm/v1/vnf_instances/{vnfInstanceId}
"os_nfv_orchestration_api:vnf_instances:show": "rule:vnflcm_attrs_cmp and rule:owner or role:admin"
# Terminate a VNF instance.
# POST /vnflcm/v1/vnf_instances/{vnfInstanceId}/terminate
"os_nfv_orchestration_api:vnf_instances:terminate": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Heal a VNF instance.
# POST /vnflcm/v1/vnf_instances/{vnfInstanceId}/heal
"os_nfv_orchestration_api:vnf_instances:heal": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Scale a VNF instance.
# POST /vnflcm/v1/vnf_instances/{vnfInstanceId}/scale
"os_nfv_orchestration_api:vnf_instances:scale": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Query an Individual VNF LCM operation occurrence.
# GET /vnflcm/v1/vnf_lcm_op_occs/{vnfLcmOpOccId}
"os_nfv_orchestration_api:vnf_instances:show_lcm_op_occs": "rule:admin_or_owner"
# Query VNF LCM operation occurrence.
# GET /vnflcm/v1/vnf_lcm_op_occs
"os_nfv_orchestration_api:vnf_instances:list_lcm_op_occs": "rule:admin_or_owner"
# Query VNF instances.
# GET /vnflcm/v1/vnf_instances
"os_nfv_orchestration_api:vnf_instances:index": "rule:vnflcm_attrs_cmp and rule:owner or role:admin"
# Delete an Individual VNF instance.
# DELETE /vnflcm/v1/vnf_instances/{vnfInstanceId}
"os_nfv_orchestration_api:vnf_instances:delete": "rule:vnflcm_delete_attrs_cmp and rule:manager_and_owner or role:admin"
# Update an Individual VNF instance.
# PATCH /vnflcm/v1/vnf_instances/{vnfInstanceId}
"os_nfv_orchestration_api:vnf_instances:update_vnf": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Rollback a VNF instance.
# POST /vnflcm/v1/vnf_lcm_op_occs/{vnfLcmOpOccId}/rollback
"os_nfv_orchestration_api:vnf_instances:rollback": "rule:admin_or_owner"
# Cancel a VNF instance.
# POST /vnflcm/v1/vnf_lcm_op_occs/{vnfLcmOpOccId}/cancel
"os_nfv_orchestration_api:vnf_instances:cancel": "rule:admin_or_owner"
# Fail a VNF instance.
# POST /vnflcm/v1/vnf_lcm_op_occs/{vnfLcmOpOccId}/fail
"os_nfv_orchestration_api:vnf_instances:fail": "rule:admin_or_owner"
# Retry a VNF instance.
# POST /vnflcm/v1/vnf_lcm_op_occs/{vnfLcmOpOccId}/retry
"os_nfv_orchestration_api:vnf_instances:retry": "rule:admin_or_owner"
# Change external VNF connectivity.
# POST /vnflcm/v1/vnf_instances/{vnfInstanceId}/change_ext_conn
"os_nfv_orchestration_api:vnf_instances:change_ext_conn": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Get API Versions.
# GET /vnflcm/v2/api_versions
"os_nfv_orchestration_api_v2:vnf_instances:api_versions": "@"
# Creates VNF instance.
# POST /vnflcm/v2/vnf_instances
"os_nfv_orchestration_api_v2:vnf_instances:create": "rule:vnflcm_create_attrs_cmp and rule:manager_and_owner or role:admin"
# Query VNF instances.
# GET /vnflcm/v2/vnf_instances
"os_nfv_orchestration_api_v2:vnf_instances:index": "rule:vnflcm_attrs_cmp and rule:owner or role:admin"
# Query an Individual VNF instance.
# GET /vnflcm/v2/vnf_instances/{vnfInstanceId}
"os_nfv_orchestration_api_v2:vnf_instances:show": "rule:vnflcm_attrs_cmp and rule:owner or role:admin"
# Delete an Individual VNF instance.
# DELETE /vnflcm/v2/vnf_instances/{vnfInstanceId}
"os_nfv_orchestration_api_v2:vnf_instances:delete": "rule:vnflcm_delete_attrs_cmp and rule:manager_and_owner or role:admin"
# Modify VNF instance information.
# PATCH /vnflcm/v2/vnf_instances/{vnfInstanceId}
"os_nfv_orchestration_api_v2:vnf_instances:update": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Instantiate VNF instance.
# POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/instantiate
"os_nfv_orchestration_api_v2:vnf_instances:instantiate": "rule:vnflcm_inst_attrs_cmp and rule:manager_and_owner or role:admin"
# Terminate VNF instance.
# POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/terminate
"os_nfv_orchestration_api_v2:vnf_instances:terminate": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Scale VNF instance.
# POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/scale
"os_nfv_orchestration_api_v2:vnf_instances:scale": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Heal VNF instance.
# POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/heal
"os_nfv_orchestration_api_v2:vnf_instances:heal": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Change external VNF connectivity.
# POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/change_ext_conn
"os_nfv_orchestration_api_v2:vnf_instances:change_ext_conn": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Change VNF package.
# POST /vnflcm/v2/vnf_instances/{vnfInstanceId}/change_vnfpkg
"os_nfv_orchestration_api_v2:vnf_instances:change_vnfpkg": "rule:vnflcm_attrs_cmp and rule:manager_and_owner or role:admin"
# Create subscription.
# POST /vnflcm/v2/subscriptions
"os_nfv_orchestration_api_v2:vnf_instances:subscription_create": "@"
# List subscription.
# GET /vnflcm/v2/subscriptions
"os_nfv_orchestration_api_v2:vnf_instances:subscription_list": "@"
# Show subscription.
# GET /vnflcm/v2/vnf_instances/{subscriptionId}
"os_nfv_orchestration_api_v2:vnf_instances:subscription_show": "@"
# Delete subscription.
# DELETE /vnflcm/v2/vnf_instances/{subscriptionId}
"os_nfv_orchestration_api_v2:vnf_instances:subscription_delete": "@"
# List VnfLcmOpOcc.
# GET /vnflcm/v2/vnf_lcm_op_occs
"os_nfv_orchestration_api_v2:vnf_instances:lcm_op_occ_list": "@"
# Show VnfLcmOpOcc.
# GET /vnflcm/v2/vnf_lcm_op_occs/{vnfLcmOpOccId}
"os_nfv_orchestration_api_v2:vnf_instances:lcm_op_occ_show": "@"
# Retry VnfLcmOpOcc.
# POST /vnflcm/v2/vnf_lcm_op_occs/{vnfLcmOpOccId}/retry
"os_nfv_orchestration_api_v2:vnf_instances:lcm_op_occ_retry": "@"
# Rollback VnfLcmOpOcc.
# POST /vnflcm/v2/vnf_lcm_op_occs/{vnfLcmOpOccId}/rollback
"os_nfv_orchestration_api_v2:vnf_instances:lcm_op_occ_rollback": "@"
# Fail VnfLcmOpOcc.
# POST /vnflcm/v2/vnf_lcm_op_occs/{vnfLcmOpOccId}/fail
"os_nfv_orchestration_api_v2:vnf_instances:lcm_op_occ_fail": "@"
# Delete VnfLcmOpOcc.
# DELETE /vnflcm/v2/vnf_lcm_op_occs/{vnfLcmOpOccId}
"os_nfv_orchestration_api_v2:vnf_instances:lcm_op_occ_delete": "@"