mirror of https://github.com/kubernetes/kops.git
				
				
				
			Merge pull request #14867 from justinsb/keyset_can_return_nil
FindKeyset can return nil
This commit is contained in:
		
						commit
						940538e04c
					
				|  | @ -273,7 +273,7 @@ func (a *Addon) installPKI(ctx context.Context, k8sClient kubernetes.Interface, | |||
| 			a.Name, | ||||
| 		}, | ||||
| 	} | ||||
| 	cert, privateKey, _, err := pki.IssueCert(req, nil) | ||||
| 	cert, privateKey, _, err := pki.IssueCert(ctx, req, nil) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ limitations under the License. | |||
| package server | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path" | ||||
|  | @ -36,7 +37,8 @@ type keystoreEntry struct { | |||
| 
 | ||||
| var _ pki.Keystore = keystore{} | ||||
| 
 | ||||
| func (k keystore) FindPrimaryKeypair(name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| // FindPrimaryKeypair implements pki.Keystore
 | ||||
| func (k keystore) FindPrimaryKeypair(ctx context.Context, name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	entry, ok := k.keys[name] | ||||
| 	if !ok { | ||||
| 		return nil, nil, fmt.Errorf("unknown CA %q", name) | ||||
|  |  | |||
|  | @ -180,7 +180,7 @@ func (s *Server) bootstrap(w http.ResponseWriter, r *http.Request) { | |||
| 	validHours := (455 * 24) + (hash.Sum32() % (30 * 24)) | ||||
| 
 | ||||
| 	for name, pubKey := range req.Certs { | ||||
| 		cert, err := s.issueCert(name, pubKey, id, validHours, req.KeypairIDs) | ||||
| 		cert, err := s.issueCert(ctx, name, pubKey, id, validHours, req.KeypairIDs) | ||||
| 		if err != nil { | ||||
| 			klog.Infof("bootstrap %s cert %q issue err: %v", r.RemoteAddr, name, err) | ||||
| 			w.WriteHeader(http.StatusBadRequest) | ||||
|  | @ -195,7 +195,7 @@ func (s *Server) bootstrap(w http.ResponseWriter, r *http.Request) { | |||
| 	klog.Infof("bootstrap %s %s success", r.RemoteAddr, id.NodeName) | ||||
| } | ||||
| 
 | ||||
| func (s *Server) issueCert(name string, pubKey string, id *bootstrap.VerifyResult, validHours uint32, keypairIDs map[string]string) (string, error) { | ||||
| func (s *Server) issueCert(ctx context.Context, name string, pubKey string, id *bootstrap.VerifyResult, validHours uint32, keypairIDs map[string]string) (string, error) { | ||||
| 	block, _ := pem.Decode([]byte(pubKey)) | ||||
| 	if block.Type != "RSA PUBLIC KEY" { | ||||
| 		return "", fmt.Errorf("unexpected key type %q", block.Type) | ||||
|  | @ -251,7 +251,7 @@ func (s *Server) issueCert(name string, pubKey string, id *bootstrap.VerifyResul | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	cert, _, _, err := pki.IssueCert(issueReq, s.keystore) | ||||
| 	cert, _, _, err := pki.IssueCert(ctx, issueReq, s.keystore) | ||||
| 	if err != nil { | ||||
| 		return "", fmt.Errorf("issuing certificate: %v", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -215,7 +215,7 @@ func createKeypair(ctx context.Context, out io.Writer, options *CreateKeypairOpt | |||
| 			Serial:     serial, | ||||
| 			PrivateKey: privateKey, | ||||
| 		} | ||||
| 		cert, _, _, err = pki.IssueCert(&req, nil) | ||||
| 		cert, _, _, err = pki.IssueCert(ctx, &req, nil) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("error issuing certificate: %v", err) | ||||
| 		} | ||||
|  | @ -232,7 +232,7 @@ func createKeypair(ctx context.Context, out io.Writer, options *CreateKeypairOpt | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	keyset, err := keyStore.FindKeyset(name) | ||||
| 	keyset, err := keyStore.FindKeyset(ctx, name) | ||||
| 	var item *fi.KeysetItem | ||||
| 	if os.IsNotExist(err) || (err == nil && keyset == nil) { | ||||
| 		if options.Primary { | ||||
|  | @ -295,12 +295,14 @@ func completeKeyset(ctx context.Context, cluster *kopsapi.Cluster, clientSet sim | |||
| 		return nil, nil, keysets, cobra.ShellCompDirectiveNoFileComp | ||||
| 	} | ||||
| 
 | ||||
| 	keyset, err = keyStore.FindKeyset(args[0]) | ||||
| 	keyset, err = keyStore.FindKeyset(ctx, args[0]) | ||||
| 	if err != nil { | ||||
| 		completions, directive := commandutils.CompletionError("finding keyset", err) | ||||
| 		return nil, keyStore, completions, directive | ||||
| 	} | ||||
| 
 | ||||
| 	// keyset may be nil if not found
 | ||||
| 
 | ||||
| 	return keyset, keyStore, nil, cobra.ShellCompDirectiveNoFileComp | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -145,7 +145,7 @@ func RunDistrustKeypair(ctx context.Context, f *util.Factory, out io.Writer, opt | |||
| } | ||||
| 
 | ||||
| func distrustKeypair(ctx context.Context, out io.Writer, name string, keypairIDs []string, keyStore fi.CAStore) error { | ||||
| 	keyset, err := keyStore.FindKeyset(name) | ||||
| 	keyset, err := keyStore.FindKeyset(ctx, name) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} else if keyset == nil { | ||||
|  |  | |||
|  | @ -145,6 +145,7 @@ func RunExportKubeconfig(ctx context.Context, f *util.Factory, out io.Writer, op | |||
| 			return err | ||||
| 		} | ||||
| 		conf, err := kubeconfig.BuildKubecfg( | ||||
| 			ctx, | ||||
| 			cluster, | ||||
| 			keyStore, | ||||
| 			secretStore, | ||||
|  |  | |||
|  | @ -154,7 +154,7 @@ func RunPromoteKeypair(ctx context.Context, f *util.Factory, out io.Writer, opti | |||
| } | ||||
| 
 | ||||
| func promoteKeypair(ctx context.Context, out io.Writer, name string, keypairID string, keyStore fi.CAStore) error { | ||||
| 	keyset, err := keyStore.FindKeyset(name) | ||||
| 	keyset, err := keyStore.FindKeyset(ctx, name) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("reading keyset: %v", err) | ||||
| 	} else if keyset == nil { | ||||
|  |  | |||
|  | @ -108,10 +108,13 @@ func RunTrustKeypair(ctx context.Context, f *util.Factory, out io.Writer, option | |||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	keyset, err := keyStore.FindKeyset(options.Keyset) | ||||
| 	keyset, err := keyStore.FindKeyset(ctx, options.Keyset) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if keyset == nil { | ||||
| 		return fmt.Errorf("keyset %q not found", options.Keyset) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, id := range options.KeypairIDs { | ||||
| 		item := keyset.Items[id] | ||||
|  |  | |||
|  | @ -325,6 +325,7 @@ func RunUpdateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *Up | |||
| 		// TODO: Another flag?
 | ||||
| 		useKopsAuthenticationPlugin := false | ||||
| 		conf, err := kubeconfig.BuildKubecfg( | ||||
| 			ctx, | ||||
| 			cluster, | ||||
| 			keyStore, | ||||
| 			secretStore, | ||||
|  |  | |||
|  | @ -289,9 +289,12 @@ func (c *NodeupModelContext) BuildBootstrapKubeconfig(name string, ctx *fi.Nodeu | |||
| 
 | ||||
| 		return kubeConfig.GetConfig(), nil | ||||
| 	} else { | ||||
| 		keyset, err := c.KeyStore.FindKeyset(name) | ||||
| 		keyset, err := c.KeyStore.FindKeyset(ctx.Context(), name) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("error fetching keyset: %v from keystore: %v", name, err) | ||||
| 			return nil, fmt.Errorf("error fetching keyset %q from keystore: %w", name, err) | ||||
| 		} | ||||
| 		if keyset == nil { | ||||
| 			return nil, fmt.Errorf("keyset %q not found", name) | ||||
| 		} | ||||
| 
 | ||||
| 		keypairID := c.NodeupConfig.KeypairIDs[name] | ||||
|  | @ -422,10 +425,13 @@ func (c *NodeupModelContext) buildCertificatePairTask(ctx *fi.NodeupModelBuilder | |||
| 		return fmt.Errorf("no keypair ID for %q", name) | ||||
| 	} | ||||
| 
 | ||||
| 	keyset, err := c.KeyStore.FindKeyset(name) | ||||
| 	keyset, err := c.KeyStore.FindKeyset(ctx.Context(), name) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if keyset == nil { | ||||
| 		return fmt.Errorf("keyset %q not found", name) | ||||
| 	} | ||||
| 
 | ||||
| 	item := keyset.Items[keypairID] | ||||
| 	if item == nil { | ||||
|  | @ -476,7 +482,7 @@ func (c *NodeupModelContext) buildCertificatePairTask(ctx *fi.NodeupModelBuilder | |||
| 
 | ||||
| // BuildCertificateTask builds a task to create a certificate file.
 | ||||
| func (c *NodeupModelContext) BuildCertificateTask(ctx *fi.NodeupModelBuilderContext, name, filename string, owner *string) error { | ||||
| 	keyset, err := c.KeyStore.FindKeyset(name) | ||||
| 	keyset, err := c.KeyStore.FindKeyset(ctx.Context(), name) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | @ -507,7 +513,7 @@ func (c *NodeupModelContext) BuildCertificateTask(ctx *fi.NodeupModelBuilderCont | |||
| 
 | ||||
| // BuildLegacyPrivateKeyTask builds a task to create a private key file.
 | ||||
| func (c *NodeupModelContext) BuildLegacyPrivateKeyTask(ctx *fi.NodeupModelBuilderContext, name, filename string, owner *string) error { | ||||
| 	keyset, err := c.KeyStore.FindKeyset(name) | ||||
| 	keyset, err := c.KeyStore.FindKeyset(ctx.Context(), name) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  |  | |||
|  | @ -36,8 +36,9 @@ type fakeKeystore struct { | |||
| 
 | ||||
| var _ fi.Keystore = &fakeKeystore{} | ||||
| 
 | ||||
| func (k fakeKeystore) FindPrimaryKeypair(name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	keyset, err := k.FindKeyset(name) | ||||
| // FindPrimaryKeypair implements pki.Keystore
 | ||||
| func (k fakeKeystore) FindPrimaryKeypair(ctx context.Context, name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	keyset, err := k.FindKeyset(ctx, name) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
|  | @ -45,7 +46,8 @@ func (k fakeKeystore) FindPrimaryKeypair(name string) (*pki.Certificate, *pki.Pr | |||
| 	return keyset.Primary.Certificate, keyset.Primary.PrivateKey, nil | ||||
| } | ||||
| 
 | ||||
| func (k fakeKeystore) FindKeyset(name string) (*fi.Keyset, error) { | ||||
| // FindKeyset implements KeystoreReader.
 | ||||
| func (k fakeKeystore) FindKeyset(ctx context.Context, name string) (*fi.Keyset, error) { | ||||
| 	kopsKeyset := k.privateKeysets[name] | ||||
| 	if kopsKeyset == nil { | ||||
| 		return nil, nil | ||||
|  |  | |||
|  | @ -255,7 +255,7 @@ func buildCredentials(ctx context.Context, f *util.Factory, options *HelperKubec | |||
| 		}, | ||||
| 		Validity: options.Lifetime, | ||||
| 	} | ||||
| 	cert, privateKey, _, err := pki.IssueCert(&req, keyStore) | ||||
| 	cert, privateKey, _, err := pki.IssueCert(ctx, &req, keyStore) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("unable to issue certificate: %v", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ limitations under the License. | |||
| package configserver | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"k8s.io/kops/pkg/pki" | ||||
|  | @ -31,11 +32,11 @@ func NewKeyStore() fi.KeystoreReader { | |||
| } | ||||
| 
 | ||||
| // FindPrimaryKeypair implements pki.Keystore
 | ||||
| func (s *configserverKeyStore) FindPrimaryKeypair(name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| func (s *configserverKeyStore) FindPrimaryKeypair(ctx context.Context, name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	return nil, nil, fmt.Errorf("FindPrimaryKeypair %q not supported by configserverKeyStore", name) | ||||
| } | ||||
| 
 | ||||
| // FindKeyset implements fi.Keystore
 | ||||
| func (s *configserverKeyStore) FindKeyset(name string) (*fi.Keyset, error) { | ||||
| // FindKeyset implements KeystoreReader.
 | ||||
| func (s *configserverKeyStore) FindKeyset(ctx context.Context, name string) (*fi.Keyset, error) { | ||||
| 	return nil, fmt.Errorf("FindKeyset %q not supported by configserverKeyStore", name) | ||||
| } | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ limitations under the License. | |||
| package kubeconfig | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/x509/pkix" | ||||
| 	"fmt" | ||||
| 	"os/user" | ||||
|  | @ -32,7 +33,7 @@ import ( | |||
| 
 | ||||
| const DefaultKubecfgAdminLifetime = 18 * time.Hour | ||||
| 
 | ||||
| func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.SecretStore, cloud fi.Cloud, admin time.Duration, configUser string, internal bool, kopsStateStore string, useKopsAuthenticationPlugin bool) (*KubeconfigBuilder, error) { | ||||
| func BuildKubecfg(ctx context.Context, cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.SecretStore, cloud fi.Cloud, admin time.Duration, configUser string, internal bool, kopsStateStore string, useKopsAuthenticationPlugin bool) (*KubeconfigBuilder, error) { | ||||
| 	clusterName := cluster.ObjectMeta.Name | ||||
| 
 | ||||
| 	var server string | ||||
|  | @ -88,7 +89,7 @@ func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.Se | |||
| 	// add the CA Cert to the kubeconfig only if we didn't specify a certificate for the LB
 | ||||
| 	//  or if we're using admin credentials and the secondary port
 | ||||
| 	if cluster.Spec.API.LoadBalancer == nil || cluster.Spec.API.LoadBalancer.SSLCertificate == "" || cluster.Spec.API.LoadBalancer.Class == kops.LoadBalancerClassNetwork || internal { | ||||
| 		keySet, err := keyStore.FindKeyset(fi.CertificateIDCA) | ||||
| 		keySet, err := keyStore.FindKeyset(ctx, fi.CertificateIDCA) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("error fetching CA keypair: %v", err) | ||||
| 		} | ||||
|  | @ -120,7 +121,7 @@ func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.Se | |||
| 			}, | ||||
| 			Validity: admin, | ||||
| 		} | ||||
| 		cert, privateKey, _, err := pki.IssueCert(&req, keyStore) | ||||
| 		cert, privateKey, _, err := pki.IssueCert(ctx, &req, keyStore) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  |  | |||
|  | @ -101,11 +101,15 @@ type fakeKeyStore struct { | |||
| 	MirrorToFn func(basedir vfs.Path) error | ||||
| } | ||||
| 
 | ||||
| func (f fakeKeyStore) FindPrimaryKeypair(name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	return fi.FindPrimaryKeypair(f, name) | ||||
| var _ fi.Keystore = &fakeKeyStore{} | ||||
| 
 | ||||
| // FindPrimaryKeypair implements pki.Keystore
 | ||||
| func (f fakeKeyStore) FindPrimaryKeypair(ctx context.Context, name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	return fi.FindPrimaryKeypair(ctx, f, name) | ||||
| } | ||||
| 
 | ||||
| func (f fakeKeyStore) FindKeyset(name string) (*fi.Keyset, error) { | ||||
| // FindKeyset implements KeystoreReader.
 | ||||
| func (f fakeKeyStore) FindKeyset(ctx context.Context, name string) (*fi.Keyset, error) { | ||||
| 	return f.FindKeysetFn(name) | ||||
| } | ||||
| 
 | ||||
|  | @ -349,6 +353,8 @@ func TestBuildKubecfg(t *testing.T) { | |||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			ctx := context.TODO() | ||||
| 
 | ||||
| 			kopsStateStore := "memfs://example-state-store" | ||||
| 
 | ||||
| 			keyStore := fakeKeyStore{ | ||||
|  | @ -358,7 +364,7 @@ func TestBuildKubecfg(t *testing.T) { | |||
| 				}, | ||||
| 			} | ||||
| 
 | ||||
| 			got, err := BuildKubecfg(tt.args.cluster, keyStore, tt.args.secretStore, tt.args.status, tt.args.admin, tt.args.user, tt.args.internal, kopsStateStore, tt.args.useKopsAuthenticationPlugin) | ||||
| 			got, err := BuildKubecfg(ctx, tt.args.cluster, keyStore, tt.args.secretStore, tt.args.status, tt.args.admin, tt.args.user, tt.args.internal, kopsStateStore, tt.args.useKopsAuthenticationPlugin) | ||||
| 			if (err != nil) != tt.wantErr { | ||||
| 				t.Errorf("BuildKubecfg() error = %v, wantErr %v", err, tt.wantErr) | ||||
| 				return | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ limitations under the License. | |||
| package pki | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto" | ||||
| 	"crypto/x509" | ||||
| 	"crypto/x509/pkix" | ||||
|  | @ -58,11 +59,12 @@ type IssueCertRequest struct { | |||
| type Keystore interface { | ||||
| 	// FindPrimaryKeypair 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).
 | ||||
| 	FindPrimaryKeypair(name string) (*Certificate, *PrivateKey, error) | ||||
| 	// Also note that if the keypair is not found at all, this returns (nil, nil, nil)
 | ||||
| 	FindPrimaryKeypair(ctx context.Context, name string) (*Certificate, *PrivateKey, error) | ||||
| } | ||||
| 
 | ||||
| // IssueCert issues a certificate, either a self-signed CA or from a CA in a keystore.
 | ||||
| func IssueCert(request *IssueCertRequest, keystore Keystore) (issuedCertificate *Certificate, issuedKey *PrivateKey, caCertificate *Certificate, err error) { | ||||
| func IssueCert(ctx context.Context, request *IssueCertRequest, keystore Keystore) (issuedCertificate *Certificate, issuedKey *PrivateKey, caCertificate *Certificate, err error) { | ||||
| 	certificateType := request.Type | ||||
| 	if expanded, found := wellKnownCertificateTypes[certificateType]; found { | ||||
| 		certificateType = expanded | ||||
|  | @ -116,7 +118,7 @@ func IssueCert(request *IssueCertRequest, keystore Keystore) (issuedCertificate | |||
| 	var signer *x509.Certificate | ||||
| 	if !template.IsCA { | ||||
| 		var err error | ||||
| 		caCertificate, caPrivateKey, err = keystore.FindPrimaryKeypair(request.Signer) | ||||
| 		caCertificate, caPrivateKey, err = keystore.FindPrimaryKeypair(ctx, request.Signer) | ||||
| 		if err != nil { | ||||
| 			return nil, nil, nil, err | ||||
| 		} | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ limitations under the License. | |||
| package pki | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/x509" | ||||
| 	"crypto/x509/pkix" | ||||
|  | @ -38,7 +39,8 @@ type mockKeystore struct { | |||
| 	invoked bool | ||||
| } | ||||
| 
 | ||||
| func (m *mockKeystore) FindPrimaryKeypair(name string) (*Certificate, *PrivateKey, error) { | ||||
| // FindPrimaryKeypair implements pki.Keystore
 | ||||
| func (m *mockKeystore) FindPrimaryKeypair(ctx context.Context, name string) (*Certificate, *PrivateKey, error) { | ||||
| 	assert.False(m.t, m.invoked, "invoked already") | ||||
| 	m.invoked = true | ||||
| 	assert.Equal(m.t, m.signer, name, "name argument") | ||||
|  | @ -139,6 +141,8 @@ func TestIssueCert(t *testing.T) { | |||
| 		}, | ||||
| 	} { | ||||
| 		t.Run(tc.name, func(t *testing.T) { | ||||
| 			ctx := context.TODO() | ||||
| 
 | ||||
| 			var minExpectedValidity int64 | ||||
| 			if tc.req.Validity == 0 { | ||||
| 				minExpectedValidity = time.Now().Add(time.Hour * 10 * 365 * 24).Unix() | ||||
|  | @ -156,7 +160,7 @@ func TestIssueCert(t *testing.T) { | |||
| 					key:    caPrivateKey, | ||||
| 				} | ||||
| 			} | ||||
| 			certificate, key, caCert, err := IssueCert(&tc.req, keystore) | ||||
| 			certificate, key, caCert, err := IssueCert(ctx, &tc.req, keystore) | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 			cert := certificate.Certificate | ||||
|  |  | |||
|  | @ -71,8 +71,8 @@ type KeysetItem struct { | |||
| type KeystoreReader interface { | ||||
| 	pki.Keystore | ||||
| 
 | ||||
| 	// FindKeyset finds a Keyset.
 | ||||
| 	FindKeyset(name string) (*Keyset, error) | ||||
| 	// FindKeyset finds a Keyset.  If the keyset is not found, it returns (nil, nil)
 | ||||
| 	FindKeyset(ctx context.Context, name string) (*Keyset, error) | ||||
| } | ||||
| 
 | ||||
| // Keystore contains just the functions we need to issue keypairs, not to list / manage them
 | ||||
|  | @ -112,8 +112,8 @@ type SSHCredentialStore interface { | |||
| } | ||||
| 
 | ||||
| // FindPrimaryKeypair is a common implementation of pki.FindPrimaryKeypair.
 | ||||
| func FindPrimaryKeypair(c Keystore, name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	keyset, err := c.FindKeyset(name) | ||||
| func FindPrimaryKeypair(ctx context.Context, c Keystore, name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	keyset, err := c.FindKeyset(ctx, name) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
|  |  | |||
|  | @ -155,14 +155,13 @@ func FindPrimary(keyset *kops.Keyset) *kops.KeysetItem { | |||
| 	return primary | ||||
| } | ||||
| 
 | ||||
| // FindPrimaryKeypair implements PKI::FindPrimaryKeypair
 | ||||
| func (c *ClientsetCAStore) FindPrimaryKeypair(name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	return FindPrimaryKeypair(c, name) | ||||
| // FindPrimaryKeypair implements pki.Keystore
 | ||||
| func (c *ClientsetCAStore) FindPrimaryKeypair(ctx context.Context, name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	return FindPrimaryKeypair(ctx, c, name) | ||||
| } | ||||
| 
 | ||||
| // FindKeyset implements CAStore::FindKeyset
 | ||||
| func (c *ClientsetCAStore) FindKeyset(name string) (*Keyset, error) { | ||||
| 	ctx := context.TODO() | ||||
| // FindKeyset implements KeystoreReader.
 | ||||
| func (c *ClientsetCAStore) FindKeyset(ctx context.Context, name string) (*Keyset, error) { | ||||
| 	return c.loadKeyset(ctx, name) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -69,12 +69,14 @@ func (e *Keypair) CompareWithID() *string { | |||
| } | ||||
| 
 | ||||
| func (e *Keypair) Find(c *fi.CloudupContext) (*Keypair, error) { | ||||
| 	ctx := c.Context() | ||||
| 
 | ||||
| 	name := fi.ValueOf(e.Name) | ||||
| 	if name == "" { | ||||
| 		return nil, nil | ||||
| 	} | ||||
| 
 | ||||
| 	keyset, err := c.T.Keystore.FindKeyset(name) | ||||
| 	keyset, err := c.T.Keystore.FindKeyset(ctx, name) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -195,7 +197,7 @@ func (_ *Keypair) Render(c *fi.CloudupContext, a, e, changes *Keypair) error { | |||
| 	if createCertificate { | ||||
| 		klog.V(2).Infof("Creating PKI keypair %q", name) | ||||
| 
 | ||||
| 		keyset, err := c.T.Keystore.FindKeyset(name) | ||||
| 		keyset, err := c.T.Keystore.FindKeyset(ctx, name) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | @ -242,7 +244,7 @@ func (_ *Keypair) Render(c *fi.CloudupContext, a, e, changes *Keypair) error { | |||
| 			PrivateKey:     privateKey, | ||||
| 			Serial:         serial, | ||||
| 		} | ||||
| 		cert, privateKey, _, err := pki.IssueCert(&req, c.T.Keystore) | ||||
| 		cert, privateKey, _, err := pki.IssueCert(ctx, &req, c.T.Keystore) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | @ -267,9 +269,10 @@ func (_ *Keypair) Render(c *fi.CloudupContext, a, e, changes *Keypair) error { | |||
| 		} | ||||
| 
 | ||||
| 		// Make double-sure it round-trips
 | ||||
| 		_, err = c.T.Keystore.FindKeyset(name) | ||||
| 		if err != nil { | ||||
| 		if roundtrip, err := c.T.Keystore.FindKeyset(ctx, name); err != nil { | ||||
| 			return err | ||||
| 		} else if roundtrip == nil { | ||||
| 			return fmt.Errorf("unable to find created certificate %q: %w", name, err) | ||||
| 		} | ||||
| 
 | ||||
| 		klog.V(8).Infof("created certificate with cn=%s", cert.Subject.CommonName) | ||||
|  | @ -280,10 +283,14 @@ func (_ *Keypair) Render(c *fi.CloudupContext, a, e, changes *Keypair) error { | |||
| 	if changeStoredFormat { | ||||
| 		// We fetch and reinsert the same keypair, forcing an update to our preferred format
 | ||||
| 		// TODO: We're assuming that we want to save in the preferred format
 | ||||
| 		keyset, err := c.T.Keystore.FindKeyset(name) | ||||
| 		keyset, err := c.T.Keystore.FindKeyset(ctx, name) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if keyset == nil { | ||||
| 			return fmt.Errorf("keyset %q not found", name) | ||||
| 		} | ||||
| 
 | ||||
| 		keyset.LegacyFormat = false | ||||
| 		err = c.T.Keystore.StoreKeyset(ctx, name, keyset) | ||||
| 		if err != nil { | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ package nodetasks | |||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"crypto/x509/pkix" | ||||
| 	"fmt" | ||||
| 	"hash/fnv" | ||||
|  | @ -130,6 +131,8 @@ func (i *IssueCert) AddFileTasks(c *fi.NodeupModelBuilderContext, dir string, na | |||
| } | ||||
| 
 | ||||
| func (e *IssueCert) Run(c *fi.NodeupContext) error { | ||||
| 	ctx := c.Context() | ||||
| 
 | ||||
| 	// Skew the certificate lifetime by up to 30 days based on information about the generating node.
 | ||||
| 	// This is so that different nodes created at the same time have the certificates they generated
 | ||||
| 	// expire at different times, but all certificates on a given node expire around the same time.
 | ||||
|  | @ -155,13 +158,13 @@ func (e *IssueCert) Run(c *fi.NodeupContext) error { | |||
| 		Validity:       time.Hour * time.Duration(validHours), | ||||
| 	} | ||||
| 
 | ||||
| 	keystore, err := newStaticKeystore(e.Signer, e.KeypairID, c.T.Keystore) | ||||
| 	keystore, err := newStaticKeystore(ctx, e.Signer, e.KeypairID, c.T.Keystore) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	klog.Infof("signing certificate for %q", e.Name) | ||||
| 	certificate, privateKey, caCertificate, err := pki.IssueCert(req, keystore) | ||||
| 	certificate, privateKey, caCertificate, err := pki.IssueCert(ctx, req, keystore) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | @ -208,14 +211,15 @@ type staticKeystore struct { | |||
| 	key         *pki.PrivateKey | ||||
| } | ||||
| 
 | ||||
| func (s staticKeystore) FindPrimaryKeypair(name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| // FindPrimaryKeypair implements pki.Keystore
 | ||||
| func (s staticKeystore) FindPrimaryKeypair(ctx context.Context, name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	if name != s.keyset { | ||||
| 		return nil, nil, fmt.Errorf("wrong signer: expected %q got %q", s.keyset, name) | ||||
| 	} | ||||
| 	return s.certificate, s.key, nil | ||||
| } | ||||
| 
 | ||||
| func newStaticKeystore(signer string, keypairID string, keystore fi.KeystoreReader) (pki.Keystore, error) { | ||||
| func newStaticKeystore(ctx context.Context, signer string, keypairID string, keystore fi.KeystoreReader) (pki.Keystore, error) { | ||||
| 	if signer == "" { | ||||
| 		return nil, nil | ||||
| 	} | ||||
|  | @ -224,10 +228,13 @@ func newStaticKeystore(signer string, keypairID string, keystore fi.KeystoreRead | |||
| 		return nil, fmt.Errorf("missing keypairID for %s", signer) | ||||
| 	} | ||||
| 
 | ||||
| 	keyset, err := keystore.FindKeyset(signer) | ||||
| 	keyset, err := keystore.FindKeyset(ctx, signer) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("reading keyset for %s: %v", signer, err) | ||||
| 	} | ||||
| 	if keyset == nil { | ||||
| 		return nil, fmt.Errorf("keyset %q not found", signer) | ||||
| 	} | ||||
| 
 | ||||
| 	item := keyset.Items[keypairID] | ||||
| 	if item == nil { | ||||
|  |  | |||
|  | @ -211,8 +211,9 @@ func serializeKeysetBundle(o *kops.Keyset) ([]byte, error) { | |||
| 	return objectData.Bytes(), nil | ||||
| } | ||||
| 
 | ||||
| func (c *VFSCAStore) FindPrimaryKeypair(name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	return FindPrimaryKeypair(c, name) | ||||
| // FindPrimaryKeypair implements pki.Keystore
 | ||||
| func (c *VFSCAStore) FindPrimaryKeypair(ctx context.Context, name string) (*pki.Certificate, *pki.PrivateKey, error) { | ||||
| 	return FindPrimaryKeypair(ctx, c, name) | ||||
| } | ||||
| 
 | ||||
| var legacyKeysetMappings = map[string]string{ | ||||
|  | @ -222,7 +223,8 @@ var legacyKeysetMappings = map[string]string{ | |||
| 	"kubernetes-ca": "ca", | ||||
| } | ||||
| 
 | ||||
| func (c *VFSCAStore) FindKeyset(id string) (*Keyset, error) { | ||||
| // FindKeyset implements KeystoreReader.
 | ||||
| func (c *VFSCAStore) FindKeyset(ctx context.Context, id string) (*Keyset, error) { | ||||
| 	keys, err := c.findPrivateKeyset(id) | ||||
| 	if keys == nil || os.IsNotExist(err) { | ||||
| 		if legacyId := legacyKeysetMappings[id]; legacyId != "" { | ||||
|  |  | |||
|  | @ -137,7 +137,7 @@ spec: | |||
| 			t.Fatalf("unexpected private/ca/keyset.yaml: %q", string(privateKeysetYaml)) | ||||
| 		} | ||||
| 
 | ||||
| 		keyset, err := s.FindKeyset("kubernetes-ca") | ||||
| 		keyset, err := s.FindKeyset(ctx, "kubernetes-ca") | ||||
| 		if err != nil { | ||||
| 			t.Fatalf("error reading certificate pool: %v", err) | ||||
| 		} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue