Skip to content

Commit fb27c74

Browse files
committed
wip
Signed-off-by: Ilya Lesikov <[email protected]>
1 parent 9e4279f commit fb27c74

File tree

5 files changed

+94
-104
lines changed

5 files changed

+94
-104
lines changed

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ require (
1818
github.com/go-openapi/validate v0.19.12
1919
github.com/goccy/go-graphviz v0.2.9
2020
github.com/gofrs/uuid/v5 v5.3.2
21+
github.com/gookit/color v1.5.4
2122
github.com/hashicorp/go-multierror v1.1.1
2223
github.com/kennygrant/sanitize v1.2.4
2324
github.com/onsi/gomega v1.37.0
2425
github.com/pkg/errors v0.9.1
2526
github.com/stretchr/testify v1.10.0
2627
github.com/tidwall/gjson v1.17.0
27-
github.com/werf/nelm v1.2.0
28+
github.com/werf/nelm v1.4.2-0.20250527153113-7fe26b436d2d
2829
gopkg.in/alecthomas/kingpin.v2 v2.2.6
2930
gopkg.in/yaml.v3 v3.0.1
3031
helm.sh/helm/v3 v3.15.4
@@ -115,7 +116,6 @@ require (
115116
github.com/google/gofuzz v1.2.0 // indirect
116117
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
117118
github.com/google/uuid v1.6.0 // indirect
118-
github.com/gookit/color v1.5.4 // indirect
119119
github.com/gorilla/mux v1.8.1 // indirect
120120
github.com/gorilla/websocket v1.5.1 // indirect
121121
github.com/gosuri/uitable v0.0.4 // indirect
@@ -182,8 +182,8 @@ require (
182182
github.com/tidwall/pretty v1.2.1 // indirect
183183
github.com/tidwall/sjson v1.2.5 // indirect
184184
github.com/wI2L/jsondiff v0.5.0 // indirect
185-
github.com/werf/3p-helm v0.0.0-20250423070931-cbf97ffb83ad // indirect
186-
github.com/werf/common-go v0.0.0-20250417171011-97dbede6f27c // indirect
185+
github.com/werf/3p-helm v0.0.0-20250523104754-b2fc45bbcb87 // indirect
186+
github.com/werf/common-go v0.0.0-20250520111308-b0eda28dde0d // indirect
187187
github.com/werf/kubedog v0.13.1-0.20250411133038-3d8084fab0ec // indirect
188188
github.com/werf/lockgate v0.1.1 // indirect
189189
github.com/werf/logboek v0.6.1 // indirect

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -595,18 +595,18 @@ github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6
595595
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
596596
github.com/wI2L/jsondiff v0.5.0 h1:RRMTi/mH+R2aXcPe1VYyvGINJqQfC3R+KSEakuU1Ikw=
597597
github.com/wI2L/jsondiff v0.5.0/go.mod h1:qqG6hnK0Lsrz2BpIVCxWiK9ItsBCpIZQiv0izJjOZ9s=
598-
github.com/werf/3p-helm v0.0.0-20250423070931-cbf97ffb83ad h1:UNOFSDUUCBNX0HSQPzVPySs7BP7KoqofdgszTOFIrrA=
599-
github.com/werf/3p-helm v0.0.0-20250423070931-cbf97ffb83ad/go.mod h1:bwpkc66otpnI2/K8fteIF/IkrHrq6jrAFW5ETHPNa00=
600-
github.com/werf/common-go v0.0.0-20250417171011-97dbede6f27c h1:DOXbzVhCnkn9znHNgiD1UahLu59Dv48iFO/L8i4Z/bI=
601-
github.com/werf/common-go v0.0.0-20250417171011-97dbede6f27c/go.mod h1:taKDUxKmGfqNOlVx1O0ad5vdV4duKexTLO7Rch9HfeA=
598+
github.com/werf/3p-helm v0.0.0-20250523104754-b2fc45bbcb87 h1:kHySZA0mA/KtaaO8lftbSHbM5FoB29ipvXrG9esUMtY=
599+
github.com/werf/3p-helm v0.0.0-20250523104754-b2fc45bbcb87/go.mod h1:KDjmOsjFiOmj0fB0+q+0gGvlejPMjTgckLC59bX0BLg=
600+
github.com/werf/common-go v0.0.0-20250520111308-b0eda28dde0d h1:nVN0E4lQdToFiPty19uwj5TF+bCI/kAp5LLG4stWdO4=
601+
github.com/werf/common-go v0.0.0-20250520111308-b0eda28dde0d/go.mod h1:taKDUxKmGfqNOlVx1O0ad5vdV4duKexTLO7Rch9HfeA=
602602
github.com/werf/kubedog v0.13.1-0.20250411133038-3d8084fab0ec h1:tyfkagRcJVtfBF4aoxmnE6/idE7YIPo4RqdJQXNoJRg=
603603
github.com/werf/kubedog v0.13.1-0.20250411133038-3d8084fab0ec/go.mod h1:Y6pesrIN5uhFKqmHnHSoeW4jmVyZlWPFWv5SjB0rUPg=
604604
github.com/werf/lockgate v0.1.1 h1:S400JFYjtWfE4i4LY9FA8zx0fMdfui9DPrBiTciCrx4=
605605
github.com/werf/lockgate v0.1.1/go.mod h1:0yIFSLq9ausy6ejNxF5uUBf/Ib6daMAfXuCaTMZJzIE=
606606
github.com/werf/logboek v0.6.1 h1:oEe6FkmlKg0z0n80oZjLplj6sXcBeLleCkjfOOZEL2g=
607607
github.com/werf/logboek v0.6.1/go.mod h1:Gez5J4bxekyr6MxTmIJyId1F61rpO+0/V4vjCIEIZmk=
608-
github.com/werf/nelm v1.2.0 h1:CLRjpd9SFnpen4Y77rG/uVNe8K8aYkoRSQa6LQE4WHQ=
609-
github.com/werf/nelm v1.2.0/go.mod h1:9SR2Rfi0uE06z5bbnFRqfZTePNGnbyw9RLOVyYuV+cg=
608+
github.com/werf/nelm v1.4.2-0.20250527153113-7fe26b436d2d h1:U/PL54kLXeT5C+CkIxX5OEgj4JMhhfUSVvywEr3veyQ=
609+
github.com/werf/nelm v1.4.2-0.20250527153113-7fe26b436d2d/go.mod h1:2BaEAXz2OHy3fQyNfFe65A8IPY25E5SX1JomFBUAIxg=
610610
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
611611
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
612612
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=

pkg/helm/nelm/nelm.go

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,36 @@ package nelm
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"log/slog"
78
"os"
8-
"regexp"
9+
"sort"
910
"strconv"
1011
"time"
1112

13+
"github.com/gookit/color"
1214
"helm.sh/helm/v3/pkg/cli"
1315
"k8s.io/cli-runtime/pkg/genericclioptions"
1416
"k8s.io/client-go/rest"
17+
"sigs.k8s.io/yaml"
1518

1619
"github.com/flant/addon-operator/pkg/helm/client"
1720
"github.com/flant/addon-operator/pkg/utils"
1821

1922
"github.com/werf/nelm/pkg/action"
23+
"github.com/werf/nelm/pkg/log"
2024
)
2125

22-
// FIXME(nelm): get rid of all globals in Nelm to be able to run them sequentially or in parallel
23-
2426
var (
2527
_ client.HelmClient = &NelmClient{}
2628
commonOptions *CommonOptions
2729
)
2830

2931
func Init(opts *CommonOptions, logger *NelmLogger) error {
32+
log.Default = logger
33+
color.Disable()
34+
3035
getter := buildConfigFlagsFromEnv(&commonOptions.Namespace, cli.New())
3136

3237
// FIXME(addon-operator): add all other options from getter in the same manner
@@ -38,10 +43,6 @@ func Init(opts *CommonOptions, logger *NelmLogger) error {
3843
opts.HelmDriver = os.Getenv("HELM_DRIVER")
3944
}
4045

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-
4546
commonOptions = opts
4647

4748
versionResult, err := action.Version(context.TODO(), action.VersionOptions{
@@ -57,9 +58,8 @@ func Init(opts *CommonOptions, logger *NelmLogger) error {
5758
}
5859

5960
type CommonOptions struct {
60-
Namespace string
61-
HistoryMax int32
62-
// FIXME(nelm): add global timeout to Nelm actions
61+
Namespace string
62+
HistoryMax int32
6363
Timeout time.Duration
6464
HelmDriver string
6565
KubeContext string
@@ -95,8 +95,8 @@ func (c *NelmClient) LastReleaseStatus(releaseName string) (string, string, erro
9595
ReleaseStorageDriver: commonOptions.HelmDriver,
9696
})
9797
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) {
100100
return "0", "", fmt.Errorf("get nelm release %q: %w", releaseName, err)
101101
}
102102

@@ -112,15 +112,15 @@ func (c *NelmClient) UpgradeRelease(releaseName string, chartName string, values
112112
slog.String("chart", chartName),
113113
slog.String("namespace", namespace))
114114

115-
// FIXME(nelm): deploy without installing CRDs
116-
// FIXME(nelm): allow passing labels to Release.Labels
117115
if err := action.ReleaseInstall(context.TODO(), releaseName, namespace, action.ReleaseInstallOptions{
118-
// FIXME(nelm): allow passing remote chart path
119-
ChartDirPath: chartName,
116+
Chart: chartName,
120117
ExtraLabels: c.labels,
121118
KubeContext: commonOptions.KubeContext,
119+
NoInstallCRDs: true,
122120
ReleaseHistoryLimit: int(commonOptions.HistoryMax),
121+
ReleaseLabels: labels,
123122
ReleaseStorageDriver: commonOptions.HelmDriver,
123+
Timeout: commonOptions.Timeout,
124124
ValuesFilesPaths: valuesPaths,
125125
ValuesSets: setValues,
126126
}); err != nil {
@@ -153,12 +153,11 @@ func (c *NelmClient) GetReleaseChecksum(releaseName string) (string, error) {
153153
return checksum, nil
154154
}
155155

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+
}
162161

163162
return "", fmt.Errorf("moduleChecksum label not found in nelm release %q", releaseName)
164163
}
@@ -167,6 +166,7 @@ func (c *NelmClient) DeleteRelease(releaseName string) error {
167166
c.logger.Debug(context.TODO(), "nelm release: execute nelm uninstall", slog.String("release", releaseName))
168167

169168
if err := action.ReleaseUninstall(context.TODO(), releaseName, commonOptions.Namespace, action.ReleaseUninstallOptions{
169+
Timeout: commonOptions.Timeout,
170170
KubeContext: commonOptions.KubeContext,
171171
ReleaseHistoryLimit: int(commonOptions.HistoryMax),
172172
ReleaseStorageDriver: commonOptions.HelmDriver,
@@ -193,21 +193,37 @@ func (c *NelmClient) IsReleaseExists(releaseName string) (bool, error) {
193193
}
194194

195195
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
198218
}
199219

200220
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-
203221
c.logger.Debug(context.TODO(), "Render nelm templates for chart ...",
204222
slog.String("chart", chartName),
205223
slog.String("namespace", namespace))
206224

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,
211227
ExtraLabels: c.labels,
212228
KubeContext: commonOptions.KubeContext,
213229
Remote: true,
@@ -223,8 +239,21 @@ func (c *NelmClient) Render(releaseName, chartName string, valuesPaths, setValue
223239

224240
c.logger.Info(context.TODO(), "Render nelm templates for chart was successful", slog.String("chart", chartName))
225241

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
228257
}
229258

230259
func buildConfigFlagsFromEnv(ns *string, env *cli.EnvSettings) *genericclioptions.ConfigFlags {

pkg/helm/nelm/nelm_logger.go

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,110 @@
11
package nelm
22

3-
import "context"
3+
import (
4+
"context"
5+
"fmt"
46

5-
var _ Logger = (*NelmLogger)(nil)
7+
"github.com/werf/nelm/pkg/log"
8+
)
69

7-
// FIXME(addon-operator): reference implementation here: https://github.com/werf/nelm/blob/72b22bcd3959e4083a41765ae0b7362c22a2d23d/internal/log/logboek_logger.go
8-
// Must be thread-safe.
10+
var _ log.Logger = (*NelmLogger)(nil)
911

1012
func NewNelmLogger() *NelmLogger {
1113
return &NelmLogger{}
1214
}
1315

16+
// FIXME(addon-operator): implement all methods. Must be thread-safe. Reference implementation here:
17+
// https://github.com/werf/nelm/blob/72b22bcd3959e4083a41765ae0b7362c22a2d23d/internal/log/logboek_logger.go
1418
type NelmLogger struct{}
1519

1620
func (n *NelmLogger) Trace(ctx context.Context, format string, a ...interface{}) {
17-
// FIXME(addon-operator): implement this
1821
panic("not implemented yet")
1922
}
2023

2124
func (n *NelmLogger) TraceStruct(ctx context.Context, obj interface{}, format string, a ...interface{}) {
22-
// FIXME(addon-operator): implement this
2325
panic("not implemented yet")
2426
}
2527

2628
func (n *NelmLogger) TracePush(ctx context.Context, group, format string, a ...interface{}) {
27-
// FIXME(addon-operator): implement this
2829
panic("not implemented yet")
2930
}
3031

3132
func (n *NelmLogger) TracePop(ctx context.Context, group string) {
32-
// FIXME(addon-operator): implement this
3333
panic("not implemented yet")
3434
}
3535

3636
func (n *NelmLogger) Debug(ctx context.Context, format string, a ...interface{}) {
37-
// FIXME(addon-operator): implement this
3837
panic("not implemented yet")
3938
}
4039

4140
func (n *NelmLogger) DebugPush(ctx context.Context, group, format string, a ...interface{}) {
42-
// FIXME(addon-operator): implement this
4341
panic("not implemented yet")
4442
}
4543

4644
func (n *NelmLogger) DebugPop(ctx context.Context, group string) {
47-
// FIXME(addon-operator): implement this
4845
panic("not implemented yet")
4946
}
5047

5148
func (n *NelmLogger) Info(ctx context.Context, format string, a ...interface{}) {
52-
// FIXME(addon-operator): implement this
5349
panic("not implemented yet")
5450
}
5551

5652
func (n *NelmLogger) InfoPush(ctx context.Context, group, format string, a ...interface{}) {
57-
// FIXME(addon-operator): implement this
5853
panic("not implemented yet")
5954
}
6055

6156
func (n *NelmLogger) InfoPop(ctx context.Context, group string) {
62-
// FIXME(addon-operator): implement this
6357
panic("not implemented yet")
6458
}
6559

6660
func (n *NelmLogger) Warn(ctx context.Context, format string, a ...interface{}) {
67-
// FIXME(addon-operator): implement this
6861
panic("not implemented yet")
6962
}
7063

7164
func (n *NelmLogger) WarnPush(ctx context.Context, group, format string, a ...interface{}) {
72-
// FIXME(addon-operator): implement this
7365
panic("not implemented yet")
7466
}
7567

7668
func (n *NelmLogger) WarnPop(ctx context.Context, group string) {
77-
// FIXME(addon-operator): implement this
7869
panic("not implemented yet")
7970
}
8071

8172
func (n *NelmLogger) Error(ctx context.Context, format string, a ...interface{}) {
82-
// FIXME(addon-operator): implement this
8373
panic("not implemented yet")
8474
}
8575

8676
func (n *NelmLogger) ErrorPush(ctx context.Context, group, format string, a ...interface{}) {
87-
// FIXME(addon-operator): implement this
8877
panic("not implemented yet")
8978
}
9079

9180
func (n *NelmLogger) ErrorPop(ctx context.Context, group string) {
92-
// FIXME(addon-operator): implement this
9381
panic("not implemented yet")
9482
}
9583

96-
func (n *NelmLogger) InfoBlock(ctx context.Context, opts BlockOptions, format string, a ...interface{}) error {
97-
// FIXME(addon-operator): implement this. No need to do all the stuff we do in logboek. Would be
98-
// fine to just print `----------` in the beginning and the end of the block, no indentation.
84+
// FIXME(addon-operator): example implementation
85+
func (n *NelmLogger) InfoBlock(ctx context.Context, opts log.BlockOptions, fn func()) {
86+
if opts.BlockTitle != "" {
87+
fmt.Printf("----------\n%s\n", opts.BlockTitle)
88+
}
89+
90+
fmt.Printf("----------\n")
91+
fn()
92+
fmt.Printf("----------\n")
93+
}
94+
95+
func (n *NelmLogger) InfoBlockErr(ctx context.Context, opts log.BlockOptions, fn func() error) error {
9996
panic("not implemented yet")
10097
}
10198

102-
func (n *NelmLogger) SetLevel(ctx context.Context, lvl Level) {
103-
// FIXME(addon-operator): implement this
99+
func (n *NelmLogger) SetLevel(ctx context.Context, lvl log.Level) {
104100
panic("not implemented yet")
105101
}
106102

107-
func (n *NelmLogger) Level(ctx context.Context) Level {
108-
// FIXME(addon-operator): implement this
103+
func (n *NelmLogger) Level(ctx context.Context) log.Level {
109104
panic("not implemented yet")
110105
}
111106

112-
func (n *NelmLogger) AcceptLevel(ctx context.Context, lvl Level) bool {
113-
// FIXME(addon-operator): implement this
107+
func (n *NelmLogger) AcceptLevel(ctx context.Context, lvl log.Level) bool {
114108
panic("not implemented yet")
115109
}
116110

0 commit comments

Comments
 (0)