Skip to content

Commit f504964

Browse files
justinsbtomasaschan
andcommitted
mockkubeapiserver: Support stringData when creating a secret
This is an edge case in the kube apiserver, but there is special handling for the stringData field of a secret, that is mapped to base64 data. Co-authored-by: Tomas Aschan <[email protected]>
1 parent dc6d6ba commit f504964

File tree

12 files changed

+318
-2
lines changed

12 files changed

+318
-2
lines changed

dev/update-golden

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ chmod +x bin/kubectl
1919
export PATH="${REPO_ROOT}/bin:$PATH"
2020
echo "kubectl version is $(kubectl version --client)"
2121

22-
WRITE_GOLDEN_OUTPUT=1 go test -count=1 -v ./...
22+
WRITE_GOLDEN_OUTPUT=1 go test -count=1 -v ./...
23+
24+
cd "${REPO_ROOT}/mockkubeapiserver"
25+
WRITE_GOLDEN_OUTPUT=1 go test -count=1 -v ./...

mockkubeapiserver/go.mod

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,34 @@ toolchain go1.22.0
77
require (
88
github.com/google/go-cmp v0.6.0
99
k8s.io/apimachinery v0.26.2
10+
k8s.io/client-go v0.26.2
1011
k8s.io/klog/v2 v2.110.1
1112
sigs.k8s.io/structured-merge-diff/v4 v4.4.1
1213
sigs.k8s.io/yaml v1.4.0
1314
)
1415

1516
require (
17+
github.com/davecgh/go-spew v1.1.1 // indirect
1618
github.com/go-logr/logr v1.4.1 // indirect
1719
github.com/gogo/protobuf v1.3.2 // indirect
20+
github.com/golang/protobuf v1.5.3 // indirect
1821
github.com/google/gofuzz v1.2.0 // indirect
1922
github.com/google/uuid v1.3.0 // indirect
2023
github.com/json-iterator/go v1.1.12 // indirect
2124
github.com/kr/text v0.2.0 // indirect
2225
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
2326
github.com/modern-go/reflect2 v1.0.2 // indirect
2427
golang.org/x/net v0.19.0 // indirect
28+
golang.org/x/oauth2 v0.12.0 // indirect
29+
golang.org/x/sys v0.16.0 // indirect
30+
golang.org/x/term v0.15.0 // indirect
2531
golang.org/x/text v0.14.0 // indirect
32+
golang.org/x/time v0.3.0 // indirect
33+
google.golang.org/appengine v1.6.7 // indirect
34+
google.golang.org/protobuf v1.31.0 // indirect
2635
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
2736
gopkg.in/inf.v0 v0.9.1 // indirect
2837
gopkg.in/yaml.v2 v2.4.0 // indirect
29-
k8s.io/client-go v0.26.2 // indirect
3038
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
3139
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
3240
)

mockkubeapiserver/go.sum

+32
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,21 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
22
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
33
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
44
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5+
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
56
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
67
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
78
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
9+
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
10+
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
11+
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
812
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
913
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
14+
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
15+
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
16+
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
17+
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
18+
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
19+
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
1020
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1121
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
1222
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -15,6 +25,7 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
1525
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
1626
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
1727
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
28+
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
1829
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
1930
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
2031
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@@ -26,11 +37,13 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
2637
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
2738
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
2839
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
40+
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
2941
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
3042
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
3143
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
3244
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
3345
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
46+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
3447
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3548
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3649
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
@@ -47,21 +60,31 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
4760
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
4861
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
4962
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
63+
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
5064
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
5165
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
5266
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
5367
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
5468
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
69+
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
70+
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
5571
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5672
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5773
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5874
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5975
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6076
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
77+
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
78+
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
79+
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
80+
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
6181
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
82+
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
6283
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
6384
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
6485
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
86+
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
87+
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
6588
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
6689
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
6790
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -70,6 +93,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
7093
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
7194
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
7295
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
96+
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
97+
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
98+
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
99+
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
100+
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
101+
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
73102
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
74103
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
75104
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@@ -80,14 +109,17 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
80109
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
81110
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
82111
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
112+
k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw=
83113
k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ=
84114
k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
85115
k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc=
86116
k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU=
87117
k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI=
88118
k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU=
119+
k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A=
89120
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
90121
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
122+
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
91123
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
92124
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
93125
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=

