diff --git a/apis/compute/v1beta1/computeforwardingrule_types.go b/apis/compute/v1beta1/computeforwardingrule_types.go index b83c1b1975..3ef6a5e395 100644 --- a/apis/compute/v1beta1/computeforwardingrule_types.go +++ b/apis/compute/v1beta1/computeforwardingrule_types.go @@ -87,6 +87,9 @@ type ForwardingruleServiceDirectoryRegistrations struct { } type ForwardingruleTarget struct { + // +optional + GoogleApiBundle *string `json:"googleApiBundle,omitempty"` + // +optional ServiceAttachmentRef *refs.ComputeServiceAttachmentRef `json:"serviceAttachmentRef,omitempty"` diff --git a/apis/compute/v1beta1/zz_generated.deepcopy.go b/apis/compute/v1beta1/zz_generated.deepcopy.go index b26a9c7026..c5c20d00c3 100644 --- a/apis/compute/v1beta1/zz_generated.deepcopy.go +++ b/apis/compute/v1beta1/zz_generated.deepcopy.go @@ -358,6 +358,11 @@ func (in *ForwardingruleServiceDirectoryRegistrations) DeepCopy() *Forwardingrul // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ForwardingruleTarget) DeepCopyInto(out *ForwardingruleTarget) { *out = *in + if in.GoogleApiBundle != nil { + in, out := &in.GoogleApiBundle, &out.GoogleApiBundle + *out = new(string) + **out = **in + } if in.ServiceAttachmentRef != nil { in, out := &in.ServiceAttachmentRef, &out.ServiceAttachmentRef *out = new(refsv1beta1.ComputeServiceAttachmentRef) diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_computeforwardingrules.compute.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_computeforwardingrules.compute.cnrm.cloud.google.com.yaml index 40d12cc5c5..49b45807cc 100644 --- a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_computeforwardingrules.compute.cnrm.cloud.google.com.yaml +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_computeforwardingrules.compute.cnrm.cloud.google.com.yaml @@ -8,7 +8,6 @@ metadata: cnrm.cloud.google.com/managed-by-kcc: "true" cnrm.cloud.google.com/stability-level: stable cnrm.cloud.google.com/system: "true" - cnrm.cloud.google.com/tf2crd: "true" name: computeforwardingrules.compute.cnrm.cloud.google.com spec: group: compute.cnrm.cloud.google.com @@ -16,6 +15,7 @@ spec: categories: - gcp kind: ComputeForwardingRule + listKind: ComputeForwardingRuleList plural: computeforwardingrules shortNames: - gcpcomputeforwardingrule @@ -43,16 +43,17 @@ spec: name: v1beta1 schema: openAPIV3Schema: + description: ComputeForwardingRule is the Schema for the compute API properties: apiVersion: - description: 'apiVersion defines the versioned schema of this representation + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'kind is a string value representing the REST resource this + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -93,9 +94,8 @@ spec: whether the PSC endpoint can be accessed from another region. type: boolean backendServiceRef: - description: |- - A ComputeBackendService to receive the matched traffic. This is - used only for internal load balancing. + description: A ComputeBackendService to receive the matched traffic. + This is used only for internal load balancing. oneOf: - not: required: @@ -112,20 +112,21 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `ComputeBackendService` - resource.' + description: The ComputeBackendService selflink in the form "projects/{{project}}/global/backendServices/{{name}}" + or "projects/{{project}}/regions/{{region}}/backendServices/{{name}}" + when not managed by KCC. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeBackendService` resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeBackendService` + resource. type: string type: object description: - description: |- - Immutable. An optional description of this resource. Provide this property when - you create the resource. + description: Immutable. An optional description of this resource. + Provide this property when you create the resource. type: string ipAddress: description: |- @@ -148,11 +149,6 @@ spec: forwarding rule. By default, if this field is empty, an ephemeral internal IP address will be automatically allocated from the IP range of the subnet or network configured for this forwarding rule. - oneOf: - - required: - - addressRef - - required: - - ip properties: addressRef: oneOf: @@ -171,14 +167,14 @@ spec: - external properties: external: - description: 'Allowed value: The `address` field of a `ComputeAddress` - resource.' + description: The ComputeAddress selflink in the form "projects/{{project}}/regions/{{region}}/addresses/{{name}}" + when not managed by KCC. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeAddress` resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeAddress` resource. type: string type: object ip: @@ -260,14 +256,12 @@ spec: items: properties: name: - description: |- - Immutable. Name of the metadata label. The length must be between - 1 and 1024 characters, inclusive. + description: Immutable. Name of the metadata label. The + length must be between 1 and 1024 characters, inclusive. type: string value: - description: |- - Immutable. The value that the label must match. The value has a maximum - length of 1024 characters. + description: Immutable. The value that the label must + match. The value has a maximum length of 1024 characters. type: string required: - name @@ -290,11 +284,10 @@ spec: type: object type: array networkRef: - description: |- - This field is not used for external load balancing. For internal - load balancing, this field identifies the network that the load - balanced IP should belong to for this forwarding rule. If this - field is not specified, the default network will be used. + description: This field is not used for external load balancing. For + internal load balancing, this field identifies the network that + the load balanced IP should belong to for this forwarding rule. + If this field is not specified, the default network will be used. oneOf: - not: required: @@ -311,14 +304,14 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `ComputeNetwork` - resource.' + description: The compute network selflink of form "projects//global/networks/", + when not managed by Config Connector. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeNetwork` resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeNetwork` resource. type: string type: object networkTier: @@ -352,7 +345,6 @@ spec: [port specifications](https://cloud.google.com/load-balancing/docs/forwarding-rule-concepts#port_specifications) for details. - Only packets addressed to ports in the specified range will be forwarded to the backends configured with this forwarding rule. @@ -374,7 +366,6 @@ spec: * By internal TCP/UDP load balancers, backend service-based network load balancers, internal protocol forwarding and when protocol is not L3_DEFAULT. - You can specify a list of up to five ports by number, separated by commas. The ports can be contiguous or discontiguous. Only packets addressed to these ports will be forwarded to the backends configured with this @@ -465,38 +456,24 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `ComputeSubnetwork` - resource.' + description: The ComputeSubnetwork selflink of form "projects/{{project}}/regions/{{region}}/subnetworks/{{name}}", + when not managed by KCC. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeSubnetwork` resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeSubnetwork` resource. type: string type: object target: - description: |- - The target resource to receive the matched traffic. The forwarded - traffic must be of a type appropriate to the target object. For - INTERNAL_SELF_MANAGED load balancing, only HTTP and HTTPS targets + description: The target resource to receive the matched traffic. The + forwarded traffic must be of a type appropriate to the target object. + For INTERNAL_SELF_MANAGED load balancing, only HTTP and HTTPS targets are valid. - oneOf: - - required: - - serviceAttachmentRef - - required: - - targetGRPCProxyRef - - required: - - targetHTTPProxyRef - - required: - - targetHTTPSProxyRef - - required: - - targetSSLProxyRef - - required: - - targetTCPProxyRef - - required: - - targetVPNGatewayRef properties: + googleApiBundle: + type: string serviceAttachmentRef: oneOf: - not: @@ -514,14 +491,17 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `ComputeServiceAttachment` - resource.' + description: The ComputeServiceAttachment selflink in the + form "projects/{{project}}/regions/{{region}}/serviceAttachments/{{name}}" + when not managed by KCC. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeServiceAttachment` + resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeServiceAttachment` + resource. type: string type: object targetGRPCProxyRef: @@ -541,14 +521,17 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `ComputeTargetGRPCProxy` - resource.' + description: The ComputeTargetGrpcProxy selflink in the form + "projects/{{project}}/global/targetGrpcProxies/{{name}}" + when not managed by KCC. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeTargetGrpcProxy` + resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeTargetGrpcProxy` + resource. type: string type: object targetHTTPProxyRef: @@ -568,14 +551,18 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `ComputeTargetHTTPProxy` - resource.' + description: The ComputeTargetHTTPProxy selflink in the form + "projects/{{project}}/global/targetHttpProxies/{{name}}" + or "projects/{{project}}/regions/{{region}}/targetHttpProxies/{{name}}" + when not managed by KCC. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeTargetHTTPProxy` + resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeTargetHTTPProxy` + resource. type: string type: object targetHTTPSProxyRef: @@ -595,14 +582,18 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `ComputeTargetHTTPSProxy` - resource.' + description: The ComputeTargetHTTPSProxy selflink in the form + "projects/{{project}}/global/targetHttpProxies/{{name}}" + or "projects/{{project}}/regions/{{region}}/targetHttpProxies/{{name}}" + when not managed by KCC. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeTargetHTTPSProxy` + resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeTargetHTTPSProxy` + resource. type: string type: object targetSSLProxyRef: @@ -622,14 +613,17 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `ComputeTargetSSLProxy` - resource.' + description: The ComputeTargetSSLProxy selflink in the form + "projects/{{project}}/global/targetSslProxies/{{name}}" + when not managed by KCC. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeTargetSSLProxy` + resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeTargetSSLProxy` + resource. type: string type: object targetTCPProxyRef: @@ -649,14 +643,18 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `ComputeTargetTCPProxy` - resource.' + description: The ComputeTargetTCPProxy selflink in the form + "projects/{{project}}/global/targetTcpProxies/{{name}}" + or "projects/{{project}}/regions/{{region}}/targetTcpProxies/{{name}}" + when not managed by KCC. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeTargetTCPProxy` + resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeTargetTCPProxy` + resource. type: string type: object targetVPNGatewayRef: @@ -676,14 +674,17 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `ComputeTargetVPNGateway` - resource.' + description: The ComputeTargetVPNGateway selflink in the form + "projects/{{project}}/regions/{{region}}/targetVpnGateways/{{name}}" + when not managed by KCC. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeTargetVPNGateway` + resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeTargetVPNGateway` + resource. type: string type: object type: object @@ -700,8 +701,8 @@ spec: if the current Forwarding Rule does not have sourceIPRanges specified.' type: string conditions: - description: Conditions represent the latest available observation - of the resource's current state. + description: Conditions represent the latest available observations + of the object's current state. items: properties: lastTransitionTime: @@ -728,9 +729,12 @@ spec: creationTimestamp: description: Creation timestamp in RFC3339 text format. type: string + externalRef: + description: A unique Config Connector specifier for the resource + in GCP. + type: string labelFingerprint: - description: |- - The fingerprint used for optimistic locking of this resource. Used + description: The fingerprint used for optimistic locking of this resource. Used internally during updates. type: string observedGeneration: @@ -739,6 +743,7 @@ spec: If this is equal to metadata.generation, then that means that the current reported status reflects the most recent desired state of the resource. + format: int64 type: integer pscConnectionId: description: The PSC connection id of the PSC Forwarding Rule. @@ -757,16 +762,8 @@ spec: This field is only used for INTERNAL load balancing. type: string type: object - required: - - spec type: object served: true storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/dev/tasks/generate-crds b/dev/tasks/generate-crds index 4be2951203..228368b3b2 100755 --- a/dev/tasks/generate-crds +++ b/dev/tasks/generate-crds @@ -55,7 +55,7 @@ go run ./scripts/crd-tools reflow-descriptions --dir apis/config/crd/ # excluded_resources are resources that are under development for a direct conversion # we don't modify the CRD just yet for those but will in the future -excluded_resources=("computeforwardingrule") +#excluded_resources=("computeforwardingrule") cd ${REPO_ROOT} cd apis/config/crd/ diff --git a/mockgcp/mockcompute/globalforwardingrulesv1.go b/mockgcp/mockcompute/globalforwardingrulesv1.go index 5338e34d26..27d91be5d2 100644 --- a/mockgcp/mockcompute/globalforwardingrulesv1.go +++ b/mockgcp/mockcompute/globalforwardingrulesv1.go @@ -77,6 +77,17 @@ func (s *GlobalForwardingRulesV1) Insert(ctx context.Context, req *pb.InsertGlob if obj.NetworkTier == nil { obj.NetworkTier = PtrTo("PREMIUM") } + if isPSCForwardingRule(obj) { + var num uint64 = 111111111111 + obj.PscConnectionId = &num + obj.ServiceDirectoryRegistrations = []*pb.ForwardingRuleServiceDirectoryRegistration{ + { + Namespace: PtrTo("goog-psc-${networkID}-${networkID}"), + ServiceDirectoryRegion: PtrTo("us-central1"), + }, + } + + } // pattern: \d+(?:-\d+)? if obj.PortRange != nil { @@ -102,10 +113,17 @@ func (s *GlobalForwardingRulesV1) Insert(ctx context.Context, req *pb.InsertGlob return nil, err } + var opType *string + if isPSCForwardingRule(obj) { + opType = PtrTo("createPSCServiceEndpoint") + } else { + opType = PtrTo("insert") + } + op := &pb.Operation{ TargetId: obj.Id, TargetLink: obj.SelfLink, - OperationType: PtrTo("insert"), + OperationType: opType, User: PtrTo("user@example.com"), } return s.startGlobalLRO(ctx, name.Project.ID, op, func() (proto.Message, error) { @@ -127,10 +145,17 @@ func (s *GlobalForwardingRulesV1) Delete(ctx context.Context, req *pb.DeleteGlob return nil, err } + var opType *string + if isPSCForwardingRule(deleted) { + opType = PtrTo("deletePSCServiceEndpoint") + } else { + opType = PtrTo("delete") + } + op := &pb.Operation{ TargetId: deleted.Id, TargetLink: deleted.SelfLink, - OperationType: PtrTo("delete"), + OperationType: opType, User: PtrTo("user@example.com"), } return s.startGlobalLRO(ctx, name.Project.ID, op, func() (proto.Message, error) { @@ -160,7 +185,7 @@ func (s *GlobalForwardingRulesV1) SetLabels(ctx context.Context, req *pb.SetLabe op := &pb.Operation{ TargetId: obj.Id, TargetLink: obj.SelfLink, - OperationType: PtrTo("SetLabels"), + OperationType: PtrTo("setLabels"), User: PtrTo("user@example.com"), // SetLabels operation has EndTime in response EndTime: PtrTo("2024-04-01T12:34:56.123456Z"), @@ -192,7 +217,7 @@ func (s *GlobalForwardingRulesV1) SetTarget(ctx context.Context, req *pb.SetTarg op := &pb.Operation{ TargetId: obj.Id, TargetLink: obj.SelfLink, - OperationType: PtrTo("SetTarget"), + OperationType: PtrTo("setTarget"), User: PtrTo("user@example.com"), } return s.startGlobalLRO(ctx, name.Project.ID, op, func() (proto.Message, error) { @@ -230,3 +255,11 @@ func (s *MockService) parseGlobalForwardingRuleName(name string) (*globalForward return nil, status.Errorf(codes.InvalidArgument, "name %q is not valid", name) } } + +func isPSCForwardingRule(obj *pb.ForwardingRule) bool { + target := *obj.Target + if target == "all-apis" || target == "vpc-sc" || strings.Contains(target, "/serviceAttachments/") { + return true + } + return false +} diff --git a/mockgcp/mockcompute/regionalforwardingrulev1.go b/mockgcp/mockcompute/regionalforwardingrulev1.go index 6f64832373..68b2d84ce2 100644 --- a/mockgcp/mockcompute/regionalforwardingrulev1.go +++ b/mockgcp/mockcompute/regionalforwardingrulev1.go @@ -161,7 +161,7 @@ func (s *RegionalForwardingRulesV1) SetLabels(ctx context.Context, req *pb.SetLa op := &pb.Operation{ TargetId: obj.Id, TargetLink: obj.SelfLink, - OperationType: PtrTo("SetLabels"), + OperationType: PtrTo("setLabels"), User: PtrTo("user@example.com"), // SetLabels operation has EndTime in response EndTime: PtrTo("2024-04-01T12:34:56.123456Z"), @@ -193,7 +193,7 @@ func (s *RegionalForwardingRulesV1) SetTarget(ctx context.Context, req *pb.SetTa op := &pb.Operation{ TargetId: obj.Id, TargetLink: obj.SelfLink, - OperationType: PtrTo("SetTarget"), + OperationType: PtrTo("setTarget"), User: PtrTo("user@example.com"), } return s.startRegionalLRO(ctx, name.Project.ID, name.Region, op, func() (proto.Message, error) { diff --git a/pkg/clients/generated/apis/compute/v1beta1/computeforwardingrule_types.go b/pkg/clients/generated/apis/compute/v1beta1/computeforwardingrule_types.go index ab48a31e93..0c96422dda 100644 --- a/pkg/clients/generated/apis/compute/v1beta1/computeforwardingrule_types.go +++ b/pkg/clients/generated/apis/compute/v1beta1/computeforwardingrule_types.go @@ -36,12 +36,10 @@ import ( ) type ForwardingruleFilterLabels struct { - /* Immutable. Name of the metadata label. The length must be between - 1 and 1024 characters, inclusive. */ + /* Immutable. Name of the metadata label. The length must be between 1 and 1024 characters, inclusive. */ Name string `json:"name"` - /* Immutable. The value that the label must match. The value has a maximum - length of 1024 characters. */ + /* Immutable. The value that the label must match. The value has a maximum length of 1024 characters. */ Value string `json:"value"` } @@ -81,6 +79,9 @@ type ForwardingruleServiceDirectoryRegistrations struct { } type ForwardingruleTarget struct { + // +optional + GoogleApiBundle *string `json:"googleApiBundle,omitempty"` + // +optional ServiceAttachmentRef *v1alpha1.ResourceRef `json:"serviceAttachmentRef,omitempty"` @@ -138,13 +139,11 @@ type ComputeForwardingRuleSpec struct { // +optional AllowPscGlobalAccess *bool `json:"allowPscGlobalAccess,omitempty"` - /* A ComputeBackendService to receive the matched traffic. This is - used only for internal load balancing. */ + /* A ComputeBackendService to receive the matched traffic. This is used only for internal load balancing. */ // +optional BackendServiceRef *v1alpha1.ResourceRef `json:"backendServiceRef,omitempty"` - /* Immutable. An optional description of this resource. Provide this property when - you create the resource. */ + /* Immutable. An optional description of this resource. Provide this property when you create the resource. */ // +optional Description *string `json:"description,omitempty"` @@ -234,10 +233,7 @@ type ComputeForwardingRuleSpec struct { // +optional MetadataFilters []ForwardingruleMetadataFilters `json:"metadataFilters,omitempty"` - /* This field is not used for external load balancing. For internal - load balancing, this field identifies the network that the load - balanced IP should belong to for this forwarding rule. If this - field is not specified, the default network will be used. */ + /* This field is not used for external load balancing. For internal load balancing, this field identifies the network that the load balanced IP should belong to for this forwarding rule. If this field is not specified, the default network will be used. */ // +optional NetworkRef *v1alpha1.ResourceRef `json:"networkRef,omitempty"` @@ -269,7 +265,6 @@ type ComputeForwardingRuleSpec struct { [port specifications](https://cloud.google.com/load-balancing/docs/forwarding-rule-concepts#port_specifications) for details. - Only packets addressed to ports in the specified range will be forwarded to the backends configured with this forwarding rule. @@ -291,7 +286,6 @@ type ComputeForwardingRuleSpec struct { * By internal TCP/UDP load balancers, backend service-based network load balancers, internal protocol forwarding and when protocol is not L3_DEFAULT. - You can specify a list of up to five ports by number, separated by commas. The ports can be contiguous or discontiguous. Only packets addressed to these ports will be forwarded to the backends configured with this @@ -348,10 +342,7 @@ type ComputeForwardingRuleSpec struct { // +optional SubnetworkRef *v1alpha1.ResourceRef `json:"subnetworkRef,omitempty"` - /* The target resource to receive the matched traffic. The forwarded - traffic must be of a type appropriate to the target object. For - INTERNAL_SELF_MANAGED load balancing, only HTTP and HTTPS targets - are valid. */ + /* The target resource to receive the matched traffic. The forwarded traffic must be of a type appropriate to the target object. For INTERNAL_SELF_MANAGED load balancing, only HTTP and HTTPS targets are valid. */ // +optional Target *ForwardingruleTarget `json:"target,omitempty"` } @@ -368,8 +359,11 @@ type ComputeForwardingRuleStatus struct { // +optional CreationTimestamp *string `json:"creationTimestamp,omitempty"` - /* The fingerprint used for optimistic locking of this resource. Used - internally during updates. */ + /* A unique Config Connector specifier for the resource in GCP. */ + // +optional + ExternalRef *string `json:"externalRef,omitempty"` + + /* The fingerprint used for optimistic locking of this resource. Used internally during updates. */ // +optional LabelFingerprint *string `json:"labelFingerprint,omitempty"` diff --git a/pkg/clients/generated/apis/compute/v1beta1/zz_generated.deepcopy.go b/pkg/clients/generated/apis/compute/v1beta1/zz_generated.deepcopy.go index 75c3d39b19..7d54baecb3 100644 --- a/pkg/clients/generated/apis/compute/v1beta1/zz_generated.deepcopy.go +++ b/pkg/clients/generated/apis/compute/v1beta1/zz_generated.deepcopy.go @@ -2842,6 +2842,11 @@ func (in *ComputeForwardingRuleStatus) DeepCopyInto(out *ComputeForwardingRuleSt *out = new(string) **out = **in } + if in.ExternalRef != nil { + in, out := &in.ExternalRef, &out.ExternalRef + *out = new(string) + **out = **in + } if in.LabelFingerprint != nil { in, out := &in.LabelFingerprint, &out.LabelFingerprint *out = new(string) @@ -10605,6 +10610,11 @@ func (in *ForwardingruleServiceDirectoryRegistrations) DeepCopy() *Forwardingrul // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ForwardingruleTarget) DeepCopyInto(out *ForwardingruleTarget) { *out = *in + if in.GoogleApiBundle != nil { + in, out := &in.GoogleApiBundle, &out.GoogleApiBundle + *out = new(string) + **out = **in + } if in.ServiceAttachmentRef != nil { in, out := &in.ServiceAttachmentRef, &out.ServiceAttachmentRef *out = new(v1alpha1.ResourceRef) diff --git a/pkg/controller/direct/compute/forwardingrule_controller.go b/pkg/controller/direct/compute/forwardingrule_controller.go index 5be5f0318d..7da41dae3c 100644 --- a/pkg/controller/direct/compute/forwardingrule_controller.go +++ b/pkg/controller/direct/compute/forwardingrule_controller.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "reflect" + "strings" "k8s.io/klog/v2" @@ -90,8 +91,8 @@ func (m *forwardingRuleModel) AdapterForObject(ctx context.Context, reader clien obj.Spec.NetworkRef.External = networkRef.External } - // Get compute address - if obj.Spec.IpAddress.AddressRef != nil { + // Get compute address, address is optional + if obj.Spec.IpAddress != nil && obj.Spec.IpAddress.AddressRef != nil { computeAddressRef, err := ResolveComputeAddress(ctx, reader, obj, obj.Spec.IpAddress.AddressRef) if err != nil { return nil, err @@ -249,7 +250,13 @@ func (a *forwardingRuleAdapter) Create(ctx context.Context, createOp *directbase return mapCtx.Err() } forwardingRule.Name = direct.LazyPtr(a.id.forwardingRule) - forwardingRule.Labels = desired.Labels + target := direct.ValueOf(forwardingRule.Target) + + // API restriction: Labels are invalid in Private Service Connect Forwarding Rule. + // TF workaround: https://github.com/GoogleCloudPlatform/k8s-config-connector/pull/944 + if target != "all-apis" && target != "vpc-sc" && !strings.Contains(target, "/serviceAttachments/") { + forwardingRule.Labels = desired.Labels + } var err error op := &gcp.Operation{} diff --git a/pkg/controller/direct/compute/mapper.go b/pkg/controller/direct/compute/mapper.go index 2160112a73..4823647ea7 100644 --- a/pkg/controller/direct/compute/mapper.go +++ b/pkg/controller/direct/compute/mapper.go @@ -37,7 +37,7 @@ func ComputeForwardingRuleSpec_IpAddress_ToProto(mapCtx *direct.MapContext, in * } out = direct.LazyPtr(oneof.External) } - if in.Ip != nil { + if oneof := in.Ip; oneof != nil { out = in.Ip } return out @@ -115,6 +115,9 @@ func ComputeForwardingRuleSpec_Target_ToProto(mapCtx *direct.MapContext, in *krm } var out *string + if oneof := in.GoogleApiBundle; oneof != nil { + out = in.GoogleApiBundle + } if oneof := in.ServiceAttachmentRef; oneof != nil { if oneof.External == "" { mapCtx.Errorf("reference %s was not pre-resolved", oneof.Name) diff --git a/pkg/randomid/generator.go b/pkg/randomid/generator.go index 601577c154..ac86d2f7d9 100644 --- a/pkg/randomid/generator.go +++ b/pkg/randomid/generator.go @@ -29,7 +29,11 @@ type ID struct { // New builds a random identifier. // We always generate a more secure random value; we could in future expose less secure options if this becomes a bottleneck. func New() ID { - b := make([]byte, 12) + // The forwarding rule name for PSC Google APIs must be an 1-20 characters string with lowercase letters and numbers and must start with a letter. + // 9 bytes is equivalent to 72 bits of data. Each character in Base32 represents 5 bits. + // Calculation: 72 bits / 5 bits per character = 14.4 characters. + // Round up to the nearest whole number, which is 15. the ID string will have 15 characters. + b := make([]byte, 9) if _, err := cryptorand.Read(b); err != nil { klog.Fatalf("failed to read from crypto/rand: %v", err) } diff --git a/pkg/test/constants/constants.go b/pkg/test/constants/constants.go index 9c4b291706..52e1458ba1 100644 --- a/pkg/test/constants/constants.go +++ b/pkg/test/constants/constants.go @@ -49,6 +49,8 @@ var TestNameRegexesToSkip = []string{ // Disable due to TF bug https://github.com/hashicorp/terraform-provider-google/issues/16255. // We can't specify labels in the create operation, that causes AssertLabelsMatchAndHaveManagedLabel check to fail. ".*(regionalforwardingrulepsc).*", + // This test only works with direct controller. Re-enable it when we turn on direct ComputeForwardingRule. + ".*(globalforwardingrulepscgoogleapis).*", } // TestNameRegexToSkipForTestCRUD is similar to diff --git a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalcomputeforwardingrule/_http.log b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalcomputeforwardingrule/_http.log index 398e273a35..87acd3e297 100644 --- a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalcomputeforwardingrule/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalcomputeforwardingrule/_http.log @@ -895,7 +895,7 @@ X-Xss-Protection: 0 "insertTime": "2024-04-01T12:34:56.123456Z", "kind": "compute#operation", "name": "${operationID}", - "operationType": "SetLabels", + "operationType": "setLabels", "progress": 0, "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", "startTime": "2024-04-01T12:34:56.123456Z", @@ -929,7 +929,7 @@ X-Xss-Protection: 0 "insertTime": "2024-04-01T12:34:56.123456Z", "kind": "compute#operation", "name": "${operationID}", - "operationType": "SetLabels", + "operationType": "setLabels", "progress": 100, "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", "startTime": "2024-04-01T12:34:56.123456Z", @@ -1007,7 +1007,7 @@ X-Xss-Protection: 0 "insertTime": "2024-04-01T12:34:56.123456Z", "kind": "compute#operation", "name": "${operationID}", - "operationType": "SetTarget", + "operationType": "setTarget", "progress": 0, "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", "startTime": "2024-04-01T12:34:56.123456Z", @@ -1041,7 +1041,7 @@ X-Xss-Protection: 0 "insertTime": "2024-04-01T12:34:56.123456Z", "kind": "compute#operation", "name": "${operationID}", - "operationType": "SetTarget", + "operationType": "setTarget", "progress": 100, "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", "startTime": "2024-04-01T12:34:56.123456Z", diff --git a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/_generated_object_globalforwardingrulepscgoogleapis.golden.yaml b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/_generated_object_globalforwardingrulepscgoogleapis.golden.yaml new file mode 100644 index 0000000000..48d60951ed --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/_generated_object_globalforwardingrulepscgoogleapis.golden.yaml @@ -0,0 +1,38 @@ +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeForwardingRule +metadata: + annotations: + cnrm.cloud.google.com/management-conflict-prevention-policy: none + cnrm.cloud.google.com/project-id: ${projectId} + finalizers: + - cnrm.cloud.google.com/finalizer + - cnrm.cloud.google.com/deletion-defender + generation: 1 + labels: + cnrm-test: "true" + label-one: value-two + name: rule${uniqueId} + namespace: ${uniqueId} +spec: + description: A global forwarding rule + ipAddress: + addressRef: + name: default + loadBalancingScheme: "" + location: global + networkRef: + name: default + target: + googleApiBundle: all-apis +status: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: The resource is up to date + reason: UpToDate + status: "True" + type: Ready + creationTimestamp: "1970-01-01T00:00:00Z" + externalRef: //compute.googleapis.com/projects/${projectId}/global/forwardingrules/rule${uniqueId} + labelFingerprint: abcdef0123A= + observedGeneration: 1 + selfLink: https://www.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/rule${uniqueId} diff --git a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/_http.log b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/_http.log new file mode 100644 index 0000000000..f59ea347ab --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/_http.log @@ -0,0 +1,792 @@ +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "description": "Default network for the project", + "id": "000000000000000000000", + "kind": "compute#network", + "name": "${networkID}", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}" +} + +--- + +PATCH https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +{ + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL" +} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "compute.networks.patch", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}?alt=json&prettyPrint=false +User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "endTime": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "compute.networks.patch", + "progress": 100, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "description": "Default network for the project", + "id": "000000000000000000000", + "kind": "compute#network", + "name": "${networkID}", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}" +} + +--- + +PATCH https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +{ + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL" +} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "compute.networks.patch", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}?alt=json&prettyPrint=false +User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "endTime": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "compute.networks.patch", + "progress": 100, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "description": "Default network for the project", + "id": "000000000000000000000", + "kind": "compute#network", + "name": "${networkID}", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${networkID}?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +404 Not Found +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "error": { + "code": 404, + "errors": [ + { + "domain": "global", + "message": "address \"projects/${projectId}/global/addresses/${networkID}\" not found", + "reason": "notFound" + } + ], + "message": "address \"projects/${projectId}/global/addresses/${networkID}\" not found" + } +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +{ + "address": "100.100.100.106", + "addressType": "INTERNAL", + "labels": { + "cnrm-test": "true", + "managed-by-cnrm": "true" + }, + "name": "${networkID}", + "network": "projects/${projectId}/global/networks/${networkID}", + "purpose": "PRIVATE_SERVICE_CONNECT" +} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${networkID}?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "address": "100.100.100.106", + "addressType": "INTERNAL", + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "kind": "compute#address", + "labelFingerprint": "abcdef0123A=", + "labels": { + "cnrm-test": "true", + "managed-by-cnrm": "true" + }, + "name": "${networkID}", + "network": "projects/${projectId}/global/networks/${networkID}", + "purpose": "PRIVATE_SERVICE_CONNECT", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${networkID}" +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${networkID}/setLabels?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +{ + "labelFingerprint": "abcdef0123A=", + "labels": { + "cnrm-test": "true", + "managed-by-cnrm": "true" + } +} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${networkID}?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "address": "100.100.100.106", + "addressType": "INTERNAL", + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "kind": "compute#address", + "labelFingerprint": "abcdef0123A=", + "labels": { + "cnrm-test": "true", + "managed-by-cnrm": "true" + }, + "name": "${networkID}", + "network": "projects/${projectId}/global/networks/${networkID}", + "purpose": "PRIVATE_SERVICE_CONNECT", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${networkID}" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/${forwardingRuleID} +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: project=${projectId}&forwarding_rule=rule${uniqueId} + +404 Not Found +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "error": { + "code": 404, + "errors": [ + { + "domain": "global", + "message": "forwardingRule \"projects/${projectId}/global/forwardingRules/rule${uniqueId}\" not found", + "reason": "notFound" + } + ], + "message": "forwardingRule \"projects/${projectId}/global/forwardingRules/rule${uniqueId}\" not found" + } +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: project=${projectId} + +{ + "IPAddress": "100.100.100.106", + "description": "A global forwarding rule", + "loadBalancingScheme": "", + "name": "rule${uniqueId}", + "network": "projects/${projectId}/global/networks/${networkID}", + "target": "all-apis" +} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "createPSCServiceEndpoint", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${forwardingRulesId}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/rule${uniqueId}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID} +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: project=${projectId}&operation=${operationID} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "endTime": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "createPSCServiceEndpoint", + "progress": 100, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${forwardingRulesId}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/rule${uniqueId}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/${forwardingRuleID} +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: project=${projectId}&forwarding_rule=rule${uniqueId} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "IPAddress": "100.100.100.106", + "IPProtocol": "TCP", + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "description": "A global forwarding rule", + "fingerprint": "abcdef0123A=", + "id": "000000000000000000000", + "kind": "compute#forwardingRule", + "labelFingerprint": "abcdef0123A=", + "loadBalancingScheme": "", + "name": "rule${uniqueId}", + "network": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "networkTier": "PREMIUM", + "pscConnectionId": "111111111111", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/rule${uniqueId}", + "serviceDirectoryRegistrations": [ + { + "namespace": "goog-psc-${networkID}-${networkID}", + "serviceDirectoryRegion": "us-central1" + } + ], + "target": "all-apis" +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/${forwardingRuleID}/setLabels +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: project=${projectId}&resource=rule${uniqueId} + +{ + "labelFingerprint": "abcdef0123A=", + "labels": { + "cnrm-test": "true", + "label-one": "value-two", + "managed-by-cnrm": "true" + } +} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "endTime": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "setLabels", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${forwardingRulesId}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/rule${uniqueId}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID} +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: project=${projectId}&operation=${operationID} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "endTime": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "setLabels", + "progress": 100, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${forwardingRulesId}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/rule${uniqueId}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/${forwardingRuleID} +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: project=${projectId}&forwarding_rule=rule${uniqueId} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "IPAddress": "100.100.100.106", + "IPProtocol": "TCP", + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "description": "A global forwarding rule", + "fingerprint": "abcdef0123A=", + "id": "000000000000000000000", + "kind": "compute#forwardingRule", + "labelFingerprint": "abcdef0123A=", + "labels": { + "cnrm-test": "true", + "label-one": "value-two", + "managed-by-cnrm": "true" + }, + "loadBalancingScheme": "", + "name": "rule${uniqueId}", + "network": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "networkTier": "PREMIUM", + "pscConnectionId": "111111111111", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/rule${uniqueId}", + "serviceDirectoryRegistrations": [ + { + "namespace": "goog-psc-${networkID}-${networkID}", + "serviceDirectoryRegion": "us-central1" + } + ], + "target": "all-apis" +} + +--- + +DELETE https://compute.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/${forwardingRuleID} +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: project=${projectId}&forwarding_rule=rule${uniqueId} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "deletePSCServiceEndpoint", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${forwardingRulesId}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/rule${uniqueId}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID} +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: project=${projectId}&operation=${operationID} + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "endTime": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "deletePSCServiceEndpoint", + "progress": 100, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${forwardingRulesId}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/forwardingRules/rule${uniqueId}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${networkID}?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "address": "100.100.100.106", + "addressType": "INTERNAL", + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "kind": "compute#address", + "labelFingerprint": "abcdef0123A=", + "labels": { + "cnrm-test": "true", + "managed-by-cnrm": "true" + }, + "name": "${networkID}", + "network": "projects/${projectId}/global/networks/${networkID}", + "purpose": "PRIVATE_SERVICE_CONNECT", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${networkID}" +} + +--- + +DELETE https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${networkID}?alt=json +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE" +} \ No newline at end of file diff --git a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/create.yaml b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/create.yaml new file mode 100644 index 0000000000..f47d9efcb6 --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/create.yaml @@ -0,0 +1,32 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeForwardingRule +metadata: + labels: + label-one: "value-one" + name: rule${uniqueId} +spec: + description: "A global forwarding rule" + location: global + target: + # a supported Google API bundle (global-only) + googleApiBundle: "all-apis" + loadBalancingScheme: "" + ipAddress: + addressRef: + name: default + networkRef: + name: default diff --git a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/dependencies.yaml b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/dependencies.yaml new file mode 100644 index 0000000000..e2c273e5e0 --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/dependencies.yaml @@ -0,0 +1,34 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeNetwork +metadata: + annotations: + cnrm.cloud.google.com/deletion-policy: "abandon" + name: default +spec: + description: Default network for the project +--- +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeAddress +metadata: + name: default +spec: + location: global + addressType: "INTERNAL" + purpose: "PRIVATE_SERVICE_CONNECT" + networkRef: + name: default + address: "100.100.100.106" diff --git a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/update.yaml b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/update.yaml new file mode 100644 index 0000000000..2b6477605f --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/globalforwardingrulepscgoogleapis/update.yaml @@ -0,0 +1,32 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeForwardingRule +metadata: + labels: + label-one: "value-two" + name: rule${uniqueId} +spec: + description: "A global forwarding rule" + location: global + target: + # a supported Google API bundle (global-only) + googleApiBundle: "all-apis" + loadBalancingScheme: "" + ipAddress: + addressRef: + name: default + networkRef: + name: default diff --git a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/regionalcomputeforwardingrule/_http.log b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/regionalcomputeforwardingrule/_http.log index cade0a3ade..9c06262f05 100644 --- a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/regionalcomputeforwardingrule/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computeforwardingrule/regionalcomputeforwardingrule/_http.log @@ -667,7 +667,7 @@ X-Xss-Protection: 0 "insertTime": "2024-04-01T12:34:56.123456Z", "kind": "compute#operation", "name": "${operationID}", - "operationType": "SetLabels", + "operationType": "setLabels", "progress": 0, "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}", @@ -702,7 +702,7 @@ X-Xss-Protection: 0 "insertTime": "2024-04-01T12:34:56.123456Z", "kind": "compute#operation", "name": "${operationID}", - "operationType": "SetLabels", + "operationType": "setLabels", "progress": 100, "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}", diff --git a/tests/e2e/unified_test.go b/tests/e2e/unified_test.go index b3918d5d09..9379b45120 100644 --- a/tests/e2e/unified_test.go +++ b/tests/e2e/unified_test.go @@ -542,6 +542,8 @@ func runScenario(ctx context.Context, t *testing.T, testPause bool, fixture reso r.PathIDs[targetId] = "${sslCertificatesId}" case "forwardingRules": r.PathIDs[targetId] = "${forwardingRulesId}" + case "addresses": + r.PathIDs[targetId] = "${addressesId}" } } }