apis/bigquery/v1beta1/table_identity.go (82 lines of code) (raw):

// Copyright 2025 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. package v1beta1 import ( "context" "fmt" "strings" "github.com/GoogleCloudPlatform/k8s-config-connector/apis/common" "sigs.k8s.io/controller-runtime/pkg/client" ) // TableIdentity defines the resource reference to BigQueryTable, which "External" field // holds the GCP identifier for the KRM object. type TableIdentity struct { parent *TableParent id string } func (i *TableIdentity) String() string { return i.parent.String() + "/tables/" + i.id } func (i *TableIdentity) ID() string { return i.id } func (i *TableIdentity) Parent() *TableParent { return i.parent } type TableParent struct { ProjectID string DatasetID string } func (p *TableParent) String() string { return "projects/" + p.ProjectID + "/datasets/" + p.DatasetID } // New builds a TableIdentity from the Config Connector Table object. func NewTableIdentity(ctx context.Context, reader client.Reader, obj *BigQueryTable) (*TableIdentity, error) { datasetExternalRef, err := obj.Spec.DatasetRef.NormalizedExternal(ctx, reader, obj.GetNamespace()) if err != nil { return nil, err } datasetParent, dataset, err := ParseDatasetExternal(datasetExternalRef) if err != nil { return nil, err } projectID := datasetParent.ProjectID // Get desired ID resourceID := common.ValueOf(obj.Spec.ResourceID) if resourceID == "" { resourceID = obj.GetName() } if resourceID == "" { return nil, fmt.Errorf("cannot resolve resource ID") } // Use approved External externalRef := common.ValueOf(obj.Status.ExternalRef) if externalRef != "" { // Validate desired with actual actualParent, actualResourceID, err := ParseTableExternal(externalRef) if err != nil { return nil, err } if actualParent.ProjectID != datasetParent.ProjectID { return nil, fmt.Errorf("spec.projectRef changed, expect %s, got %s", actualParent.ProjectID, projectID) } if actualParent.DatasetID != dataset { return nil, fmt.Errorf("spec.datasetRef changed, expect %s, got %s", actualParent.DatasetID, dataset) } if actualResourceID != resourceID { return nil, fmt.Errorf("cannot reset `metadata.name` or `spec.resourceID` to %s, since it has already assigned to %s", resourceID, actualResourceID) } } return &TableIdentity{ parent: &TableParent{ ProjectID: datasetParent.ProjectID, DatasetID: dataset, }, id: resourceID, }, nil } func ParseTableExternal(external string) (parent *TableParent, resourceID string, err error) { tokens := strings.Split(external, "/") if len(tokens) != 6 || tokens[0] != "projects" || tokens[2] != "tables" { return nil, "", fmt.Errorf("format of BigQueryTable external=%q was not known (use projects/{{projectID}}/datasets/{{datasetID}}/tables/{{tableID}})", external) } parent = &TableParent{ ProjectID: tokens[1], DatasetID: tokens[3], } resourceID = tokens[5] return parent, resourceID, nil }