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

Migrate platform reference to Upbound official providers #22

Merged
merged 1 commit into from Sep 27, 2022

Conversation

ytsarev
Copy link
Member

@ytsarev ytsarev commented Sep 16, 2022

Description of your changes

  • Migrate to official provider-gcp
  • Include CompositeNetwork XR within the Cluster Composition in a consistent manner similar to aws and azure platform-refs
  • Comply with new GKE authentication requirements and extend abstractions with googleApplicationCredentialsSecret

I have:

  • Read and followed Upbound's contribution process.
  • Run make reviewable to ensure this PR is ready for review.
  • Added backport release-x.y labels to auto-backport this PR, as appropriate.

How has this code been tested

kubectl apply -f examples/cluster.yaml
k get managed
NAME                                                              CHART                   VERSION   SYNCED   READY   STATE      REVISION   DESCRIPTION        AGE
release.helm.crossplane.io/platform-ref-gcp-cluster-jvl4j-nb5fw   kube-prometheus-stack   34.5.1    True     True    deployed   1          Install complete   27m

NAME                                                                     READY   SYNCED   EXTERNAL-NAME                                                                                                                       AGE
projectiammember.cloudplatform.gcp.upbound.io/platform-ref-gcp-cluster   True    True     crossplane-playground/roles/container.admin/serviceAccount:platform-ref-gcp-cluster@crossplane-playground.iam.gserviceaccount.com   27m

NAME                                                                   READY   SYNCED   EXTERNAL-NAME              AGE
serviceaccount.cloudplatform.gcp.upbound.io/platform-ref-gcp-cluster   True    True     platform-ref-gcp-cluster   27m

NAME                                                                      READY   SYNCED   EXTERNAL-NAME                                                                                                                                                         AGE
serviceaccountkey.cloudplatform.gcp.upbound.io/platform-ref-gcp-cluster   True    True     projects/crossplane-playground/serviceAccounts/platform-ref-gcp-cluster@crossplane-playground.iam.gserviceaccount.com/keys/62cc39a87cca9bef38028f05bcd4614071461e12   27m

NAME                                                                     READY   SYNCED   EXTERNAL-NAME                          AGE
subnetwork.compute.gcp.upbound.io/platform-ref-gcp-cluster-jvl4j-mlr4l   True    True     platform-ref-gcp-cluster-jvl4j-mlr4l   27m

NAME                                                                  READY   SYNCED   EXTERNAL-NAME                          AGE
network.compute.gcp.upbound.io/platform-ref-gcp-cluster-jvl4j-vznfl   True    True     platform-ref-gcp-cluster-jvl4j-vznfl   27m

NAME                                                                     READY   SYNCED   EXTERNAL-NAME                          AGE
nodepool.container.gcp.upbound.io/platform-ref-gcp-cluster-jvl4j-nbnns   True    True     platform-ref-gcp-cluster-jvl4j-nbnns   27m

NAME                                                                    READY   SYNCED   EXTERNAL-NAME                          AGE
cluster.container.gcp.upbound.io/platform-ref-gcp-cluster-jvl4j-9j7g6   True    True     platform-ref-gcp-cluster-jvl4j-9j7g6   27m
k get composite
NAME                                                                  READY   COMPOSITION                      AGE
gke.gcp.platformref.upbound.io/platform-ref-gcp-cluster-jvl4j-5wvrp   True    gke.gcp.platformref.upbound.io   29m

NAME                                                                               READY   COMPOSITION                                        AGE
compositenetwork.gcp.platformref.upbound.io/platform-ref-gcp-cluster-jvl4j-w5q75   True    gcp.compositenetworks.gcp.platformref.upbound.io   29m

NAME                                                                         READY   COMPOSITION                                        AGE
compositecluster.gcp.platformref.upbound.io/platform-ref-gcp-cluster-jvl4j   True    gke.compositeclusters.gcp.platformref.upbound.io   29m

NAME                                                                       READY   COMPOSITION                           AGE
services.gcp.platformref.upbound.io/platform-ref-gcp-cluster-jvl4j-sjnk8   True    services.gcp.platformref.upbound.io   29m

examples/network.yaml Outdated Show resolved Hide resolved
@@ -0,0 +1,8 @@
apiVersion: gcp.platformref.upbound.io/v1alpha1
Copy link

Choose a reason for hiding this comment

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

I'm torn between having this as an example given that Cluster already creates a network because I thought we needed to create both. Maybe have example of every definition or only Cluster would make it more clear?

