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).
Kindis the dependency’s Kind with a lowercase first letter, i.e.projectRefRefcan be singular or plural, depending on the number of dependencies, i.e.projectRefrefers to a single project,projectRefsrefers 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.externalis required. Note: the.<Kind>Refitself can be optional. - If the reference has a corresponding Config Connector Kind, the
<Kind>Ref.externaland<Kind>Ref.nameareoneOfrequired. Note: the.<Kind>Refitself can be optional.
The external should be in the format of the asset inventory without the service domain.
- i.e.
computeNetworkRef.externalshould 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/gcp3Config 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: gcp1Some 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.