@@ -40,6 +40,81 @@ import (
4040 testutil "github.com/cert-manager/csi-lib/test/util"
4141)
4242
43+ // Tests to ensure that if a certificate is immediately ready to be requested when NodePublishVolume
44+ // is called, the call will be blocking until the volume is actually ready.
45+ func Test_PublishCallBlocksIfReadyToRequestDespiteContinueOnNotReadyTrue (t * testing.T ) {
46+ store := storage .NewMemoryFS ()
47+ clock := fakeclock .NewFakeClock (time .Now ())
48+
49+ opts , cl , stop := testdriver .Run (t , testdriver.Options {
50+ Store : store ,
51+ Clock : clock ,
52+ ContinueOnNotReady : true ,
53+ ReadyToRequest : manager .AlwaysReadyToRequest ,
54+ GeneratePrivateKey : func (meta metadata.Metadata ) (crypto.PrivateKey , error ) {
55+ return nil , nil
56+ },
57+ GenerateRequest : func (meta metadata.Metadata ) (* manager.CertificateRequestBundle , error ) {
58+ return & manager.CertificateRequestBundle {
59+ Namespace : "certificaterequest-namespace" ,
60+ }, nil
61+ },
62+ SignRequest : func (meta metadata.Metadata , key crypto.PrivateKey , request * x509.CertificateRequest ) (csr []byte , err error ) {
63+ return []byte {}, nil
64+ },
65+ WriteKeypair : func (meta metadata.Metadata , key crypto.PrivateKey , chain []byte , ca []byte ) error {
66+ store .WriteFiles (meta , map [string ][]byte {
67+ "ca" : ca ,
68+ "cert" : chain ,
69+ })
70+ nextIssuanceTime := clock .Now ().Add (time .Hour )
71+ meta .NextIssuanceTime = & nextIssuanceTime
72+ return store .WriteMetadata (meta .VolumeID , meta )
73+ },
74+ })
75+ defer stop ()
76+
77+ // Setup a routine to issue/sign the request IF it is created
78+ stopCh := make (chan struct {})
79+ go testutil .IssueAllRequests (t , opts .Client , "certificaterequest-namespace" , stopCh , selfSignedExampleCertificate , []byte ("ca bytes" ))
80+ defer close (stopCh )
81+
82+ tmpDir , err := os .MkdirTemp ("" , "*" )
83+ if err != nil {
84+ t .Fatal (err )
85+ }
86+ defer os .RemoveAll (tmpDir )
87+ ctx , cancel := context .WithTimeout (context .Background (), time .Second * 10 )
88+ defer cancel ()
89+ // This call will block until an issuance is successfully completed.
90+ _ , err = cl .NodePublishVolume (ctx , & csi.NodePublishVolumeRequest {
91+ VolumeId : "test-vol" ,
92+ VolumeContext : map [string ]string {
93+ "csi.storage.k8s.io/ephemeral" : "true" ,
94+ "csi.storage.k8s.io/pod.name" : "the-pod-name" ,
95+ "csi.storage.k8s.io/pod.namespace" : "the-pod-namespace" ,
96+ },
97+ TargetPath : tmpDir ,
98+ Readonly : true ,
99+ })
100+ if err != nil {
101+ t .Fatal (err )
102+ }
103+
104+ // We don't wait at all after the NodePublishVolume call, as it should have blocked
105+ // above meaning the read should immediately succeed.
106+ files , err := store .ReadFiles ("test-vol" )
107+ if err != nil {
108+ t .Error (err )
109+ }
110+ if ! reflect .DeepEqual (files ["ca" ], []byte ("ca bytes" )) {
111+ t .Errorf ("unexpected CA data: %v" , files ["ca" ])
112+ }
113+ if ! reflect .DeepEqual (files ["cert" ], selfSignedExampleCertificate ) {
114+ t .Errorf ("unexpected certificate data: %v" , files ["cert" ])
115+ }
116+ }
117+
43118func Test_CompletesIfNotReadyToRequest_ContinueOnNotReadyEnabled (t * testing.T ) {
44119 store := storage .NewMemoryFS ()
45120 clock := fakeclock .NewFakeClock (time .Now ())
0 commit comments