-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Creating the keyset.yaml file if it does not exist #4582
Creating the keyset.yaml file if it does not exist #4582
Conversation
02f3111
to
3e03bd6
Compare
3a4536f
to
3809385
Compare
/assign @blakebarnett @mikesplain |
Apparently this results in a new private key being generated for the CA? This would require us to rotate every cert we've created using the CA (a large number), if there's any way to make it re-use the existing private key that would be very preferable. cc: @justinsb |
@blakebarnett I am not certain that a new private cert is being generated or we are creating two private certs with a keyset.yaml. @justinsb any ideas? |
upup/pkg/fi/fitasks/keypair.go
Outdated
} else { | ||
glog.Warningf("Ignoring changes in key: %v", fi.DebugAsJsonString(changes)) | ||
} | ||
} | ||
|
||
// TODO: I am wondering if we reuse the certificate information when a.KeysetAPIVersion == "" rather than | ||
// TODO: issuing the new cert |
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 am seeing two private pems in the keypair.yaml file. Any idea how we can re-use the pem?
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 that we are eventually calling https://github.com/kubernetes/kops/blob/master/pkg/pki/csr.go#L94
And that is creating the new cert.
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.
Line 94 in 0b0932b
certificateData, err := x509.CreateCertificate(crypto_rand.Reader, template, parent, template.PublicKey, signerPrivateKey.Key) |
upup/pkg/fi/fitasks/keypair.go
Outdated
} else if a.KeypairType == "" { | ||
// The a.KeysetAPIVersion will == "" when the keyset is a legacy keyset and does not have a keypair.yaml | ||
// file store in the state store | ||
createCertificate = true |
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.
Why are you setting createCertificate here?
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 can test without it, but I think my testing did not create the keypair.yaml.
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.
As we discussed, pretty sure this shouldn't drive creation of a new certificate, but should instead drive a new UpdateStoredVersion
or similar call
pkg/model/pki.go
Outdated
@@ -34,6 +34,9 @@ type PKIModelBuilder struct { | |||
|
|||
var _ fi.ModelBuilder = &PKIModelBuilder{} | |||
|
|||
// keypairType is used to differentiate the old secretes with the newer versions |
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.
typo: secretes
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 need the spelling tool
pkg/model/pki.go
Outdated
@@ -34,6 +34,9 @@ type PKIModelBuilder struct { | |||
|
|||
var _ fi.ModelBuilder = &PKIModelBuilder{} | |||
|
|||
// keypairType is used to differentiate the old secretes with the newer versions | |||
const keypairType = "Keypair" |
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.
What is the other type? Maybe we have a field "Format" or "APIVersion", and we have "legacy" & "kops/v1alpha2" as that most closely matches what we're actually doing, I think.
Although the obvious problem with this is that I don't know how easy it is to get the stored version from the apimachinery. But I'm OK with cheating at the moment (assuming v1alpha2)
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 was the only thing in the API object that I could find that was actually set. I tested the heck out of this, and the only thing I could figure out how to access is the object name Keypair.
upup/pkg/fi/fitasks/keypair.go
Outdated
@@ -51,6 +51,9 @@ type Keypair struct { | |||
Subject string `json:"subject"` | |||
// Type the type of certificate i.e. CA, server, client etc | |||
Type string `json:"type"` | |||
// KeypairType stores the api version of kops.Keyset. We are storing this info in order to determine if kops | |||
// is accessing legacy secrets that do not use keyset.yaml. | |||
KeypairType string `json:"keypairType"` |
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 would call it APIVersion or Format. And then I'd say "This lets us convert the stored keypair to our preferred version." I don't think we should say "We are storing this info" because we're not storing it - tasks are ephemeral
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 ... renaming
upup/pkg/fi/ca.go
Outdated
@@ -44,7 +44,7 @@ type KeystoreItem struct { | |||
type Keystore interface { | |||
// FindKeypair finds a cert & private key, returning nil where either is not found | |||
// (if the certificate is found but not keypair, that is not an error: only the cert will be returned) | |||
FindKeypair(name string) (*pki.Certificate, *pki.PrivateKey, error) | |||
FindKeypair(name string) (*pki.Certificate, *pki.PrivateKey, 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.
I'm a little worried that we might need a version for both cert & privatekey, but we'll see...
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 your test is not working ... see your PR for comments.
upup/pkg/fi/fitasks/keypair.go
Outdated
} else if a.KeypairType == "" { | ||
// The a.KeysetAPIVersion will == "" when the keyset is a legacy keyset and does not have a keypair.yaml | ||
// file store in the state store | ||
createCertificate = true |
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.
As we discussed, pretty sure this shouldn't drive creation of a new certificate, but should instead drive a new UpdateStoredVersion
or similar call
upup/pkg/fi/k8sapi/k8s_keystore.go
Outdated
} | ||
|
||
return keypair.Certificate, keypair.PrivateKey, nil | ||
// TODO: KubernetesKeystore does not seem to be using the newer version of keypairs. |
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.
Not sure what you mean. keyset.yaml doesn't make sense here - keyset.yaml makes a filesystem behave more like an API server. So we don't need keyset.yaml for an API-server-backed key store.
@@ -233,27 +233,27 @@ func (c *VFSCAStore) parseKeysetYaml(data []byte) (*kops.Keyset, error) { | |||
// loadCertificatesBundle loads a keyset from the path | |||
// Returns (nil, nil) if the file is not found | |||
// Bundles avoid the need for a list-files permission, which can be tricky on e.g. GCE | |||
func (c *VFSCAStore) loadKeysetBundle(p vfs.Path) (*keyset, error) { | |||
func (c *VFSCAStore) loadKeysetBundle(p vfs.Path) (*keyset, 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.
You could put the stored version into the (internal) keyset type - should be simpler
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.
need more context
3809385
to
903b153
Compare
tests/keypair_test.go
Outdated
// memfs://keystore/private/ca/keyset.yaml | ||
// memfs://keystore/private/kubelet/2.key | ||
// memfs://keystore/private/kubelet/4.key | ||
// memfs://keystore/private/kubelet/keyset.yaml |
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.
Test is failing and this is what I am getting :(
f882a0d
to
7740ec3
Compare
upup/pkg/fi/fitasks/keypair.go
Outdated
} else if changes.Type != "" { | ||
createCertificate = true | ||
glog.V(8).Infof("creating certificate new Type") | ||
} else { | ||
glog.Warningf("Ignoring changes in key: %v", fi.DebugAsJsonString(changes)) |
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.
@chrislovecnm As per our out-of-band convo, can we suppress this during an upgrade?
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.
Done
I've run through a couple tests that create a cluster with kops 1.8, then use this patch to upgrade the cluster. keyset.yaml is being created correctly. |
7740ec3
to
2b9afa4
Compare
/assign @robinpercy PTAL |
/hold |
c0f1193
to
6939861
Compare
6939861
to
e719d56
Compare
Creating the keypair.yaml file if it does not exist. If the Keypair is not found kops creates a new keyset file. We are setting the Keyset Task Format to 'Keypair', which denotes that we do not have a keypair.yaml file. This commit enables upgrading from kops 1.8 -> 1.9 while upgrading an existing cluster. Clusters built with kops 1.8 do not have the keypair file, and these code changes allow the creation of that file.
e719d56
to
c13b952
Compare
I have refactored some, and added a bunch of code level documentation. Both @robinpercy and I have tested and the upgrades are working well :) When you upgrade to kops 1.9 from kops 1.8 and update and existing cluster built with kops 1.8 the new keypair.yaml files are created. |
/lgtm |
ae759ce
to
f785d2b
Compare
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: chrislovecnm, justinsb, robinpercy 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 |
/hold cancel |
If the Keypair is not found kops creates a new keyset file. We are
setting the Format to v1, which denotes that we do not have a keyset
file.
This commit enables upgrading from kops 1.8 -> 1.9 while upgrading an
existing cluster. Clusters built with kops 1.8 do not have the keyset
file, and these code changes allow the creation of the keyset file.
Fixes: #4546
The only thing I do not like about this fix is that we are generating a new private key. Not a horrible thing, but not sure how stuff like etcd will behave.Edit: with changes I am not generating a new private key.