@@ -2,31 +2,36 @@ package nelm
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
7
"log/slog"
7
8
"os"
8
- "regexp "
9
+ "sort "
9
10
"strconv"
10
11
"time"
11
12
13
+ "github.com/gookit/color"
12
14
"helm.sh/helm/v3/pkg/cli"
13
15
"k8s.io/cli-runtime/pkg/genericclioptions"
14
16
"k8s.io/client-go/rest"
17
+ "sigs.k8s.io/yaml"
15
18
16
19
"github.com/flant/addon-operator/pkg/helm/client"
17
20
"github.com/flant/addon-operator/pkg/utils"
18
21
19
22
"github.com/werf/nelm/pkg/action"
23
+ "github.com/werf/nelm/pkg/log"
20
24
)
21
25
22
- // FIXME(nelm): get rid of all globals in Nelm to be able to run them sequentially or in parallel
23
-
24
26
var (
25
27
_ client.HelmClient = & NelmClient {}
26
28
commonOptions * CommonOptions
27
29
)
28
30
29
31
func Init (opts * CommonOptions , logger * NelmLogger ) error {
32
+ log .Default = logger
33
+ color .Disable ()
34
+
30
35
getter := buildConfigFlagsFromEnv (& commonOptions .Namespace , cli .New ())
31
36
32
37
// FIXME(addon-operator): add all other options from getter in the same manner
@@ -38,10 +43,6 @@ func Init(opts *CommonOptions, logger *NelmLogger) error {
38
43
opts .HelmDriver = os .Getenv ("HELM_DRIVER" )
39
44
}
40
45
41
- // FIXME(nelm): this function does A LOT. And with what addon-operator expects from us
42
- // in regards to logging, all of this is kind of a mess now
43
- action .SetupLogging (context .TODO (), "info" , "" , "off" )
44
-
45
46
commonOptions = opts
46
47
47
48
versionResult , err := action .Version (context .TODO (), action.VersionOptions {
@@ -57,9 +58,8 @@ func Init(opts *CommonOptions, logger *NelmLogger) error {
57
58
}
58
59
59
60
type CommonOptions struct {
60
- Namespace string
61
- HistoryMax int32
62
- // FIXME(nelm): add global timeout to Nelm actions
61
+ Namespace string
62
+ HistoryMax int32
63
63
Timeout time.Duration
64
64
HelmDriver string
65
65
KubeContext string
@@ -95,8 +95,8 @@ func (c *NelmClient) LastReleaseStatus(releaseName string) (string, string, erro
95
95
ReleaseStorageDriver : commonOptions .HelmDriver ,
96
96
})
97
97
if err != nil {
98
- // FIXME(nelm): return a specific error from ReleaseGet if release not found
99
- if regexp . MustCompile ( `.+release ".+" (namespace ".+") not found` ). Match ([] byte ( err . Error ()) ) {
98
+ var releaseNotFoundErr * action. ReleaseNotFoundError
99
+ if errors . As ( err , & releaseNotFoundErr ) {
100
100
return "0" , "" , fmt .Errorf ("get nelm release %q: %w" , releaseName , err )
101
101
}
102
102
@@ -112,15 +112,15 @@ func (c *NelmClient) UpgradeRelease(releaseName string, chartName string, values
112
112
slog .String ("chart" , chartName ),
113
113
slog .String ("namespace" , namespace ))
114
114
115
- // FIXME(nelm): deploy without installing CRDs
116
- // FIXME(nelm): allow passing labels to Release.Labels
117
115
if err := action .ReleaseInstall (context .TODO (), releaseName , namespace , action.ReleaseInstallOptions {
118
- // FIXME(nelm): allow passing remote chart path
119
- ChartDirPath : chartName ,
116
+ Chart : chartName ,
120
117
ExtraLabels : c .labels ,
121
118
KubeContext : commonOptions .KubeContext ,
119
+ NoInstallCRDs : true ,
122
120
ReleaseHistoryLimit : int (commonOptions .HistoryMax ),
121
+ ReleaseLabels : labels ,
123
122
ReleaseStorageDriver : commonOptions .HelmDriver ,
123
+ Timeout : commonOptions .Timeout ,
124
124
ValuesFilesPaths : valuesPaths ,
125
125
ValuesSets : setValues ,
126
126
}); err != nil {
@@ -153,12 +153,11 @@ func (c *NelmClient) GetReleaseChecksum(releaseName string) (string, error) {
153
153
return checksum , nil
154
154
}
155
155
156
- // FIXME(nelm): expose Values in ReleaseGetResult and uncomment this
157
- // if recordedChecksum, hasKey := releaseGetResult.Values["_addonOperatorModuleChecksum"]; hasKey {
158
- // if recordedChecksumStr, ok := recordedChecksum.(string); ok {
159
- // return recordedChecksumStr, nil
160
- // }
161
- // }
156
+ if recordedChecksum , hasKey := releaseGetResult .Values ["_addonOperatorModuleChecksum" ]; hasKey {
157
+ if recordedChecksumStr , ok := recordedChecksum .(string ); ok {
158
+ return recordedChecksumStr , nil
159
+ }
160
+ }
162
161
163
162
return "" , fmt .Errorf ("moduleChecksum label not found in nelm release %q" , releaseName )
164
163
}
@@ -167,6 +166,7 @@ func (c *NelmClient) DeleteRelease(releaseName string) error {
167
166
c .logger .Debug (context .TODO (), "nelm release: execute nelm uninstall" , slog .String ("release" , releaseName ))
168
167
169
168
if err := action .ReleaseUninstall (context .TODO (), releaseName , commonOptions .Namespace , action.ReleaseUninstallOptions {
169
+ Timeout : commonOptions .Timeout ,
170
170
KubeContext : commonOptions .KubeContext ,
171
171
ReleaseHistoryLimit : int (commonOptions .HistoryMax ),
172
172
ReleaseStorageDriver : commonOptions .HelmDriver ,
@@ -193,21 +193,37 @@ func (c *NelmClient) IsReleaseExists(releaseName string) (bool, error) {
193
193
}
194
194
195
195
func (c * NelmClient ) ListReleasesNames () ([]string , error ) {
196
- // FIXME(nelm): implement ReleaseList as a Nelm action
197
- panic ("not implemented yet" )
196
+ releaseListResult , err := action .ReleaseList (context .TODO (), action.ReleaseListOptions {
197
+ KubeContext : commonOptions .KubeContext ,
198
+ OutputNoPrint : true ,
199
+ ReleaseStorageDriver : commonOptions .HelmDriver ,
200
+ })
201
+ if err != nil {
202
+ return nil , fmt .Errorf ("list nelm releases: %w" , err )
203
+ }
204
+
205
+ var releaseNames []string
206
+ for _ , release := range releaseListResult .Releases {
207
+ // FIXME(addon-operator): not sure how this can happen, it is impossible to deploy a release with no name with Nelm, and, I believe, with Helm too
208
+ if release .Name == "" {
209
+ continue
210
+ }
211
+
212
+ releaseNames = append (releaseNames , release .Name )
213
+ }
214
+
215
+ sort .Strings (releaseNames )
216
+
217
+ return releaseNames , nil
198
218
}
199
219
200
220
func (c * NelmClient ) Render (releaseName , chartName string , valuesPaths , setValues []string , namespace string , debug bool ) (string , error ) {
201
- // FIXME(nelm): debug arg is not used now. Nelm doesn't return bad manifests on error, instead it has very verbose trace log level which prints them. Do we really need to dump bad manifests on error?
202
-
203
221
c .logger .Debug (context .TODO (), "Render nelm templates for chart ..." ,
204
222
slog .String ("chart" , chartName ),
205
223
slog .String ("namespace" , namespace ))
206
224
207
- // FIXME(nelm): need to return ChartRenderResultV1, like we did in action.ChartRender
208
- err := action .ChartRender (context .TODO (), action.ChartRenderOptions {
209
- // FIXME(nelm): allow passing remote chart path
210
- ChartDirPath : chartName ,
225
+ chartRenderResult , err := action .ChartRender (context .TODO (), action.ChartRenderOptions {
226
+ Chart : chartName ,
211
227
ExtraLabels : c .labels ,
212
228
KubeContext : commonOptions .KubeContext ,
213
229
Remote : true ,
@@ -223,8 +239,21 @@ func (c *NelmClient) Render(releaseName, chartName string, valuesPaths, setValue
223
239
224
240
c .logger .Info (context .TODO (), "Render nelm templates for chart was successful" , slog .String ("chart" , chartName ))
225
241
226
- // FIXME(nelm): we should return manifests from ChartRenderResultV1
227
- panic ("not implemented yet" )
242
+ var result string
243
+ for _ , resource := range chartRenderResult .Resources {
244
+ b , err := yaml .Marshal (resource )
245
+ if err != nil {
246
+ return "" , fmt .Errorf ("marshal resource: %w" , err )
247
+ }
248
+
249
+ if result != "" {
250
+ result += "---\n "
251
+ }
252
+
253
+ result += string (b )
254
+ }
255
+
256
+ return result , nil
228
257
}
229
258
230
259
func buildConfigFlagsFromEnv (ns * string , env * cli.EnvSettings ) * genericclioptions.ConfigFlags {
0 commit comments