-
Notifications
You must be signed in to change notification settings - Fork 237
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: A new parent interface #3234
feat: A new parent interface #3234
Conversation
|
||
var _ Parent = &ProjectAndLocationParent{} | ||
|
||
type ProjectAndLocationParent struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can merge ProjectAndLocationParent
and ProjectAndLocationRef
, it makes this file shorter. But it adds additional complexity to the controller on error handling, and the order of the function calls to set the external
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want Foo, FooRef and FooIdentity. I think this is FooIdentity, and ProjectAndLocationRef is FooRef
08992fd
to
816f435
Compare
} | ||
if location != actualLocation { | ||
return nil, fmt.Errorf("spec.location changed, expect %s, got %s", location, actualLocation) | ||
if err := desiredParent.MatchActual(actualParent); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest just comparing String()
of the ID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This MatchActual
is more for KCC users.
My main concern about comparing String
is that it cannot give users enough information to help them fix their bad config.
For example, the parent is build from spec.ProjectRef.External
and spec.Location
(for some other resources it may also have spec. FooRef.External
spec.BarRef.External
), it is unclear for users to know which field is misconfigured by just seeing something likeexpected format projects/<projectID>/location/<lcoation>, got ....
One improvements we can do is spec.parent.projectRef
(I think we discussed this as well, but we have to make the API backward compatible)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I think I would make the message "Can't change object identity; existing identity is %q, new identity is %q" so it would be pretty easy to figure out what has changed, but ... I can send a PR on top of this - let's get this in!
@@ -88,36 +87,13 @@ type BigQueryConnectionConnectionRef struct { | |||
Namespace string `json:"namespace,omitempty"` | |||
} | |||
|
|||
func parseExternal(external string) (string, string, string, error) { | |||
func ParseConnectionExternal(external string) (*parent.ProjectAndLocationParent, string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest this should return (*ConnectionIdentity,error)
(and not the parent split out)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! (It used to be handy to split them because we don't have the identity. 😄 )
// BigQueryConnectionConnectionSpec defines the desired state to connect BigQuery to external resources | ||
// +kcc:proto=google.cloud.bigquery.connection.v1.Connection | ||
type BigQueryConnectionConnectionSpec struct { | ||
Parent `json:",inline"` | ||
*parent.ProjectAndLocationRef `json:",inline"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought you wanted to embed ConnectionIdentity
here instead
// ParentBuilder builds a Parent object from a ParentRef. | ||
// - ParentRef is the Config Connector API reference for identifying a resource's logical parent. | ||
// - The Parent object provides helper functions for parent-related logic in direct reconciliation. | ||
type ParentBuilder interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the krm object should implement ResolveIdentity(ctx context.Context, reader client.Reader) (Identity, error)
If we want Identity to be typed, it would have to be something like this:
type ObjectWithIdentity[T] interface {
ResolveIdentity(ctx contetx.Context, reader client.Reader) (*T, error)
}
// Builds a the ProjectParent from ProjectRef. | ||
// If `projectRef.external` is given, parse projectID from External, otherwise find the ConfigConnector project | ||
// according to `projectRef.name` and `projectRef.namespace`. | ||
func (p *ProjectRef) Build(ctx context.Context, reader client.Reader, othernamespace string, parent Parent) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect we don't need this function. We need a function that resolves a ProjectRef to a ProjectIdentity, and ProjectIdentity should have a function that can return the ProjectID. It might be rename this function to map from ProjectRef -> ProjectIdentity.
We would have 3 concepts: Foo, FooRef and FooIdentity
FooIdentity is essentially the fully-qualified name, I don't know if we should name it FooLink or something like that instead, but I do think that just using these 3 concepts will simplify our code a lot.
@@ -293,10 +289,6 @@ spec: | |||
description: The `projectID` field of a project, when not managed | |||
by Config Connector. | |||
type: string | |||
kind: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly we can't do this, this is a breaking API change. We can't break resources that specify kind
, even though we (I) introduced it by mistake.
@@ -76,7 +75,7 @@ func (m *model) AdapterForObject(ctx context.Context, reader client.Reader, u *u | |||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &obj); err != nil { | |||
return nil, fmt.Errorf("error converting to %T: %w", obj, err) | |||
} | |||
connectionRef, err := krm.NewBigQueryConnectionConnectionRef(ctx, reader, obj) | |||
connectionIdentity, err := krm.NewConnectionIdentity(ctx, reader, obj) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the one where maybe we could call obj.ResolveIdentity
... maybe :-)
req := &pb.CreateConnectionRequest{ | ||
Parent: parent, | ||
Parent: a.id.Parent.String(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this approach, but one thing we will have to be careful of is that we have a "partial ID" here, ResourceID is empty, the parent fields are set. There are going to be bugs because of this.
It might be easier to resolve the parent directly here, perhaps with a method on the embedded ProjectAndLocationID in BigQueryConnectionID
@@ -243,14 +223,14 @@ func (a *Adapter) Create(ctx context.Context, createOp *directbase.CreateOperati | |||
return mapCtx.Err() | |||
} | |||
|
|||
tokens := strings.Split(created.Name, "/") | |||
parent, err = a.id.Parent() | |||
_, name, err := krm.ParseConnectionExternal(created.Name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at this, I think it would read well if it was a method on BigQueryConnectionID, like this:
name := &BigQueryConnectionID{}
if err := name.ParseSelfLink(created.Name); err != nil {
....
} | ||
obj.Spec.ResourceID = &id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we embed ID into Spec, I think these three lines will just be obj.Spec.ID = id
} | ||
if location != actualLocation { | ||
return nil, fmt.Errorf("spec.location changed, expect %s, got %s", location, actualLocation) | ||
if err := desiredParent.MatchActual(actualParent); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I think I would make the message "Can't change object identity; existing identity is %q, new identity is %q" so it would be pretty easy to figure out what has changed, but ... I can send a PR on top of this - let's get this in!
return nil, fmt.Errorf("cannot resolve project") | ||
} | ||
// Get location | ||
location := obj.Spec.Location | ||
|
||
// Get desired connection ID from spec | ||
desiredID := direct.ValueOf(obj.Spec.ResourceID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to fallback to name here?
So I think two blockers, and everything else we can tackle in follow-up PRs:
|
816f435
to
cfa3a8d
Compare
I reverted the changes to BQCC. So this PR only contains the interface and the implemented |
cfa3a8d
to
a0937fe
Compare
/approve |
a0937fe
to
9075f8a
Compare
9075f8a
to
1a3b58c
Compare
1a3b58c
to
257a0e5
Compare
[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 |
d192546
into
GoogleCloudPlatform:master
Change description
Fixes #
Tests you have done
make ready-pr
to ensure this PR is ready for review.