cleaner_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package cleaner
  14. import (
  15. "testing"
  16. "time"
  17. capi "k8s.io/api/certificates/v1beta1"
  18. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  19. "k8s.io/client-go/kubernetes/fake"
  20. )
  21. const (
  22. expiredCert = `-----BEGIN CERTIFICATE-----
  23. MIICIzCCAc2gAwIBAgIJAOApTlMFDOUnMA0GCSqGSIb3DQEBCwUAMG0xCzAJBgNV
  24. BAYTAkdCMQ8wDQYDVQQIDAZMb25kb24xDzANBgNVBAcMBkxvbmRvbjEYMBYGA1UE
  25. CgwPR2xvYmFsIFNlY3VyaXR5MRYwFAYDVQQLDA1JVCBEZXBhcnRtZW50MQowCAYD
  26. VQQDDAEqMB4XDTE3MTAwNDIwNDgzOFoXDTE3MTAwMzIwNDgzOFowbTELMAkGA1UE
  27. BhMCR0IxDzANBgNVBAgMBkxvbmRvbjEPMA0GA1UEBwwGTG9uZG9uMRgwFgYDVQQK
  28. DA9HbG9iYWwgU2VjdXJpdHkxFjAUBgNVBAsMDUlUIERlcGFydG1lbnQxCjAIBgNV
  29. BAMMASowXDANBgkqhkiG9w0BAQEFAANLADBIAkEA3Gt0KmuRXDxvqZUiX/xqAn1t
  30. nZZX98guZvPPyxnQtV3YpA274W0sX3jL+U71Ya+3kaUstXQa4YrWBUHiXoqJnwID
  31. AQABo1AwTjAdBgNVHQ4EFgQUtDsIpzHoUiLsO88f9fm+G0tYSPowHwYDVR0jBBgw
  32. FoAUtDsIpzHoUiLsO88f9fm+G0tYSPowDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
  33. AQsFAANBADfrlKof5CUkxGlX9Rifxv/mWOk8ZuTLWfMYQH2nycBHnmOxy6sR+87W
  34. /Mb/uRz0TXVnGVcbu5E8Bz7e/Far1ZI=
  35. -----END CERTIFICATE-----`
  36. unexpiredCert = `-----BEGIN CERTIFICATE-----
  37. MIICJTCCAc+gAwIBAgIJAIRjMToP+pPEMA0GCSqGSIb3DQEBCwUAMG0xCzAJBgNV
  38. BAYTAkdCMQ8wDQYDVQQIDAZMb25kb24xDzANBgNVBAcMBkxvbmRvbjEYMBYGA1UE
  39. CgwPR2xvYmFsIFNlY3VyaXR5MRYwFAYDVQQLDA1JVCBEZXBhcnRtZW50MQowCAYD
  40. VQQDDAEqMCAXDTE3MTAwNDIwNDUyNFoYDzIxMTcwOTEwMjA0NTI0WjBtMQswCQYD
  41. VQQGEwJHQjEPMA0GA1UECAwGTG9uZG9uMQ8wDQYDVQQHDAZMb25kb24xGDAWBgNV
  42. BAoMD0dsb2JhbCBTZWN1cml0eTEWMBQGA1UECwwNSVQgRGVwYXJ0bWVudDEKMAgG
  43. A1UEAwwBKjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC7j9BAV5HqIJGi6r4G4YeI
  44. ioHxH2loVu8IOKSK7xVs3v/EjR/eXbQzM+jZU7duyZqn6YjySZNLl0K0MfHCHBgX
  45. AgMBAAGjUDBOMB0GA1UdDgQWBBTwxV40NFSNW7lpQ3eUWX7Mxs03yzAfBgNVHSME
  46. GDAWgBTwxV40NFSNW7lpQ3eUWX7Mxs03yzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3
  47. DQEBCwUAA0EALDi9OidANHflx8q+w3p0rJo9gpA6cJcFpEtP2Lv4kvOtB1f6L0jY
  48. MLd7MVm4cS/MNcx4L7l23UC3Hx4+nAxvIg==
  49. -----END CERTIFICATE-----`
  50. )
  51. func TestCleanerWithApprovedExpiredCSR(t *testing.T) {
  52. testCases := []struct {
  53. name string
  54. created metav1.Time
  55. certificate []byte
  56. conditions []capi.CertificateSigningRequestCondition
  57. expectedActions []string
  58. }{
  59. {
  60. "no delete approved not passed deadline",
  61. metav1.NewTime(time.Now().Add(-1 * time.Minute)),
  62. []byte(unexpiredCert),
  63. []capi.CertificateSigningRequestCondition{
  64. {
  65. Type: capi.CertificateApproved,
  66. LastUpdateTime: metav1.NewTime(time.Now().Add(-50 * time.Minute)),
  67. },
  68. },
  69. []string{},
  70. },
  71. {
  72. "no delete approved passed deadline not issued",
  73. metav1.NewTime(time.Now().Add(-1 * time.Minute)),
  74. nil,
  75. []capi.CertificateSigningRequestCondition{
  76. {
  77. Type: capi.CertificateApproved,
  78. LastUpdateTime: metav1.NewTime(time.Now().Add(-50 * time.Minute)),
  79. },
  80. },
  81. []string{},
  82. },
  83. {
  84. "delete approved passed deadline",
  85. metav1.NewTime(time.Now().Add(-1 * time.Minute)),
  86. []byte(unexpiredCert),
  87. []capi.CertificateSigningRequestCondition{
  88. {
  89. Type: capi.CertificateApproved,
  90. LastUpdateTime: metav1.NewTime(time.Now().Add(-2 * time.Hour)),
  91. },
  92. },
  93. []string{"delete"},
  94. },
  95. {
  96. "no delete denied not passed deadline",
  97. metav1.NewTime(time.Now().Add(-1 * time.Minute)),
  98. nil,
  99. []capi.CertificateSigningRequestCondition{
  100. {
  101. Type: capi.CertificateDenied,
  102. LastUpdateTime: metav1.NewTime(time.Now().Add(-50 * time.Minute)),
  103. },
  104. },
  105. []string{},
  106. },
  107. {
  108. "delete denied passed deadline",
  109. metav1.NewTime(time.Now().Add(-1 * time.Minute)),
  110. nil,
  111. []capi.CertificateSigningRequestCondition{
  112. {
  113. Type: capi.CertificateDenied,
  114. LastUpdateTime: metav1.NewTime(time.Now().Add(-2 * time.Hour)),
  115. },
  116. },
  117. []string{"delete"},
  118. },
  119. {
  120. "no delete pending not passed deadline",
  121. metav1.NewTime(time.Now().Add(-5 * time.Hour)),
  122. nil,
  123. []capi.CertificateSigningRequestCondition{},
  124. []string{},
  125. },
  126. {
  127. "delete pending passed deadline",
  128. metav1.NewTime(time.Now().Add(-25 * time.Hour)),
  129. nil,
  130. []capi.CertificateSigningRequestCondition{},
  131. []string{"delete"},
  132. },
  133. {
  134. "no delete approved not passed deadline unexpired",
  135. metav1.NewTime(time.Now().Add(-1 * time.Minute)),
  136. []byte(unexpiredCert),
  137. []capi.CertificateSigningRequestCondition{
  138. {
  139. Type: capi.CertificateApproved,
  140. LastUpdateTime: metav1.NewTime(time.Now().Add(-50 * time.Minute)),
  141. },
  142. },
  143. []string{},
  144. },
  145. {
  146. "delete approved not passed deadline expired",
  147. metav1.NewTime(time.Now().Add(-1 * time.Minute)),
  148. []byte(expiredCert),
  149. []capi.CertificateSigningRequestCondition{
  150. {
  151. Type: capi.CertificateApproved,
  152. LastUpdateTime: metav1.NewTime(time.Now().Add(-50 * time.Minute)),
  153. },
  154. },
  155. []string{"delete"},
  156. },
  157. }
  158. for _, tc := range testCases {
  159. t.Run(tc.name, func(t *testing.T) {
  160. csr := &capi.CertificateSigningRequest{
  161. ObjectMeta: metav1.ObjectMeta{
  162. Name: "fake-csr",
  163. CreationTimestamp: tc.created,
  164. },
  165. Status: capi.CertificateSigningRequestStatus{
  166. Certificate: tc.certificate,
  167. Conditions: tc.conditions,
  168. },
  169. }
  170. client := fake.NewSimpleClientset(csr)
  171. s := &CSRCleanerController{
  172. csrClient: client.CertificatesV1beta1().CertificateSigningRequests(),
  173. }
  174. err := s.handle(csr)
  175. if err != nil {
  176. t.Fatalf("failed to clean CSR: %v", err)
  177. }
  178. actions := client.Actions()
  179. if len(actions) != len(tc.expectedActions) {
  180. t.Fatalf("got %d actions, wanted %d actions", len(actions), len(tc.expectedActions))
  181. }
  182. for i := 0; i < len(actions); i++ {
  183. if a := actions[i]; !a.Matches(tc.expectedActions[i], "certificatesigningrequests") {
  184. t.Errorf("got action %#v, wanted %v", a, tc.expectedActions[i])
  185. }
  186. }
  187. })
  188. }
  189. }