Copy link
Member Author

Choose a reason for hiding this comment

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

following the strategy in ref-aws and ref-gcp, I renamed example file to network-xr.yaml and cluster-claim.yaml to reflect their kind

cluster/composition.yaml Show resolved Hide resolved
cluster/gke/definition.yaml Outdated Show resolved Hide resolved
required:
- nodes
- networkRef
- googleApplicationCredentialsSecret
Copy link

Choose a reason for hiding this comment

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

Suggested change
- googleApplicationCredentialsSecret
- googleApplicationCredentialsSecret
- compositeNetworkSelector

@@ -1,39 +1,28 @@
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: gke.gcp.platformref.crossplane.io
name: gke.gcp.platformref.upbound.io
Copy link

Choose a reason for hiding this comment

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

I started with a bare ServiceAccount to be used in my providerconfig and it turns out that a ServiceAccount is necessary for Cluster to create the default node pool. If it's not given under spec.nodeConfig[0].serviceAccount, it falls back to using default in the Google project. I realized this because my fresh service account didn't have permissions to use default service account.

'apply failed: googleapi: Error 400: The user does not have access to
      service account "283222062215-compute@developer.gserviceaccount.com". Ask a
      project owner to grant you the iam.serviceAccountUser role on the service account.

I think having a ServiceAccount in Composition and referencing it from both Cluster and NodePool objects would be a better experience.

Copy link
Member Author

Choose a reason for hiding this comment

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

Composition extended, things to note:

  • I had to add ServiceAccount management role to the account that is used for GCP provider credentials
  • Currently I hit
  Warning  CannotUpdateManagedResource      3m8s (x111 over 8m36s)  managed/container.gcp.upbound.io/v1beta1, kind=cluster  Operation cannot be fulfilled on clusters.container.gcp.upbound.io "platform-ref-gcp-cluster-fd76b-xbn5d": the object has been modified; please apply your changes to the latest version and try again

Maybe it is due

              nodeConfig:
                - serviceAccountSelector:
                    matchControllerRef: true

and similar to https://github.com/upbound/official-providers/issues/466#issuecomment-1253444978 , though the selector is part of the spec not a patch there, so I do not yet properly understand the root cause

@muvaf should we propagate ServiceAccount ID through XR status here?

Copy link

Choose a reason for hiding this comment

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

@ytsarev Yes, I'm afraid we need to patch through status. It's an array and core crossplane replaces the array item when you try to patch, hence it ends up having only matchControllerRef.

cluster/services/composition.yaml Show resolved Hide resolved
@ytsarev
Copy link
Member Author

ytsarev commented Sep 27, 2022

image

Everything works now.

Caveat: ServiceAccount associated with provider-gcp credentials has to be quite powerful to manage ServiceAccounts, ServiceAccountKeys and create ProjectIAMMember

crossplane.yaml Outdated
- provider: xpkg.upbound.io/upbound/provider-gcp
version: ">=v0.13.0-0"
- provider: xpkg.upbound.io/crossplane/provider-helm
version: ">=v0.10.0-0"
Copy link

Choose a reason for hiding this comment

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

Suggested change
version: ">=v0.10.0-0"
version: ">=v0.11.1-0"

Copy link
Member Author

Choose a reason for hiding this comment

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

@muvaf , thanks, updated!

During the configuration testing, I got v0.12.rc build installed. Is that expected?

 k get providers
NAME                       INSTALLED   HEALTHY   PACKAGE                                                            AGE
provider-aws               True        True      xpkg.upbound.io/upbound/provider-aws:v0.14.0                       5d15h
provider-gcp               True        True      xpkg.upbound.io/upbound/provider-gcp:v0.13.0                       16h
crossplane-provider-helm   True        True      xpkg.upbound.io/crossplane/provider-helm:v0.12.0-rc.0.5.gb368192   30s

Copy link

Choose a reason for hiding this comment

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

    - provider: xpkg.upbound.io/upbound/provider-gcp
      version: ">=v0.13.0"
    - provider: xpkg.upbound.io/crossplane/provider-helm
      version: ">=v0.11.1"

@hasheddan let me know that they shouldn't have the suffix, especially the provider-helm one since it publishes RC builds as well to the original repo as opposed to the big three official providers.

@ytsarev ytsarev requested a review from muvaf September 27, 2022 12:55
@ytsarev
Copy link
Member Author

ytsarev commented Sep 27, 2022

