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

Initial commit for handling multiple secrets #241

Merged

Conversation

davidvonthenen
Copy link
Contributor

@davidvonthenen davidvonthenen commented Aug 26, 2019

What this PR does / why we need it:
This PR implements the following issue (#233) and a bonus feature! 😀

This allows each [VirtualCenter] to have their own dedicated Secret containing VC credentials (username/password). By having a dedicated Secret, each [VirtualCenter] will be isolated from accessing each other's Secret when said Secret is placed into their own namespace. Maybe an example vsphere.conf might be helpful...

[Global]
# properties in this section will be used for all specified vCenters unless overriden in VirtualCenter section.
port = "443" #Optional
insecure-flag = "1" #set to 1 if the vCenter uses a self-signed cert

[VirtualCenter "10.160.140.218"]
datacenters = "vicdc"
secret-name = "vccm-europe-secret"
secret-namespace = "kube-system"
# port, insecure-flag will be used from Global section.

[VirtualCenter "10.161.60.78"]
datacenters = "vic0dc,vic1dc"
secret-name = "vccm-us-secret"
secret-namespace = "kube-system"
# port, insecure-flag will be used from Global section.

[Labels]
region = k8s-region
zone = k8s-zone

The "bonus" feature is something I am calling TenantRefs. Prior to this PR, a single [VirtualCenter] was constrained to have either all or a subset of Datacenters contribute to the k8s cluster. Those DCs that weren't contributing to the cluster, couldn't have a different configuration because the [VirtualCenter] "key" was the ip/fqdn of that vCenter Server. A TenantRefs is set by defining the server field under the [VirtualCenter] section. If that server field is set, it is assumed that the value in [VirtualCenter "value"] is the TenantRef. By implementing TenantRefs, this allows the potential for each VC/DC to have its own unique configuration based on the access controls of a given set of creds. So what does this feature translate into in English? Think of this as possibly enabling multi-tenancy. Maybe an example configuration might help...

[Global]
# properties in this section will be used for all specified vCenters unless overriden in VirtualCenter section.
port = "443" #Optional
insecure-flag = "1" #set to 1 if the vCenter uses a self-signed cert

[VirtualCenter "us-west-tenant1"]
server = "10.160.140.218"
datacenters = "tenant1"
secret-name = "vccm-tenant1-secret"
secret-namespace = "tenant1"
# port, insecure-flag will be used from Global section.

[VirtualCenter "us-east-tenant2"]
server = "10.161.60.78"
datacenters = "tenant2"
secret-name = "vccm-tenant2-secret"
secret-namespace = "tenant2"
# port, insecure-flag will be used from Global section.

[VirtualCenter "us-east-tenant3"]
server = "10.161.60.78"
datacenters = "us-east"
secret-name = "vccm-tenant3-secret"
secret-namespace = "tenant3"
# port, insecure-flag will be used from Global section.

[VirtualCenter "us-east-tenant4"]
server = "10.161.60.78"
datacenters = "us-east"
secret-name = "vccm-tenant4-secret"
secret-namespace = "tenant4"
# port, insecure-flag will be used from Global section.

[Labels]
region = k8s-region
zone = k8s-zone

Some things to note based on the example configuration above:

  • the defined TenantRefs starting from the top of the config file to the bottom are: us-west-tenant1, us-east-tenant2, us-east-tenant3, and us-east-tenant4. TenantRefs must be unique!
  • each tenant has their own secret which means each tenant has their own vSphere user account
  • tenant3 and tenant4 are sharing a given DC. the resources each tenant is using can be assigned based on the vSphere user account (maybe each account has their own ResourcePool or ComputeCluster)
  • tenant2 has its own dedicated DC but sharing the same VC as tenant3 and 4
  • tenant1 has their own VC (and subsequently their own DC)

Here is an example vsphere.conf based on what I actually tested:

[Global]
# properties in this section will be used for all specified vCenters unless overridden in VirtualCenter section.
port = "443" #Optional
insecure-flag = "1" #set to 1 if the vCenter uses a self-signed cert

[VirtualCenter "europe"]
server = "10.160.140.218"
datacenters = "vicdc"
secret-name = "vccm-europe-secret"
secret-namespace = "kube-system"
# port, insecure-flag will be used from Global section.

[VirtualCenter "us-west"]
server = "10.161.60.78"
datacenters = "vic0dc"
secret-name = "vccm-us-west-secret"
secret-namespace = "kube-system"
# port, insecure-flag will be used from Global section.

[VirtualCenter "us-east"]
serever = "10.161.60.78"
datacenters = "vic1dc"
secret-name = "vccm-us-east-secret"
secret-namespace = "kube-system"
# port, insecure-flag will be used from Global section.

[Labels]
region = k8s-region
zone = k8s-zone

Other minor changes along for the ride in this PR:

  • cleaned up some functions in the Config package. it made more sense to make them member functions of the Config instead of passing the Config into the function
  • the old Connect(vcServer string) in ConnectionManager is no longer sufficient to determine which VirtualCenterConfig is being referenced and since there is only one method for Connect() now, I renamed ConnectByInstance() to Connect(). Example of ambiguity in old Connect(vcServer string):
[VirtualCenter "10.161.60.78"]
datacenters = "vic0dc"
...

[VirtualCenter "10.161.60.78"]
datacenters = "vic1dc"
...
  • Moved a number of consts and user-defined errors into their own go file. Adding more just started to make the go files with business logic larger in length (ie it's easier to manage this way and a number of package already do this).
  • Removed the function removePortFromHost() because URL.Hostname() exists and returns the Hostname minus the port.
  • Renamed SecretCredentialManager to CredentialManager because it actually does handle Creds from the Config as well. So the name should accurately reflect what it actually manages... ie all credentials.

Which issue this PR fixes: #233

Special notes for your reviewer:
Tested on vSphere 6.7u2
Test cases included:

  • Using the backward compatible (aka Config format before this feature was introduced) with a single global secret
  • Using the new TenantRefs with each their own dedicated Secret. In my test configuration, that's 3 Datacenters mapping to 3 [VirtualCenter] with 3 secrets.
  • Using a hybrid of the previous two test cases. In other words, each [VirtualCenter] has their own TenantRef, 2 of the 3 [VirtualCenter] had their own dedicated Secret, and the 3rd [VirtualCenter] used the "global" Secret. This is a complicated use case which I am sure no one will use... the point in testing this just means I have confidence everything is working fine. 🙂

Since this feature is a pretty significant change and because the default/current/backward-compatible vsphere.conf file format still works, I am going to do the documentation in a separate PR. This is mainly due to the fact that this will impact CSI and I would like to start the integration of this feature into CSI before the new CNS based implementation PR start making their way over and I lose the ability to accurately test this feature on CSI.

Release note:
Default/current/backward-compatible vsphere.conf still works!

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Aug 26, 2019
@k8s-ci-robot k8s-ci-robot requested review from dougm and imkin August 26, 2019 21:08
@davidvonthenen
Copy link
Contributor Author

davidvonthenen commented Aug 26, 2019

Oops... my last couple of commits broke the go test and fix some lint/vet/fmt issues. I just need to update the simulated vsphere.conf files.

@davidvonthenen davidvonthenen changed the title Initial commit for handling multiple service accounts/secrets [WIP] Initial commit for handling multiple service accounts/secrets Aug 26, 2019
@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 26, 2019
@davidvonthenen davidvonthenen force-pushed the feature/individualsvcaccts branch 3 times, most recently from 823f03a to e0796a7 Compare August 26, 2019 21:50
@davidvonthenen davidvonthenen changed the title [WIP] Initial commit for handling multiple service accounts/secrets Initial commit for handling multiple service accounts/secrets Aug 26, 2019
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 26, 2019
@davidvonthenen
Copy link
Contributor Author

Fixed simulated vsphere.conf which corrected the go test and fixed lint/vet/fmt issues. This PR is ready for review.

CC: @frapposelli @andrewsykim @codenrhoden

@davidvonthenen davidvonthenen force-pushed the feature/individualsvcaccts branch 2 times, most recently from 44a8311 to fabb1af Compare August 27, 2019 02:19
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Aug 27, 2019
@andrewsykim
Copy link
Member

So the ServiceAccounts are to ensure the CCM can't accidentally modify a VM belonging to another VC but only if the secrets are stored in separate namespaces?

@davidvonthenen
Copy link
Contributor Author

davidvonthenen commented Aug 27, 2019

So the ServiceAccounts are to ensure the CCM can't accidentally modify a VM belonging to another VC but only if the secrets are stored in separate namespaces?

That really depends on how you set everything up. I could see a few different ways of how you architect everything. The CPI's vCenter accounts should only need to be read-only (need to think about that a little more 🤔to be sure). CSI, on the other hand, is probably where the real benefit sits because it needs to have create/modify access for datastores, volumes and VMs.

The service accounts are a method to restrict access to k8s secrets. The VC credentials within those secrets are what actually prevents modification of VMs by reducing scope and access/permissions of what that VC user cred can see/modify/delete on a given vCenter Server. Hope that makes sense.

Still... even the reduced scope for the CPI even using read-only vCenter Server user creds will have significant security benefits. Viewing inventory you shouldn't see is still no bueno.

Copy link
Contributor

@codenrhoden codenrhoden left a comment

Choose a reason for hiding this comment

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

I added comments where I felt like I saw something. :) But I don't really know enough about this code to use "Request Changes" and feel like you have to.

pkg/common/config/config.go Outdated Show resolved Hide resolved
pkg/common/config/config.go Outdated Show resolved Hide resolved
pkg/common/config/config.go Outdated Show resolved Hide resolved
pkg/common/config/consts_and_errors.go Outdated Show resolved Hide resolved
pkg/common/config/virtualcenterconfig.go Outdated Show resolved Hide resolved
pkg/common/connectionmanager/connectionmanager.go Outdated Show resolved Hide resolved
pkg/common/connectionmanager/consts_and_errors.go Outdated Show resolved Hide resolved
pkg/common/credentialmanager/consts_and_errors.go Outdated Show resolved Hide resolved
Copy link
Member

@andrewsykim andrewsykim left a comment

Choose a reason for hiding this comment

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

So maybe I'm missing something still. I’m confused because the default ClusterRole we use for CPI can read secrets from all namespaces, so specifying the SA doesn’t really add additional isolation but it does make the install/configure steps more complicated. Is the intention to remove access to secrets in the cloud-controller-manager role and require SAs (w/ Role + RoleBinding) per VC?

pkg/common/config/types.go Outdated Show resolved Hide resolved
@davidvonthenen
Copy link
Contributor Author

So maybe I'm missing something still. I’m confused because the default ClusterRole we use for CPI can read secrets from all namespaces, so specifying the SA doesn’t really add additional isolation but it does make the install/configure steps more complicated. Is the intention to remove access to secrets in the cloud-controller-manager role and require SAs (w/ Role + RoleBinding) per VC?

Yup, that's the exact intention. I just added a note that the default cloud-controller-manager-roles.yaml needs to be changed to in the PR. It should also be noted that we will still need the cloud-controller-manager role because that "default" service account is used for listening for the NodeManager for adds/removes/updates to nodes.

@k8s-ci-robot k8s-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Aug 28, 2019
@davidvonthenen davidvonthenen force-pushed the feature/individualsvcaccts branch from 61fcc6c to 654b2d5 Compare August 28, 2019 16:31
@davidvonthenen
Copy link
Contributor Author

Updated based feedback from @andrewsykim and updated the description (comment #1) of the PR for consistency.

The good news is by changing how we enable ConnectionLabels from what was first implemented, it's made the code much simpler. The short version of this change is you enable the ConnectionLabel by defining the server field under the [VirtualCenter] section. When server which contains the ip/fqdn of the vCenter Server is set, the value in [VirtualCenter "value"] is the ConnectionLabel. Check the updated description for config examples. The logic now is 💯

Thanks @andrewsykim !!

@davidvonthenen
Copy link
Contributor Author

/hold

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 29, 2019
@davidvonthenen
Copy link
Contributor Author

/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 29, 2019
@davidvonthenen
Copy link
Contributor Author

Yup, we are good to go!

@codenrhoden
Copy link
Contributor

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 29, 2019
Copy link
Member

@andrewsykim andrewsykim left a comment

Choose a reason for hiding this comment

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

Overall LGTM, left a few more minor comments

pkg/common/config/config.go Outdated Show resolved Hide resolved
pkg/common/config/types.go Outdated Show resolved Hide resolved
pkg/common/config/types.go Outdated Show resolved Hide resolved
pkg/common/config/types.go Outdated Show resolved Hide resolved
pkg/common/config/types.go Outdated Show resolved Hide resolved
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 30, 2019
@davidvonthenen davidvonthenen force-pushed the feature/individualsvcaccts branch 2 times, most recently from 4474859 to eb639aa Compare August 30, 2019 14:00
Copy link
Member

@andrewsykim andrewsykim left a comment

Choose a reason for hiding this comment

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

/approve
/hold

LGTM, remaining comments non-blocking, holding in-case you want to address them

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 30, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: andrewsykim

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

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 30, 2019
@davidvonthenen davidvonthenen force-pushed the feature/individualsvcaccts branch from 2585a90 to f98e4bc Compare August 30, 2019 15:38
Improvement to use ConnectionLabels

Update with bug fixes

Fix bug with global lister

Fix for ConnectionLabel in config

Fix lint, vet, and etc

Fix the rename of the variable

Fix go test

Remove klog InitFlags from go test

Removed commented out code

Revert YAML to remove arg0

Updates based on the Travis' feedback

Updated test

Update validate func

Remove because no longer needed

Made global lock a member variable

Remove service account logic

Update based on AK feedback

Update based on AK feedback

Update based on feedback

Fix go test

Update go test for TestConnectionLabels

Rename ConnectionLabel to TenantRef
@davidvonthenen davidvonthenen force-pushed the feature/individualsvcaccts branch from a351a04 to 3c937e4 Compare August 30, 2019 17:04
@andrewsykim
Copy link
Member

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 30, 2019
@davidvonthenen
Copy link
Contributor Author

/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 30, 2019
@k8s-ci-robot k8s-ci-robot merged commit 180a0a9 into kubernetes:master Aug 30, 2019
@davidvonthenen davidvonthenen deleted the feature/individualsvcaccts branch August 30, 2019 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants