Neutron/sharing-model-for-external-networks
当前逻辑
目前,“外部”网络的概念在某种程度上类似于“共享”网络的概念。然而,虽然每个租户都可以操作共享网络,但租户在外部网络上可以执行的操作集更加有限,目前仅限于在路由器上设置外部网关和创建浮动 IP。
尽管如此,“外部”意味着某种形式的共享,这会对可以实现的网络拓扑产生影响。例如,目前无法拥有仅供特定租户保留的外部网络。该外部网络始终会出现在其他租户执行的查询结果中。
目标
此蓝图的目标是找到一种解决方案,以限制外部网络的可见性范围,同时保持向后兼容性。如果找不到保留向后兼容性的合理解决方案,则此蓝图应推迟到下一个版本。
方案
最简单的解决方案似乎是将“外部”的概念与“共享”的概念解耦。外部将从拓扑角度限定网络,而“共享”将从访问权限角度限定网络。这样,我们今天所知的外部网络将是“外部且共享”的,而仅是外部的网络将仅对拥有它的租户可见,就像任何其他网络一样。
这在某种程度上是向后兼容的。确实,可以使用数据迁移为每个 external=True 的网络设置 shared=True,但响应会有所不同,因为现有外部网络的“shared”属性将从 False 更改为 True。
此外,为了保持向后兼容性,将网络设置为外部应该保持与现在相同的行为。这意味着网络必须同时是“共享”和“外部”。如果用户想要一个“私有”外部网络,他/她将不得不提交一个带有 shared=False, external=True 的请求(这有点奇怪)。同样,当取消设置“external”属性时,网络将恢复到“私有”状态。
然而,真正的问题在于考虑以下操作序列时
- POST /networks with shared=True --> shared = True, external=False
- PUT /networks with external=True --> shared=True, external=False
- PUT /networks external=False --> shared=False, external=False
在步骤 3 中网络的状态与步骤 1 不同,这是不可接受的。
此外,在这种情况下,与策略验证相关的也会出现一些复杂情况。[进一步讨论]
公共“外部”网络没有租户
为应该共享的外部网络设置 tenant_id=None。由于没有 tenant_id 的资源会导致 get_networks 不返回此网络,这将需要对 Neutron 的数据库层进行一些非平凡的更改。从授权角度来看,没有所有者的资源也可能存在问题。
不建议采用此方法。
额外属性
基本逻辑是:如果管理员创建外部网络,它将是共享的,除非他/她明确为另一个租户创建它,在这种情况下,它将仅对该租户私有。这可以通过 API 未公开的数据模型 API 实现。如果外部网络且 tenant_id 选择的 != context.tenant_id,则隐式设置数据库字段以使网络私有。
如果允许对外部网络的共享进行编程控制的理由充分,则此属性(我们可以称之为 private)也可以通过 API 公开。在这种情况下,我们将引入私有网络的概念。默认情况下,每个网络都是私有的。网络不能同时是私有的和共享的。但是,网络可以同时是私有的和外部的。
网络的 RBAC 控制
有一个 废弃的蓝图 来自 Kilo,提议针对网络的基于角色的访问控制。