common.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /*
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. limitations under the License.
  10. */
  11. package common
  12. import (
  13. "fmt"
  14. v1 "k8s.io/api/core/v1"
  15. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  16. "crypto/rand"
  17. "crypto/x509"
  18. "encoding/pem"
  19. esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
  20. "github.com/external-secrets/external-secrets/e2e/framework"
  21. p12 "software.sslmate.com/src/go-pkcs12"
  22. )
  23. // This case creates multiple secrets with simple key/value pairs and syncs them using multiple .Spec.Data blocks.
  24. // Not supported by: vault.
  25. func SimpleDataSync(f *framework.Framework) (string, func(*framework.TestCase)) {
  26. return "[common] should sync simple secrets from .Data[]", func(tc *framework.TestCase) {
  27. secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
  28. secretKey2 := fmt.Sprintf("%s-%s", f.Namespace.Name, "other")
  29. secretValue := "bar"
  30. tc.Secrets = map[string]string{
  31. secretKey1: secretValue,
  32. secretKey2: secretValue,
  33. }
  34. tc.ExpectedSecret = &v1.Secret{
  35. Type: v1.SecretTypeOpaque,
  36. Data: map[string][]byte{
  37. secretKey1: []byte(secretValue),
  38. secretKey2: []byte(secretValue),
  39. },
  40. }
  41. tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
  42. {
  43. SecretKey: secretKey1,
  44. RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
  45. Key: secretKey1,
  46. },
  47. },
  48. {
  49. SecretKey: secretKey2,
  50. RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
  51. Key: secretKey2,
  52. },
  53. },
  54. }
  55. }
  56. }
  57. // This case creates multiple secrets with json values and syncs them using multiple .Spec.Data blocks.
  58. // The data is extracted from the JSON key using ref.Property.
  59. func JSONDataWithProperty(f *framework.Framework) (string, func(*framework.TestCase)) {
  60. return "[common] should sync multiple secrets from .Data[]", func(tc *framework.TestCase) {
  61. secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
  62. secretKey2 := fmt.Sprintf("%s-%s", f.Namespace.Name, "two")
  63. secretValue1 := "{\"foo1\":\"foo1-val\",\"bar1\":\"bar1-val\"}"
  64. secretValue2 := "{\"foo2\":\"foo2-val\",\"bar2\":\"bar2-val\"}"
  65. tc.Secrets = map[string]string{
  66. secretKey1: secretValue1,
  67. secretKey2: secretValue2,
  68. }
  69. tc.ExpectedSecret = &v1.Secret{
  70. Type: v1.SecretTypeOpaque,
  71. Data: map[string][]byte{
  72. secretKey1: []byte("foo1-val"),
  73. secretKey2: []byte("bar2-val"),
  74. },
  75. }
  76. tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
  77. {
  78. SecretKey: secretKey1,
  79. RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
  80. Key: secretKey1,
  81. Property: "foo1",
  82. },
  83. },
  84. {
  85. SecretKey: secretKey2,
  86. RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
  87. Key: secretKey2,
  88. Property: "bar2",
  89. },
  90. },
  91. }
  92. }
  93. }
  94. // This case creates multiple secrets with json values and renders a template.
  95. // The data is extracted from the JSON key using ref.Property.
  96. func JSONDataWithTemplate(f *framework.Framework) (string, func(*framework.TestCase)) {
  97. return "[common] should sync json secrets with template", func(tc *framework.TestCase) {
  98. secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
  99. secretKey2 := fmt.Sprintf("%s-%s", f.Namespace.Name, "other")
  100. secretValue1 := "{\"foo1\":\"foo1-val\",\"bar1\":\"bar1-val\"}"
  101. secretValue2 := "{\"foo2\":\"foo2-val\",\"bar2\":\"bar2-val\"}"
  102. tc.Secrets = map[string]string{
  103. secretKey1: secretValue1,
  104. secretKey2: secretValue2,
  105. }
  106. tc.ExpectedSecret = &v1.Secret{
  107. Type: v1.SecretTypeOpaque,
  108. ObjectMeta: metav1.ObjectMeta{
  109. Annotations: map[string]string{
  110. "example": "annotation",
  111. },
  112. Labels: map[string]string{
  113. "example": "label",
  114. },
  115. },
  116. Data: map[string][]byte{
  117. "my-data": []byte(`executed: foo1-val|bar2-val`),
  118. },
  119. }
  120. tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
  121. Metadata: esv1alpha1.ExternalSecretTemplateMetadata{
  122. Annotations: map[string]string{
  123. "example": "annotation",
  124. },
  125. Labels: map[string]string{
  126. "example": "label",
  127. },
  128. },
  129. Data: map[string]string{
  130. "my-data": "executed: {{ .one | toString }}|{{ .two | toString }}",
  131. },
  132. }
  133. tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
  134. {
  135. SecretKey: "one",
  136. RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
  137. Key: secretKey1,
  138. Property: "foo1",
  139. },
  140. },
  141. {
  142. SecretKey: "two",
  143. RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
  144. Key: secretKey2,
  145. Property: "bar2",
  146. },
  147. },
  148. }
  149. }
  150. }
  151. // This case creates one secret with json values and syncs them using a single .Spec.DataFrom block.
  152. func JSONDataFromSync(f *framework.Framework) (string, func(*framework.TestCase)) {
  153. return "[common] should sync secrets with dataFrom", func(tc *framework.TestCase) {
  154. secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
  155. targetSecretKey1 := "name"
  156. targetSecretValue1 := "great-name"
  157. targetSecretKey2 := "surname"
  158. targetSecretValue2 := "great-surname"
  159. secretValue := fmt.Sprintf("{ \"%s\": \"%s\", \"%s\": \"%s\" }", targetSecretKey1, targetSecretValue1, targetSecretKey2, targetSecretValue2)
  160. tc.Secrets = map[string]string{
  161. secretKey1: secretValue,
  162. }
  163. tc.ExpectedSecret = &v1.Secret{
  164. Type: v1.SecretTypeOpaque,
  165. Data: map[string][]byte{
  166. targetSecretKey1: []byte(targetSecretValue1),
  167. targetSecretKey2: []byte(targetSecretValue2),
  168. },
  169. }
  170. tc.ExternalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
  171. {
  172. Key: secretKey1,
  173. },
  174. }
  175. }
  176. }
  177. // This case creates a secret with a nested json value. It is synced into two secrets.
  178. // The values from the nested data are extracted using gjson.
  179. // not supported by: vault.
  180. func NestedJSONWithGJSON(f *framework.Framework) (string, func(*framework.TestCase)) {
  181. return "[common] should sync nested json secrets and get inner keys", func(tc *framework.TestCase) {
  182. secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
  183. targetSecretKey1 := "firstname"
  184. targetSecretValue1 := "Tom"
  185. targetSecretKey2 := "first_friend"
  186. targetSecretValue2 := "Roger"
  187. secretValue := fmt.Sprintf(
  188. `{
  189. "name": {"first": "%s", "last": "Anderson"},
  190. "friends":
  191. [
  192. {"first": "Dale", "last": "Murphy"},
  193. {"first": "%s", "last": "Craig"},
  194. {"first": "Jane", "last": "Murphy"}
  195. ]
  196. }`, targetSecretValue1, targetSecretValue2)
  197. tc.Secrets = map[string]string{
  198. secretKey1: secretValue,
  199. }
  200. tc.ExpectedSecret = &v1.Secret{
  201. Type: v1.SecretTypeOpaque,
  202. Data: map[string][]byte{
  203. targetSecretKey1: []byte(targetSecretValue1),
  204. targetSecretKey2: []byte(targetSecretValue2),
  205. },
  206. }
  207. tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
  208. {
  209. SecretKey: targetSecretKey1,
  210. RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
  211. Key: secretKey1,
  212. Property: "name.first",
  213. },
  214. },
  215. {
  216. SecretKey: targetSecretKey2,
  217. RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
  218. Key: secretKey1,
  219. Property: "friends.1.first",
  220. },
  221. },
  222. }
  223. }
  224. }
  225. // P12Cert case creates a secret with a p12 cert containing a privkey and cert bundled together.
  226. // It uses templating to generate a k8s secret of type tls with pem values
  227. func P12Cert(f *framework.Framework) (string, func(*framework.TestCase)) {
  228. return "[common] should sync p12 configurated cert secrets with template", func(tc *framework.TestCase) {
  229. cloudSecretName := fmt.Sprintf("%s-%s", f.Namespace.Name, "p12-cert-example")
  230. certPEM := `-----BEGIN CERTIFICATE-----
  231. MIIFQjCCBCqgAwIBAgISBHszg5W2maz/7CIxGrf7mqukMA0GCSqGSIb3DQEBCwUA
  232. MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
  233. EwJSMzAeFw0yMTA3MjQxMjQyMzNaFw0yMTEwMjIxMjQyMzFaMCgxJjAkBgNVBAMT
  234. HXRlbXBvcmFyeS5leHRlcm5hbC1zZWNyZXRzLmlvMIIBIjANBgkqhkiG9w0BAQEF
  235. AAOCAQ8AMIIBCgKCAQEAyRROdZskA8qnGnoMgQ5Ry5MVY/lgo3HzlhKq02u23J2w
  236. 14w+LiEU2hcSJKYv5OXysbfq7M52u2zXYZXs6krkQZlYNpFw7peZ0JtUbVkSpST/
  237. X4b1GJKDSkRs7fTi+v+pb9OT9rTbtd8jfGe/YCe5rjXEm/ih2DgS13737lKCD5n6
  238. 3QUOG7CR+SKFeRXOGkncqJHAyRkpNfAmS8m1C+ucodfjSFoqAwwVGx7eyEktG4s/
  239. JbwLEb03hGrP15vnnOgxQmiAzWskxhMyHX6vmA71Oq4F3RVsuD3CEjKzgJ2+ghk3
  240. BIY3DZSfSReWSMYM573YFglENi+qJK012XnFmZcevwIDAQABo4ICWjCCAlYwDgYD
  241. VR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNV
  242. HRMBAf8EAjAAMB0GA1UdDgQWBBRvn1wGi46XcyhRIIxJkSSUoCyoNzAfBgNVHSME
  243. GDAWgBQULrMXt1hWy65QCUDmH6+dixTCxjBVBggrBgEFBQcBAQRJMEcwIQYIKwYB
  244. BQUHMAGGFWh0dHA6Ly9yMy5vLmxlbmNyLm9yZzAiBggrBgEFBQcwAoYWaHR0cDov
  245. L3IzLmkubGVuY3Iub3JnLzAoBgNVHREEITAfgh10ZW1wb3JhcnkuZXh0ZXJuYWwt
  246. c2VjcmV0cy5pbzBMBgNVHSAERTBDMAgGBmeBDAECATA3BgsrBgEEAYLfEwEBATAo
  247. MCYGCCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCCAQYGCisG
  248. AQQB1nkCBAIEgfcEgfQA8gB3APZclC/RdzAiFFQYCDCUVo7jTRMZM7/fDC8gC8xO
  249. 8WTjAAABetjA0asAAAQDAEgwRgIhAPYbBNim7q3P0qmD9IrAx1E1fEClYpoLrAVs
  250. 4LGBkQobAiEA+IaTPWs9eHmqtCwar96PNxE0Iucak0DYkgfcWJT5gfYAdwBvU3as
  251. MfAxGdiZAKRRFf93FRwR2QLBACkGjbIImjfZEwAAAXrYwNJTAAAEAwBIMEYCIQDY
  252. xWJKFljK1AW2z/uVsU7TwcAAcIqUf5/nhS04JAwpfwIhANDTvwvcRvPebU7fv6dq
  253. lNH1g2Oyv/4Vm7W+Vrc5cFD0MA0GCSqGSIb3DQEBCwUAA4IBAQAR29s3pDGZbNPN
  254. 5K+Zqg9UDT8s+P0fb9r97T7hWEFkiUtG4bz7QvGzSoDXhD/DZkdjLmkX7+bLiE3L
  255. hRSSYe+Am+Bw5soyzefX2FHAUeOLeK0mJhOrdiKqrW4nnvOOJWLkcWS799kW2z7j
  256. 2MgUWTOz/xXGUOWHt1KjyoM31G3shoAIB9lg3lHbuVIyDd3yyUpjt0zevVdYrO9G
  257. CgI2mJfv26EiddBvgudzN+R5Ayis9czaFHu8gpplaf9DahaKs1Uys6lg0HnzRn3l
  258. XMYitHfpGhc+DTTiTWMQ13J0b1j4yv8A7ZaG2366aa28oSTD6eQFhmVCBwa54j++
  259. IOwzHn5R
  260. -----END CERTIFICATE-----
  261. `
  262. privkeyPEM := `-----BEGIN PRIVATE KEY-----
  263. MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDJFE51myQDyqca
  264. egyBDlHLkxVj+WCjcfOWEqrTa7bcnbDXjD4uIRTaFxIkpi/k5fKxt+rszna7bNdh
  265. lezqSuRBmVg2kXDul5nQm1RtWRKlJP9fhvUYkoNKRGzt9OL6/6lv05P2tNu13yN8
  266. Z79gJ7muNcSb+KHYOBLXfvfuUoIPmfrdBQ4bsJH5IoV5Fc4aSdyokcDJGSk18CZL
  267. ybUL65yh1+NIWioDDBUbHt7ISS0biz8lvAsRvTeEas/Xm+ec6DFCaIDNayTGEzId
  268. fq+YDvU6rgXdFWy4PcISMrOAnb6CGTcEhjcNlJ9JF5ZIxgznvdgWCUQ2L6okrTXZ
  269. ecWZlx6/AgMBAAECggEBAI9sDX5zFuAhdsk6zppqtUrn8TTq1dQe3ihnzjKYvMhl
  270. LZLA9EUA0ZexJv6/DqBMp6u9TDJ2HVgYDRQM1PxUSLTFhJb/bDayKUMS18ha5SKn
  271. 3gKsBzvsnPqnDa84oYF4Q8mAdyRb4e66ZtxAP8985kLtFPxO/llzvXS5mmwBq8Ul
  272. wlLOg5xAXubm3vgLyFm2GW9qI6ZvY9mmh1mv5ZLP8/8hikRjwJijnX3dyqqIAYnc
  273. DHjJYy2I1VxGJybqVQRquG++Tl4qLXbOUZ/lhKe62ARx/MBR9lEst5TURc9N7U3D
  274. Mgsu7FcFwqjVkig3P0XiNRWwCu0HrYee5rLXmtDnF9kCgYEA69+OuJM/RIsrLQQd
  275. 1alppgT+SFyaJM3X1MJD3yxW6Vqqvkhqe7+XCWnmVYcpHPcilWmZnnQ3PiWqPJ8A
  276. 3mIMp+Xg0ddFQXb3n7z4D0Mg4IPzvSKnlieTT1rDhhHRv/xArw1UBkF6kqcnZizZ
  277. FcWcOIt/dYodTWZzPJtLtf7QW0sCgYEA2jy0vJ5rg0/CSinkccreegC6gbbd+oE9
  278. uR/aGeu1XmnULoYYMMy7BLqd8/OiXvujbgUSUWnzbEclR88dPDkiRxDL7mYiaCn+
  279. l9jPuVB1W5x6irJdG/7lpSnLuijpkzey177ZKrlfGsOjtVZsc1ytnqTCWsF1r9eY
  280. yXCSvkJQjd0CgYEA5+vl0hh+MfBA4L9WcnpkNehc+luK+LspB7qHr81SG5qZngVo
  281. JgspAAmPf/Mo+qEI8S5m7MVKeCHitD6HRSHVXdUK7GklYIwQSJEuuxr/HaLAquyD
  282. KYH6NyGAdLfarFHka/rH7mq9kasnczCPtveZdoO7LKBD1ZHxptrvY6CLz+cCgYEA
  283. yEq2xfXPTrDA7DgOhbFfBjHs+mfOyr4a2/Czxt5hkskmB5ziTsdXTTvJA8Ay4WGp
  284. 2Kum6DmJQ3L4cDNR7ZeyMe7ke2QZZ+hC1TITU0zYqL+wZ+LTOYJzWWZGqBAsbwTL
  285. it6JiYCgHHw5n5A18Jq6bcNg7NJpJH2GqDo9M4jBTbECgYEAlMuvNExEXGVzWrGF
  286. NXHpAev64RJ2jTq59jtmxWrNvzeWJREOWd/Nt+0t+bE0sHMfgaMrhNFWiR8oesrF
  287. Jdx0ECYawviQoreDAyIXV6HouoeRbDtLZ9AJvxMoIjGcjAR2FQHc3yx4h/lf3Tfx
  288. x6HaRh+EUwU51von6M9lEF9/p5Q=
  289. -----END PRIVATE KEY-----
  290. `
  291. blockCert, _ := pem.Decode([]byte(certPEM))
  292. cert, _ := x509.ParseCertificate(blockCert.Bytes)
  293. blockPrivKey, _ := pem.Decode([]byte(privkeyPEM))
  294. privkey, _ := x509.ParsePKCS8PrivateKey(blockPrivKey.Bytes)
  295. emptyCACerts := []*x509.Certificate{}
  296. p12Cert, _ := p12.Encode(rand.Reader, privkey, cert, emptyCACerts, "")
  297. tc.Secrets = map[string]string{
  298. cloudSecretName: string(p12Cert),
  299. }
  300. tc.ExpectedSecret = &v1.Secret{
  301. Type: v1.SecretTypeTLS,
  302. Data: map[string][]byte{
  303. "tls.crt": []byte(certPEM),
  304. "tls.key": []byte(privkeyPEM),
  305. },
  306. }
  307. tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
  308. {
  309. SecretKey: "mysecret",
  310. RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
  311. Key: cloudSecretName,
  312. },
  313. },
  314. }
  315. tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
  316. Type: v1.SecretTypeTLS,
  317. Data: map[string]string{
  318. "tls.crt": "{{ .mysecret | pkcs12cert | pemCertificate }}",
  319. "tls.key": "{{ .mysecret | pkcs12key | pemPrivateKey }}",
  320. },
  321. }
  322. }
  323. }