Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ExternalReference (selfLink) with GCP update/deletion uniqueness guardrail #2020

Merged
merged 1 commit into from
Jun 18, 2024

Conversation

yuwenma
Copy link
Collaborator

@yuwenma yuwenma commented Jun 17, 2024

Follow up PR to resolve comment in #1920 (comment)

)

func NewResourceRef(gcpObj *cloudbuildpb.WorkerPool) *ResourceRef {
return &ResourceRef{
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This CBWP ResourceRef customize the common ResourceRef, mostly to provide dedicated user information.

return setStatus(u, status)
}

func (a *Adapter) Update(ctx context.Context, u *unstructured.Unstructured) error {
if err := a.ValidateExternalResource(); err != nil {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not allow user to update the spec.resourceID spec.projectRef or spec.location to a different value (which means a different GCP object).

Ideally we can move this to the directbase_controller. (or we already have this check somewhere?)

pkg/controller/direct/externalresource/resource.go Outdated Show resolved Hide resolved

func NewResourceRef(gcpObj *cloudbuildpb.WorkerPool) *ResourceRef {
return &ResourceRef{
externalresource.New("https://cloudbuild.googleapis.com/v1/", gcpObj),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I don't know if we want v1. Although I guess it depends on whether in OnePlatform a v1 and v2 with the same name would be the same resource.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean. I think we need to specify a version in the URL anyways to make it valid. Maybe I'm wrong, but does the v1/v2 bundles in the godoc.org/cloud.google.com/go?

}

func (e *ResourceRef) GetResourceID() string {
segments := strings.Split(*e.Get(), "/workerPools/")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two nits:

  1. Dereferencing pointers is always scary (because it panics on nil), better to use a helper like ValueOf
  2. I think you should also check that segments actually has len != 0.

It might be the fluent way to do this is to move the parsing to NewResourceRef (which can then return an error)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! The code looks much nicer now.

@@ -283,6 +287,8 @@ func (a *Adapter) Update(ctx context.Context, u *unstructured.Unstructured) erro
}
status.ObservedState.CreateTime = ToOpenAPIDateTime(updated.GetCreateTime())
status.ObservedState.UpdateTime = ToOpenAPIDateTime(updated.GetUpdateTime())
// This value should not be updated. Just in case.
status.ExternalRef = NewResourceRef(updated).Get()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to write a quick design-doc for "status.externalRef" including "why is it not status.selfLink", how it fixes resource deletion etc

@@ -313,6 +320,38 @@ func (a *Adapter) Delete(ctx context.Context) (bool, error) {
return true, nil
}

// ValidateExternalResource compares the `status.externalRef` with the `spec` Project, Location and
// (external) resourceID to make sure those fields are immutable and matches the previous deployed value.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oooh cool - another advantage!

return fmt.Errorf("`spec.location` is immutable field, expect %s, got %s",
actualExternalRef.GetLocation(), a.desired.Spec.Location)
}
// TODO: Some Selflink may change the project from projectID to projectNum.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also won't be able to check e.g. references like containerRef on a NodePool.

This method seems cool, but it might be overkill - at least for now?

existsAlready, err := adapter.Find(ctx)
if err != nil {
if unwrappedErr, ok := lifecyclehandler.CausedByUnresolvableDeps(err); ok {
logger.Info(unwrappedErr.Error(), "resource", k8s.GetNamespacedName(u))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One gotcha is that if we're deleting we likely don't need the spec refs, we just need status.externalRef.

I guess we can tackle this later (as part of cleaning up resource cleanup)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, right! Yes I like that.
I added a todo and would like to do that in a follow up PR, since that requires some refactoring of the fullyQualifiedName method.

pkg/controller/direct/externalresource/resource.go Outdated Show resolved Hide resolved
@@ -30,6 +30,7 @@ status:
reason: UpToDate
status: "True"
type: Ready
externalRef: https://cloudbuild.googleapis.com/v1/projects/${projectId}/locations/us-central1/workerPools/cloudbuildworkerpool-${uniqueId}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing this here, I like this!

@justinsb
Copy link
Collaborator

You have some conflicts, but...

/approve
/lgtm

@justinsb
Copy link
Collaborator

Thanks - looks great!

/approve
/lgtm

@google-oss-prow google-oss-prow bot added the lgtm label Jun 18, 2024
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: justinsb

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@google-oss-prow google-oss-prow bot merged commit aa7eb04 into GoogleCloudPlatform:master Jun 18, 2024
14 checks passed
@yuwenma yuwenma added this to the 1.120 milestone Jun 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants