Skip to content

Commit

Permalink
chore: create shared project number/id mapper
Browse files Browse the repository at this point in the history
  • Loading branch information
justinsb committed Dec 19, 2024
1 parent 9f21414 commit 561ba16
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 41 deletions.
58 changes: 58 additions & 0 deletions apis/common/projects/mapper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package projects

import (
"context"
"fmt"
"strconv"
"strings"

resourcemanager "cloud.google.com/go/resourcemanager/apiv3"
"cloud.google.com/go/resourcemanager/apiv3/resourcemanagerpb"
)

type ProjectMapper struct {
client *resourcemanager.ProjectsClient
}

func NewProjectMapper(client *resourcemanager.ProjectsClient) *ProjectMapper {
return &ProjectMapper{
client: client,
}
}

func (m *ProjectMapper) ReplaceProjectNumberWithID(ctx context.Context, projectID string) (string, error) {
if _, err := strconv.ParseInt(projectID, 10, 64); err != nil {
// Not a project number, no need to map
return projectID, nil
}

req := &resourcemanagerpb.GetProjectRequest{
Name: "projects/" + projectID,
}
project, err := m.client.GetProject(ctx, req)
if err != nil {
return "", fmt.Errorf("error getting project %q: %w", req.Name, err)
}
return project.ProjectId, nil
}

func (m *ProjectMapper) LookupProjectNumber(ctx context.Context, projectID string) (int64, error) {
// Check if the project number is already a valid integer
// If not, we need to look it up
projectNumber, err := strconv.ParseInt(projectID, 10, 64)
if err != nil {
req := &resourcemanagerpb.GetProjectRequest{
Name: "projects/" + projectID,
}
project, err := m.client.GetProject(ctx, req)
if err != nil {
return 0, fmt.Errorf("error getting project %q: %w", req.Name, err)
}
n, err := strconv.ParseInt(strings.TrimPrefix(project.Name, "projects/"), 10, 64)
if err != nil {
return 0, fmt.Errorf("error parsing project number for %q: %w", project.Name, err)
}
projectNumber = n
}
return projectNumber, nil
}
23 changes: 5 additions & 18 deletions apis/refs/v1beta1/computerefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ import (
"strconv"
"strings"

resourcemanager "cloud.google.com/go/resourcemanager/apiv3"
resourcemanagerpb "cloud.google.com/go/resourcemanager/apiv3/resourcemanagerpb"
"github.com/GoogleCloudPlatform/k8s-config-connector/apis/common/projects"
"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand Down Expand Up @@ -74,7 +73,7 @@ func ParseComputeNetworkID(external string) (*ComputeNetworkID, error) {
}