@muvaf @stevendborrelli this PR is ready for the test, Configuration is also installable via examples/configuration.yaml

apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
  name: platform-ref-gcp-staging
spec:
  package: xpkg.upbound.io/upbound/platform-ref-gcp-staging:v0.1.2
  packagePullSecrets:
    - name: package-pull-secret

Copy link

@muvaf muvaf left a comment

Choose a reason for hiding this comment

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

Tested it a couple of times. Everything works as expected. For some reason, the cluster goes into repairing state first during deletion which makes it take longer to delete but that's likely about GCP API. Thanks a lot @ytsarev !!

kind: ServiceAccount
patches:
- fromFieldPath: spec.id
toFieldPath: metadata.name
Copy link

Choose a reason for hiding this comment

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

Suggested change
toFieldPath: metadata.name
toFieldPath: metadata.annotations[crossplane.io/external-name]

This is a better way of naming resources in general so that Crossplane can take care of metadata.name, making sure there is no conflict.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, got it. I always had an opposite vector of name -> external-name in mind. That makes sense, will update

Comment on lines 48 to 49
- fromFieldPath: spec.id
toFieldPath: metadata.name
Copy link

Choose a reason for hiding this comment

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

Suggested change
- fromFieldPath: spec.id
toFieldPath: metadata.name

Seems like keys don't have names. Not patching it at all would be enough here to prevent conflicts I think.

@@ -14,8 +14,6 @@ spec:
services:
Copy link

Choose a reason for hiding this comment

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

I think using 1 as count would be faster to provision.

metadata:
name: platform-ref-gcp-staging
spec:
package: xpkg.upbound.io/upbound/platform-ref-gcp-staging:v0.1.2
Copy link

Choose a reason for hiding this comment

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

Don't forget to replace with the real repo before merging.

@donovanmuller
Copy link
Contributor

donovanmuller commented Sep 27, 2022

Tested it a couple of times. Everything works as expected. For some reason, the cluster goes into repairing state first during deletion which makes it take longer to delete but that's likely about GCP API. Thanks a lot @ytsarev !!

@muvaf I actually ran into something similar here as part of https://github.com/upbound/official-providers/pull/657, where if there are two node pools (default and additional NodePool) on creation, it causes this behaviour. See this related post.

@muvaf
Copy link

muvaf commented Sep 27, 2022

Test with latest state. The deletion succeeded, too.

NAME                                                              CHART                   VERSION   SYNCED   READY   STATE      REVISION   DESCRIPTION        AGE
release.helm.crossplane.io/platform-ref-gcp-cluster-4rdlm-mchl6   kube-prometheus-stack   34.5.1    True     True    deployed   1          Install complete   12m

NAME                                                                                 READY   SYNCED   EXTERNAL-NAME                                                                                                                       AGE
projectiammember.cloudplatform.gcp.upbound.io/platform-ref-gcp-cluster-4rdlm-xfqb8   True    True     crossplane-playground/roles/container.admin/serviceAccount:platform-ref-gcp-cluster@crossplane-playground.iam.gserviceaccount.com   12m

NAME                                                                               READY   SYNCED   EXTERNAL-NAME              AGE
serviceaccount.cloudplatform.gcp.upbound.io/platform-ref-gcp-cluster-4rdlm-mwz2d   True    True     platform-ref-gcp-cluster   12m

NAME                                                                                  READY   SYNCED   EXTERNAL-NAME                                                                                                                                                         AGE
serviceaccountkey.cloudplatform.gcp.upbound.io/platform-ref-gcp-cluster-4rdlm-5xb2p   True    True     projects/crossplane-playground/serviceAccounts/platform-ref-gcp-cluster@crossplane-playground.iam.gserviceaccount.com/keys/33ef64d7fd28e5c02fc3e609ae3d3ffedd96b0fe   12m

NAME                                                                  READY   SYNCED   EXTERNAL-NAME                          AGE
network.compute.gcp.upbound.io/platform-ref-gcp-cluster-4rdlm-7gcsm   True    True     platform-ref-gcp-cluster-4rdlm-7gcsm   12m

NAME                                                                     READY   SYNCED   EXTERNAL-NAME                          AGE
subnetwork.compute.gcp.upbound.io/platform-ref-gcp-cluster-4rdlm-btdwh   True    True     platform-ref-gcp-cluster-4rdlm-btdwh   12m

