1
1
package adminconsole
2
2
3
3
import (
4
+ "bytes"
4
5
"context"
5
6
"encoding/base64"
6
7
"fmt"
@@ -9,13 +10,27 @@ import (
9
10
"github.com/pkg/errors"
10
11
"github.com/replicatedhq/embedded-cluster/pkg/addons/registry"
11
12
"github.com/replicatedhq/embedded-cluster/pkg/helm"
13
+ "github.com/replicatedhq/embedded-cluster/pkg/kubeutils"
12
14
"github.com/replicatedhq/embedded-cluster/pkg/spinner"
13
15
"golang.org/x/crypto/bcrypt"
14
16
corev1 "k8s.io/api/core/v1"
15
17
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
18
+ "k8s.io/apimachinery/pkg/runtime"
19
+ jsonserializer "k8s.io/apimachinery/pkg/runtime/serializer/json"
16
20
"sigs.k8s.io/controller-runtime/pkg/client"
17
21
)
18
22
23
+ var (
24
+ serializer runtime.Serializer
25
+ )
26
+
27
+ func init () {
28
+ scheme := kubeutils .Scheme
29
+ serializer = jsonserializer .NewSerializerWithOptions (jsonserializer .DefaultMetaFactory , scheme , scheme , jsonserializer.SerializerOptions {
30
+ Yaml : true ,
31
+ })
32
+ }
33
+
19
34
func (a * AdminConsole ) Install (ctx context.Context , kcli client.Client , hcli helm.Client , overrides []string , writer * spinner.MessageWriter ) error {
20
35
// some resources are not part of the helm chart and need to be created before the chart is installed
21
36
// TODO: move this to the helm chart
@@ -28,40 +43,49 @@ func (a *AdminConsole) Install(ctx context.Context, kcli client.Client, hcli hel
28
43
return errors .Wrap (err , "generate helm values" )
29
44
}
30
45
31
- _ , err = hcli . Install ( ctx , helm.InstallOptions {
46
+ opts := helm.InstallOptions {
32
47
ReleaseName : releaseName ,
33
48
ChartPath : a .ChartLocation (),
34
49
ChartVersion : Metadata .Version ,
35
50
Values : values ,
36
51
Namespace : namespace ,
37
52
Labels : getBackupLabels (),
38
- })
39
- if err != nil {
40
- return errors .Wrap (err , "helm install" )
41
53
}
42
54
43
- // install the application
44
-
45
- if a .KotsInstaller != nil {
46
- err := a .KotsInstaller (writer )
55
+ if a .DryRun {
56
+ manifests , err := hcli .Render (ctx , opts )
47
57
if err != nil {
48
- return err
58
+ return errors .Wrap (err , "dry run render" )
59
+ }
60
+ a .dryRunManifests = append (a .dryRunManifests , manifests ... )
61
+ } else {
62
+ _ , err = hcli .Install (ctx , opts )
63
+ if err != nil {
64
+ return errors .Wrap (err , "helm install" )
65
+ }
66
+
67
+ // install the application
68
+ if a .KotsInstaller != nil {
69
+ err := a .KotsInstaller (writer )
70
+ if err != nil {
71
+ return err
72
+ }
49
73
}
50
74
}
51
75
52
76
return nil
53
77
}
54
78
55
79
func (a * AdminConsole ) createPreRequisites (ctx context.Context , kcli client.Client ) error {
56
- if err := createNamespace (ctx , kcli , namespace ); err != nil {
80
+ if err := a . createNamespace (ctx , kcli , namespace ); err != nil {
57
81
return errors .Wrap (err , "create namespace" )
58
82
}
59
83
60
- if err := createPasswordSecret (ctx , kcli , namespace , a .Password ); err != nil {
84
+ if err := a . createPasswordSecret (ctx , kcli , namespace , a .Password ); err != nil {
61
85
return errors .Wrap (err , "create kots password secret" )
62
86
}
63
87
64
- if err := createCAConfigmap (ctx , kcli , namespace , a .PrivateCAs ); err != nil {
88
+ if err := a . createCAConfigmap (ctx , kcli , namespace , a .PrivateCAs ); err != nil {
65
89
return errors .Wrap (err , "create kots CA configmap" )
66
90
}
67
91
@@ -70,90 +94,115 @@ func (a *AdminConsole) createPreRequisites(ctx context.Context, kcli client.Clie
70
94
if err != nil {
71
95
return errors .Wrap (err , "get registry cluster IP" )
72
96
}
73
- if err := createRegistrySecret (ctx , kcli , namespace , registryIP ); err != nil {
97
+ if err := a . createRegistrySecret (ctx , kcli , namespace , registryIP ); err != nil {
74
98
return errors .Wrap (err , "create registry secret" )
75
99
}
76
100
}
77
101
78
102
return nil
79
103
}
80
104
81
- func createNamespace (ctx context.Context , kcli client.Client , namespace string ) error {
82
- ns := corev1.Namespace {
83
- ObjectMeta : metav1.ObjectMeta {
84
- Name : namespace ,
85
- },
86
- }
87
- if err := kcli .Create (ctx , & ns ); client .IgnoreAlreadyExists (err ) != nil {
88
- return err
89
- }
90
- return nil
91
- }
92
-
93
- func createPasswordSecret (ctx context.Context , kcli client.Client , namespace string , password string ) error {
94
- passwordBcrypt , err := bcrypt .GenerateFromPassword ([]byte (password ), 10 )
105
+ func (a * AdminConsole ) createCAConfigmap (ctx context.Context , cli client.Client , namespace string , privateCAs []string ) error {
106
+ cas , err := privateCAsToMap (privateCAs )
95
107
if err != nil {
96
- return errors .Wrap (err , "generate bcrypt from password " )
108
+ return errors .Wrap (err , "create private cas map " )
97
109
}
98
110
99
- kotsPasswordSecret := corev1.Secret {
111
+ kotsCAConfigmap := corev1.ConfigMap {
100
112
TypeMeta : metav1.TypeMeta {
101
- Kind : "Secret " ,
113
+ Kind : "ConfigMap " ,
102
114
APIVersion : "v1" ,
103
115
},
104
116
ObjectMeta : metav1.ObjectMeta {
105
- Name : "kotsadm-password " ,
117
+ Name : "kotsadm-private-cas " ,
106
118
Namespace : namespace ,
107
119
Labels : map [string ]string {
108
120
"kots.io/kotsadm" : "true" ,
109
121
"replicated.com/disaster-recovery" : "infra" ,
110
122
"replicated.com/disaster-recovery-chart" : "admin-console" ,
111
123
},
112
124
},
113
- Data : map [string ][]byte {
114
- "passwordBcrypt" : []byte (passwordBcrypt ),
115
- },
125
+ Data : cas ,
116
126
}
117
127
118
- err = kcli .Create (ctx , & kotsPasswordSecret )
119
- if err != nil {
120
- return errors .Wrap (err , "create kotsadm-password secret" )
128
+ if a .DryRun {
129
+ b := bytes .NewBuffer (nil )
130
+ if err := serializer .Encode (& kotsCAConfigmap , b ); err != nil {
131
+ return errors .Wrap (err , "serialize CA configmap" )
132
+ }
133
+ a .dryRunManifests = append (a .dryRunManifests , b .Bytes ())
134
+ } else {
135
+ if err := cli .Create (ctx , & kotsCAConfigmap ); client .IgnoreAlreadyExists (err ) != nil {
136
+ return errors .Wrap (err , "create kotsadm-private-cas configmap" )
137
+ }
121
138
}
122
139
123
140
return nil
124
141
}
125
142
126
- func createCAConfigmap (ctx context.Context , cli client.Client , namespace string , privateCAs []string ) error {
127
- cas , err := privateCAsToMap (privateCAs )
143
+ func (a * AdminConsole ) createNamespace (ctx context.Context , kcli client.Client , namespace string ) error {
144
+ ns := corev1.Namespace {
145
+ ObjectMeta : metav1.ObjectMeta {
146
+ Name : namespace ,
147
+ },
148
+ }
149
+
150
+ if a .DryRun {
151
+ b := bytes .NewBuffer (nil )
152
+ if err := serializer .Encode (& ns , b ); err != nil {
153
+ return errors .Wrap (err , "serialize namespace" )
154
+ }
155
+ a .dryRunManifests = append (a .dryRunManifests , b .Bytes ())
156
+ } else {
157
+ if err := kcli .Create (ctx , & ns ); client .IgnoreAlreadyExists (err ) != nil {
158
+ return err
159
+ }
160
+ }
161
+ return nil
162
+ }
163
+
164
+ func (a * AdminConsole ) createPasswordSecret (ctx context.Context , kcli client.Client , namespace string , password string ) error {
165
+ passwordBcrypt , err := bcrypt .GenerateFromPassword ([]byte (password ), 10 )
128
166
if err != nil {
129
- return errors .Wrap (err , "create private cas map " )
167
+ return errors .Wrap (err , "generate bcrypt from password " )
130
168
}
131
169
132
- kotsCAConfigmap := corev1.ConfigMap {
170
+ kotsPasswordSecret := corev1.Secret {
133
171
TypeMeta : metav1.TypeMeta {
134
- Kind : "ConfigMap " ,
172
+ Kind : "Secret " ,
135
173
APIVersion : "v1" ,
136
174
},
137
175
ObjectMeta : metav1.ObjectMeta {
138
- Name : "kotsadm-private-cas " ,
176
+ Name : "kotsadm-password " ,
139
177
Namespace : namespace ,
140
178
Labels : map [string ]string {
141
179
"kots.io/kotsadm" : "true" ,
142
180
"replicated.com/disaster-recovery" : "infra" ,
143
181
"replicated.com/disaster-recovery-chart" : "admin-console" ,
144
182
},
145
183
},
146
- Data : cas ,
184
+ Data : map [string ][]byte {
185
+ "passwordBcrypt" : []byte (passwordBcrypt ),
186
+ },
147
187
}
148
188
149
- if err := cli .Create (ctx , & kotsCAConfigmap ); client .IgnoreAlreadyExists (err ) != nil {
150
- return errors .Wrap (err , "create kotsadm-private-cas configmap" )
189
+ if a .DryRun {
190
+ b := bytes .NewBuffer (nil )
191
+ if err := serializer .Encode (& kotsPasswordSecret , b ); err != nil {
192
+ return errors .Wrap (err , "serialize password secret" )
193
+ }
194
+ a .dryRunManifests = append (a .dryRunManifests , b .Bytes ())
195
+ } else {
196
+ err = kcli .Create (ctx , & kotsPasswordSecret )
197
+ if err != nil {
198
+ return errors .Wrap (err , "create kotsadm-password secret" )
199
+ }
151
200
}
152
201
153
202
return nil
154
203
}
155
204
156
- func createRegistrySecret (ctx context.Context , kcli client.Client , namespace string , registryIP string ) error {
205
+ func ( a * AdminConsole ) createRegistrySecret (ctx context.Context , kcli client.Client , namespace string , registryIP string ) error {
157
206
authString := base64 .StdEncoding .EncodeToString ([]byte (fmt .Sprintf ("embedded-cluster:%s" , registry .GetRegistryPassword ())))
158
207
authConfig := fmt .Sprintf (`{"auths":{"%s:5000":{"username": "embedded-cluster", "password": "%s", "auth": "%s"}}}` , registryIP , registry .GetRegistryPassword (), authString )
159
208
@@ -177,16 +226,30 @@ func createRegistrySecret(ctx context.Context, kcli client.Client, namespace str
177
226
Type : "kubernetes.io/dockerconfigjson" ,
178
227
}
179
228
180
- err := kcli .Create (ctx , & registryCreds )
181
- if err != nil {
182
- return errors .Wrap (err , "create registry-auth secret" )
229
+ if a .DryRun {
230
+ b := bytes .NewBuffer (nil )
231
+ if err := serializer .Encode (& registryCreds , b ); err != nil {
232
+ return errors .Wrap (err , "serialize registry secret" )
233
+ }
234
+ a .dryRunManifests = append (a .dryRunManifests , b .Bytes ())
235
+ } else {
236
+ err := kcli .Create (ctx , & registryCreds )
237
+ if err != nil {
238
+ return errors .Wrap (err , "create registry-auth secret" )
239
+ }
183
240
}
184
241
185
242
return nil
186
243
}
187
244
188
245
func privateCAsToMap (privateCAs []string ) (map [string ]string , error ) {
189
246
cas := map [string ]string {}
247
+
248
+ // Handle nil privateCAs
249
+ if privateCAs == nil {
250
+ return cas , nil
251
+ }
252
+
190
253
for i , path := range privateCAs {
191
254
data , err := os .ReadFile (path )
192
255
if err != nil {
0 commit comments