Referencing GCP objects should define a API field spec.<Kind>Ref(s)
to reference the dependency of another GCP resource.
If a Config Connector resource depends on another resource, it should define a spec.<Kind>Ref
field, even if the dependent does not have a Config Connector resource yet (in which case only External is required).
If a Config Connector resource needs to depend on a list of resources of a single Kind, it should define a spec.<Kind>Refs
field.
spec:
# A single dependency to network
computeNetworkRef:
name: sample-network
# A list of dependencies of the same kind
projectRefs:
name: Config Connector-project1
name: Config Connector-project2
name: Config Connector-project3
As a naming convention, the resource reference field should be <Kind>Ref(s)
.
Kind
is the dependency’s Kind with a lowercase first letter, i.e.projectRef
Ref
can be singular or plural, depending on the number of dependencies, i.e.projectRef
refers to a single project,projectRefs
refers to a list of projects
type <KindRef> struct {
// +optional
External string `json:"external,omitempty"`
// +optional
Name string `json:"name,omitempty"`
// +optional
Namespace string `json:"name,omitempty"`
}
The reference validation can be either CRD validation or Config Connector controller check. It should not require GCP calls.
- If the reference does not have a corresponding Config Connector Kind yet, the
.<Kind>Ref.external
is required. Note: the.<Kind>Ref
itself can be optional. - If the reference has a corresponding Config Connector Kind, the
<Kind>Ref.external
and<Kind>Ref.name
areoneOf
required. Note: the.<Kind>Ref
itself can be optional.
The external
should be in the format of the asset inventory without the service domain.
- i.e.
computeNetworkRef.external
should be in the form ofprojects/<projectID>/global/networks/<networkID>
If the referenced Config Connector object is cluster scoped or in the same namespace, the referenced <Kind>Ref.namespace
is optional and should use default
If the referenced Config Connector object is namespace scoped but not in the same namespace, the referenced <Kind>Ref.namespace
is **required **to avoid Config Connector ambiguity and customer errors.
Config Connector has a predefined k8s.ReferenceNotFound
error that should be used when the referenced Config Connector object is not found.
A list of references of the same kind can introduce many problems if not handled well.
Config Connector should have strict validations for those resources according to the real usage. This will make Config Connector survive in the long run to avoid backward compatibility overhead.
If the GCP service expects each reference to be unique, Config Connector should require using either <Kind>Refs[].external
or <Kind>Refs[].name
, but not a mix of the two types. This gives sanity uniqueness checks without too much user overhead.
spec:
projectRefs:
name: Config Connector-project1
name: Config Connector-project2
name: Config Connector-project3
Or
spec:
projectRefs:
external: projects/gcp1
external: projects/gcp2
external: projects/gcp3
Config Connector shall allow users to change between <Kind>Refs[].external
and <Kind>Refs[].name
If <Kind>Refs[].external
is used, Config Connector shall only validate the uniqueness of the string values, but not check any GCP level requirements.
Config Connector does not (yet) have a good handle on the uniqueness of the Config Connector objects and their corresponding GCP resources.
If <Kind>Refs[].name
is used, Config Connector shall not validate the uniqueness of the namespace/name value, but check the uniqueness of the GCP resources from the corresponding Config Connector objects from externalRef field.
Config Connector shall send the exact same order of <Kind>Refs[]
to GCP service, unless sorting is preferred by the GCP service.
A change to the <Kind>Refs[]
order shall not trigger a new GCP call if only the order is changed but not the real content, unless the order matters to GCP services. If Config Connector cannot make the decision, skip this check. (open to discuss, I see some real use cases here)
The code of adding a reference should be placed in <kind>_reference.go
file under apis/<service>/<version>/
.
For TF-based or DCL-based Beta resources, Config Connector shall keep their original CRD and behavior when migrating to the Direct Resource.
Some Config Connector resources support a generic reference that requires Kind
.
When migrating to the Direct Resource, we should treat the resourceRef.Kind
as <Kind>Ref
, all other rules apply.
spec:
resourceRef:
kind: Project
name: gcp1
Some other thoughts: a conversion to change resourceRef
to <Kind>Ref
; warn that spec.resourceRef
as deprecated in status
Some Config Connector resources make the resourceKind.external
to serve different usages.
For example, the computeForwardingRule
has the ComputeAddress
reference which external
allows IP address value like 8.8.8.8
(search spec.ipAddress.addressRef.external
in this page)
We will continue supporting the existing bebavior when migrating to the Direct Resource.
Each of those ambiguous usages requires special handling, we shall limit those special handling code inside the corresponding Direct Resource resource code base and mark them with “legacy” comment to avoid repeating the bad design.