mockkubeapiserver/patchresource.go

+8
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ func (req *patchResource) Run(ctx context.Context, s *MockKubeAPIServer) error {
8585
patched.SetGeneration(1)
8686
}
8787

88+
if err := beforeObjectCreation(ctx, patched); err != nil {
89+
return err
90+
}
91+
8892
if err := resource.CreateObject(ctx, id, patched); err != nil {
8993
return err
9094
}
@@ -130,6 +134,10 @@ func (req *patchResource) Run(ctx context.Context, s *MockKubeAPIServer) error {
130134
klog.Infof("skipping write, object not changed")
131135
return req.writeResponse(existingObj)
132136
} else {
137+
if err := beforeObjectCreation(ctx, updated); err != nil {
138+
return err
139+
}
140+
133141
if resource.SetsGeneration() {
134142
specIsSame := reflect.DeepEqual(existingObj.Object["spec"], updated.Object["spec"])
135143
if !specIsSame {

mockkubeapiserver/postresource.go

+48
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package mockkubeapiserver
1818

1919
import (
2020
"context"
21+
"encoding/base64"
2122
"fmt"
2223
"io"
2324
"net/http"
@@ -73,8 +74,55 @@ func (req *postResource) Run(ctx context.Context, s *MockKubeAPIServer) error {
7374
obj.SetGeneration(1)
7475
}
7576

77+
if err := beforeObjectCreation(ctx, obj); err != nil {
78+
return err
79+
}
80+
7681
if err := resource.CreateObject(ctx, id, obj); err != nil {
7782
return err
7883
}
7984
return req.writeResponse(obj)
8085
}
86+
87+
var secretGVK = schema.GroupVersionKind{
88+
Group: "",
89+
Version: "v1",
90+
Kind: "Secret",
91+
}
92+
93+
func beforeObjectCreation(ctx context.Context, obj *unstructured.Unstructured) error {
94+
gvk := obj.GroupVersionKind()
95+
if gvk == secretGVK {
96+
return beforeSecretCreation(ctx, obj)
97+
}
98+
return nil
99+
}
100+
101+
func beforeSecretCreation(ctx context.Context, obj *unstructured.Unstructured) error {
102+
// If there is any stringData, merge it into data
103+
stringData, _, err := unstructured.NestedStringMap(obj.Object, "stringData")
104+
if err != nil {
105+
return fmt.Errorf("getting Secret stringData: %w", err)
106+
}
107+
if len(stringData) == 0 {
108+
return nil
109+
}
110+
111+
// Get a copy of data
112+
data, _, err := unstructured.NestedStringMap(obj.Object, "data")
113+
if err != nil {
114+
return fmt.Errorf("getting Secret data: %w", err)
115+
}
116+
if data == nil {
117+
data = make(map[string]string)
118+
}
119+
for k, v := range stringData {
120+
data[k] = base64.StdEncoding.EncodeToString([]byte(v))
121+
}
122+
if err := unstructured.SetNestedStringMap(obj.Object, data, "data"); err != nil {
123+
return fmt.Errorf("setting Secret data: %w", err)
124+
}
125+
unstructured.RemoveNestedField(obj.Object, "stringData")
126+
127+
return nil
128+
}

mockkubeapiserver/putresource.go

+4
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ func (req *putResource) Run(ctx context.Context, s *MockKubeAPIServer) error {
9898
}
9999
}
100100

101+
if err := beforeObjectCreation(ctx, updated); err != nil {
102+
return err
103+
}
104+
101105
if err := resource.UpdateObject(ctx, id, updated); err != nil {
102106
return err
103107
}

mockkubeapiserver/storage/hook.go

+1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ package storage
22

33
// A Hook implements a lightweight watch on all objects, intended for use to mock controller behaviour.
44
type Hook interface {
5+
// OnWatchEvent is called whenever a watch event is created
56
OnWatchEvent(ev *WatchEvent)
67
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package applier
2+
3+
import (
4+
"context"
5+
"net/http"
6+
"path/filepath"
7+
"testing"
8+
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/client-go/dynamic"
11+
"k8s.io/client-go/rest"
12+
"k8s.io/klog/v2"
13+
"sigs.k8s.io/kubebuilder-declarative-pattern/mockkubeapiserver"
14+
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative/pkg/manifest"
15+
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/restmapper"
16+
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/test/httprecorder"
17+
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/test/testharness"
18+
)
19+
20+
func TestGoldenTests(t *testing.T) {
21+
testharness.RunGoldenTests(t, "testdata", func(h *testharness.Harness, testdir string) {
22+
ctx := context.Background()
23+
24+
k8s, err := mockkubeapiserver.NewMockKubeAPIServer(":0")
25+
if err != nil {
26+
t.Fatalf("error building mock kube-apiserver: %v", err)
27+
}
28+
defer func() {
29+
if err := k8s.Stop(); err != nil {
30+
t.Fatalf("error closing mock kube-apiserver: %v", err)
31+
}
32+
}()
33+
34+
addr, err := k8s.StartServing()
35+
if err != nil {
36+
t.Errorf("error starting mock kube-apiserver: %v", err)
37+
}
38+
39+
klog.Infof("mock kubeapiserver will listen on %v", addr)
40+
41+
var requestLog httprecorder.RequestLog
42+
wrapTransport := func(rt http.RoundTripper) http.RoundTripper {
43+
return httprecorder.NewRecorder(rt, &requestLog)
44+
}
45+
restConfig := &rest.Config{
46+
Host: addr.String(),
47+
WrapTransport: wrapTransport,
48+
}
49+
50+
httpClient := &http.Client{
51+
Transport: wrapTransport(http.DefaultTransport),
52+
}
53+
54+
p := filepath.Join(testdir, "manifest.yaml")
55+
manifestYAML := string(h.MustReadFile(p))
56+
objects, err := manifest.ParseObjects(ctx, manifestYAML)
57+
if err != nil {
58+
t.Errorf("error parsing manifest %q: %v", p, err)
59+
}
60+
61+
restMapper, err := restmapper.NewForTest(restConfig)
62+
if err != nil {
63+
t.Fatalf("error from controllerrestmapper.NewForTest: %v", err)
64+
}
65+
66+
dynamicClient, err := dynamic.NewForConfigAndClient(restConfig, httpClient)
67+
if err != nil {
68+
t.Fatalf("building dynamic client: %v", err)
69+
}
70+
for _, obj := range objects.GetItems() {
71+
gvk := obj.GroupVersionKind()
72+
restMapping, err := restMapper.RESTMapping(gvk.GroupKind(), gvk.Version)
73+
if err != nil {
74+
t.Errorf("error getting restmapping for %v: %v", gvk, err)
75+
}
76+
77+
var applyOptions metav1.ApplyOptions
78+
applyOptions.FieldManager = "test"
79+
resource := dynamicClient.Resource(restMapping.Resource).Namespace(obj.GetNamespace())
80+
81+
if _, err := resource.Apply(ctx, obj.GetName(), obj.UnstructuredObject(), applyOptions); err != nil {
82+
t.Fatalf("error applying resource %v: %v", gvk, err)
83+
}
84+
}
85+
86+
t.Logf("replacing old url prefix %q", "http://"+restConfig.Host)
87+
requestLog.ReplaceURLPrefix("http://"+restConfig.Host, "http://kube-apiserver")
88+
requestLog.RemoveUserAgent()
89+
requestLog.SortGETs()
90+
91+
requests := requestLog.FormatHTTP()
92+
h.CompareGoldenFile(filepath.Join(testdir, "expected.yaml"), requests)
93+
})
94+
}

0 commit comments

Comments
 (0)