// ConvertToProjectNumber converts the external reference to use a project number.
func (ref *ComputeNetworkRef) ConvertToProjectNumber(ctx context.Context, projectsClient *resourcemanager.ProjectsClient) error {
func (ref *ComputeNetworkRef) ConvertToProjectNumber(ctx context.Context, projectMapper *projects.ProjectMapper) error {
if ref == nil {
return nil
}
Expand All @@ -84,24 +83,12 @@ func (ref *ComputeNetworkRef) ConvertToProjectNumber(ctx context.Context, projec
return err
}

// Check if the project number is already a valid integer
// If not, we need to look it up
projectNumber, err := strconv.ParseInt(id.Project, 10, 64)
projectNumber, err := projectMapper.LookupProjectNumber(ctx, id.Project)
if err != nil {
req := &resourcemanagerpb.GetProjectRequest{
Name: "projects/" + id.Project,
}
project, err := projectsClient.GetProject(ctx, req)
if err != nil {
return fmt.Errorf("error getting project %q: %w", req.Name, err)
}
n, err := strconv.ParseInt(strings.TrimPrefix(project.Name, "projects/"), 10, 64)
if err != nil {
return fmt.Errorf("error parsing project number for %q: %w", project.Name, err)
}
projectNumber = n
return fmt.Errorf("error looking up project number for project %q: %w", id.Project, err)
}
id.Project = strconv.FormatInt(projectNumber, 10)

ref.External = id.String()
return nil
}
Expand Down
23 changes: 23 additions & 0 deletions pkg/config/controllerconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@
package config

import (
"context"
"fmt"
"net/http"

cloudresourcemanager "cloud.google.com/go/resourcemanager/apiv3"
"github.com/GoogleCloudPlatform/k8s-config-connector/apis/common/projects"
"golang.org/x/oauth2"
"google.golang.org/api/option"
)
Expand All @@ -40,6 +44,25 @@ type ControllerConfig struct {
// GCPTokenSource mints OAuth2 tokens to be passed with GCP API calls,
// allowing use of a non-default OAuth2 identity
GCPTokenSource oauth2.TokenSource

// ProjectMapper maps between project ids and numbers
ProjectMapper *projects.ProjectMapper
}

func (c *ControllerConfig) Init(ctx context.Context) error {
if c.ProjectMapper == nil {
opts, err := c.RESTClientOptions()
if err != nil {
return err
}

projectsClient, err := cloudresourcemanager.NewProjectsRESTClient(ctx, opts...)
if err != nil {
return fmt.Errorf("building cloudresourcemanager client: %w", err)
}
c.ProjectMapper = projects.NewProjectMapper(projectsClient)
}
return nil
}

func (c *ControllerConfig) RESTClientOptions() ([]option.ClientOption, error) {
Expand Down
28 changes: 5 additions & 23 deletions pkg/controller/direct/cloudbuild/workerpool_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ import (

gcp "cloud.google.com/go/cloudbuild/apiv1/v2"
cloudbuildpb "cloud.google.com/go/cloudbuild/apiv1/v2/cloudbuildpb"
cloudresourcemanager "cloud.google.com/go/resourcemanager/apiv3"
"google.golang.org/protobuf/types/known/fieldmaskpb"

krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/cloudbuild/v1beta1"
"github.com/GoogleCloudPlatform/k8s-config-connector/apis/common/projects"
refs "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1"
"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/config"
"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct"
Expand Down Expand Up @@ -69,19 +69,6 @@ func (m *model) client(ctx context.Context) (*gcp.Client, error) {
return gcpClient, err
}

func (m *model) projectsClient(ctx context.Context) (*cloudresourcemanager.ProjectsClient, error) {
opts, err := m.config.RESTClientOptions()
if err != nil {
return nil, err
}

crmClient, err := cloudresourcemanager.NewProjectsRESTClient(ctx, opts...)
if err != nil {
return nil, fmt.Errorf("building cloudresourcemanager client: %w", err)
}
return crmClient, err
}

func (m *model) AdapterForObject(ctx context.Context, reader client.Reader, u *unstructured.Unstructured) (directbase.Adapter, error) {
obj := &krm.CloudBuildWorkerPool{}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &obj); err != nil {
Expand Down Expand Up @@ -134,12 +121,6 @@ func (m *model) AdapterForObject(ctx context.Context, reader client.Reader, u *u
}
}

// Get Project GCP client
projectClient, err := m.projectsClient(ctx)
if err != nil {
return nil, err
}

// Get CloudBuild GCP client
gcpClient, err := m.client(ctx)
if err != nil {
Expand All @@ -148,7 +129,7 @@ func (m *model) AdapterForObject(ctx context.Context, reader client.Reader, u *u

return &Adapter{
id: id,
projectClient: projectClient,
projectMapper: m.config.ProjectMapper,
gcpClient: gcpClient,
reader: reader,
desired: obj,
Expand All @@ -170,6 +151,7 @@ func (m *model) AdapterForURL(ctx context.Context, url string) (directbase.Adapt
}

return &Adapter{
projectMapper: m.config.ProjectMapper,
id: &CloudBuildWorkerPoolIdentity{
project: tokens[1],
location: tokens[3],
Expand All @@ -184,7 +166,7 @@ func (m *model) AdapterForURL(ctx context.Context, url string) (directbase.Adapt

type Adapter struct {
id *CloudBuildWorkerPoolIdentity
projectClient *cloudresourcemanager.ProjectsClient
projectMapper *projects.ProjectMapper
gcpClient *gcp.Client
reader client.Reader
desired *krm.CloudBuildWorkerPool
Expand Down Expand Up @@ -370,7 +352,7 @@ func (a *Adapter) resolveDependencies(ctx context.Context, reader client.Reader,
return err
}

if err := networkSpec.PeeredNetworkRef.ConvertToProjectNumber(ctx, a.projectClient); err != nil {
if err := networkSpec.PeeredNetworkRef.ConvertToProjectNumber(ctx, a.projectMapper); err != nil {
return err
}
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/controller/kccmanager/kccmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ func New(ctx context.Context, restConfig *rest.Config, cfg Config) (manager.Mana
UserAgent: gcp.KCCUserAgent,
}

if err := controllerConfig.Init(ctx); err != nil {
return nil, err
}

// Initialize direct controllers
if err := registry.Init(ctx, controllerConfig); err != nil {
return nil, err
Expand Down

0 comments on commit 561ba16

Please sign in to comment.