NAME                                                                     READY   SYNCED   EXTERNAL-NAME                          AGE
nodepool.container.gcp.upbound.io/platform-ref-gcp-cluster-4rdlm-2lj59   True    True     platform-ref-gcp-cluster-4rdlm-2lj59   12m

NAME                                                                    READY   SYNCED   EXTERNAL-NAME                          AGE
cluster.container.gcp.upbound.io/platform-ref-gcp-cluster-4rdlm-jcxbd   True    True     platform-ref-gcp-cluster-4rdlm-jcxbd   12m

Copy link
Member

@jbw976 jbw976 left a comment

Choose a reason for hiding this comment

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

Thanks for another quick but thorough investment into our major reference platforms @ytsarev!! 💪

A few questions to explore, but mostly looks good - an approval isn't far away 😂


Ensure that the following roles are added to your service account:

* `roles/compute.networkAdmin`
* `roles/container.admin`
* `roles/iam.serviceAccountUser`
* `roles/iam.securityAdmin`
Copy link
Member

Choose a reason for hiding this comment

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

what caused these extra roles/permissions to now be needed?

Copy link
Member Author

@ytsarev ytsarev Sep 27, 2022

Choose a reason for hiding this comment

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

@jbw976 it is required to create ProjectIAMMember

I mentioned here #22 (comment)

we need all that machinery to enable automated access in the form of

          identity:
            type: GoogleApplicationCredentials

for the helm ProviderConfig here

Copy link
Member

Choose a reason for hiding this comment

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

aha yes, thanks for clearing that up. So just to tie some loose ends together (for myself), this is the new approach for getting Auth to work with GKE clusters. This support was added to:

And that functionality generally address issues we've seen around this topic, like:

README.md Outdated Show resolved Hide resolved
Comment on lines 41 to 43
- fromFieldPath: spec.parameters.googleApplicationCredentialsSecret.name
- fromFieldPath: spec.parameters.googleApplicationCredentialsSecret.namespace
- fromFieldPath: spec.parameters.googleApplicationCredentialsSecret.key
Copy link
Member

Choose a reason for hiding this comment

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

what do these fromFieldPath patches without a to* destination do? where does the from data go to? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

@jbw976 without toFieldPath it is patching exactly the same destination as mentioned in fromFieldPath

But these patches are actually leftovers from the previous intermediate implementation so I remove them anyway, thanks for the catch!

@@ -0,0 +1,25 @@
apiVersion: apiextensions.crossplane.io/v1
Copy link
Member

Choose a reason for hiding this comment

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

this CompositeNetwork object is now consistently treated the same as the AWS and Azure platform refs?

We've historically had some problems here: When i first built reference platforms, I exposed the Networking as a claim, so app devs could create it on their own. That was a weird experience, because it's not something you'd expect app devs to have exposure to. Instead, the Networking should be created for them under the covers, alongside their cluster. Example issue: upbound/platform-ref-aws#25

We cleaned this up a bit in other reference platforms, but then I think GCP got updated in a different way, resulting in #21.

Would you say they are all consistent now, and #21 is fixed by this approach? 🙏

Copy link
Member Author

Choose a reason for hiding this comment

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

@jbw976 that's totally right, this PR makes network XR layout consistent with aws and azure refs:

  • Use Network XR from Cluster Composition
  • Do not provide Claim, just XR as example so it also appears in the Marketplace

Copy link
Member

@jbw976 jbw976 left a comment

Choose a reason for hiding this comment

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

Thanks for the quick responses and updates @ytsarev! giving my +1 LGTM now, is there anything else you were waiting on to merge? 🤔

@jbw976
Copy link
Member

jbw976 commented Sep 27, 2022

Do you want to squash the commit history a bit @ytsarev?

* Migrate all XRD and Compositions to OP
* Update package meta and examples
* Use compositeNetworkSelector with matchLabels propagation
* Add ServiceAccount creation within GKE Composition
* Add ServiceAccountKey for Helm ProviderConfig
* Reliably propagate ServiceAccount to Cluster and NodePool through XR status
* Create ProjectIAMMember association
* Update prometheus operator version to currently available one
* Strict versioning in meta config

Signed-off-by: Yury Tsarev <yury@upbound.io>
@ytsarev
Copy link
Member Author

ytsarev commented Sep 27, 2022

@jbw976 I've squashed the commits into one leaving only useful messages from the commit log. I've just updated the Configuration example to point to the semantical v0.1.0 version as we agreed with @muvaf .

The PR is good to merge, thank you so much for the thorough review, folks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants