Resource Limit Assignment
It is assumed that organization admins can see and manage AcceptedPlan
instances, but their tenants can only see them. Furthermore, parent
and child organization and other organization/final projects are separate
IAM scopes. Child entities also may reside in different primary regions
than their parent organization (or service). For these reasons, we have
resource type PlanAssignment
, which is even read-only, see its proto
definition. This allows admins to see the plan assigned for them, but
without any modifications, even if they are owners of their scope.
Because PlanAssignment is located in a region pointed by the
project/organization, we can guarantee synchronization with LimitPool/Limit
resources!
When AcceptedPlan is made, the Limits Controller is responsible for
creating PlanAssignment asynchronously, which may be in a different
region than source AcceptedPlan. The code for it is in
limits/controller/v1/limits_assigner/assigned_plans_copier.go
.
It creates an instance of PlanAssignment and sends a request to API
Server. The server implementation is in, naturally, file
limits/server/v1/plan_assignment/plan_assignment_service.go
. Note
that the controller is setting output-only fields, but it is fine, when
the server creates an instance, it will have these fields too. This
only ensures that, if there is any mismatch in the controller, it will
be forced to make another update.
When processing writes to PlanAssignment, the API Server grabs AcceptedPlan from the database, we require the child organization or project to be in a subset of regions available in parents. Therefore, we know at least a synced read-only copy of AcceptedPlan will be in the database. This is where we grab the desired configuration from.
PlanAssignment is synchronized with Limit and LimitPool instances, all of these belong to the same assignee, so we know our database owns these resources. Therefore, we can provide some guarantees based on SNAPSHOT: Configured limit values in Limit/LimitPool resources are guaranteed to match those in PlanAssignment, users don’t get any chance to make any mistake, and the system is not going to be out of sync here.
Note that we are only changing the configured limit, we have also so-called active limits. This is maintained by the controller. There is some chance configured limit is being set below current usage, if this happens, the active limit will stay on a higher value, as large as usage. This will affect the source limit pool reserved value, it will stay elevated! It is assumed however that PlanAssignment and configured limits must stay in sync with AcceptedPlan values, no matter if we are currently allocating/deallocating resources on the final API Server side.
Note that the limits controller tracks the active size and reserved value for LimitPool instances. Limits are on the next level.