Skip to content

Commit 1e7e868

Browse files
Add code for building and running helm operator binary (#110)
* [Helm] Add client package * [Helm] Add libraries of Helm operator * [Helm] Move library packages and add helm binary The following changes are made in this PR: 1. Add code for building and running helm operator binary 2. Move pkg/internal/controllerutil out of internal/ dir 3. Add separate helpers to read watches.yaml file for helm operator 4. Move `diff.go` and `types.go` from `pkg/internal` to `internal/` * [Helm] Remove from SupportsOwnerReference Signed-off-by: varshaprasad96 <[email protected]> * [test] test ci Signed-off-by: varshaprasad96 <[email protected]> * modify setOwnerReference to accept unstructred.Unstructured Signed-off-by: varshaprasad96 <[email protected]> * rearrange helm library related code to internal/legacy/
1 parent 1780093 commit 1e7e868

39 files changed

+3094
-17
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ require (
1212
github.com/onsi/gomega v1.14.0
1313
github.com/operator-framework/operator-lib v0.3.0
1414
github.com/prometheus/client_golang v1.11.0
15+
github.com/sergi/go-diff v1.1.0
1516
github.com/sirupsen/logrus v1.8.1
1617
github.com/spf13/afero v1.2.2
1718
github.com/spf13/cobra v1.1.3
1819
github.com/spf13/pflag v1.0.5
1920
github.com/stretchr/testify v1.7.0
2021
gomodules.xyz/jsonpatch/v2 v2.2.0
22+
gomodules.xyz/jsonpatch/v3 v3.0.1
2123
helm.sh/helm/v3 v3.6.2
2224
k8s.io/api v0.22.1
2325
k8s.io/apiextensions-apiserver v0.22.1

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,10 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
12631263
gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
12641264
gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY=
12651265
gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
1266+
gomodules.xyz/jsonpatch/v3 v3.0.1 h1:Te7hKxV52TKCbNYq3t84tzKav3xhThdvSsSp/W89IyI=
1267+
gomodules.xyz/jsonpatch/v3 v3.0.1/go.mod h1:CBhndykehEwTOlEfnsfJwvkFQbSN8YZFr9M+cIHAJto=
1268+
gomodules.xyz/orderedmap v0.1.0 h1:fM/+TGh/O1KkqGR5xjTKg6bU8OKBkg7p0Y+x/J9m8Os=
1269+
gomodules.xyz/orderedmap v0.1.0/go.mod h1:g9/TPUCm1t2gwD3j3zfV8uylyYhVdCNSi+xCEIu7yTU=
12661270
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
12671271
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
12681272
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=

internal/cmd/helm-operator/run/cmd.go

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
// Copyright 2020 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package run
16+
17+
import (
18+
"errors"
19+
"flag"
20+
"fmt"
21+
"os"
22+
"runtime"
23+
"strings"
24+
25+
"github.com/operator-framework/helm-operator-plugins/internal/flags"
26+
"github.com/operator-framework/helm-operator-plugins/internal/legacy/controller"
27+
"github.com/operator-framework/helm-operator-plugins/internal/legacy/release"
28+
watches "github.com/operator-framework/helm-operator-plugins/internal/legacy/watches"
29+
"github.com/operator-framework/helm-operator-plugins/internal/metrics"
30+
"github.com/operator-framework/helm-operator-plugins/internal/version"
31+
helmmgr "github.com/operator-framework/helm-operator-plugins/pkg/manager"
32+
"github.com/spf13/cobra"
33+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34+
ctrl "sigs.k8s.io/controller-runtime"
35+
"sigs.k8s.io/controller-runtime/pkg/cache"
36+
"sigs.k8s.io/controller-runtime/pkg/client/config"
37+
"sigs.k8s.io/controller-runtime/pkg/healthz"
38+
logf "sigs.k8s.io/controller-runtime/pkg/log"
39+
zapf "sigs.k8s.io/controller-runtime/pkg/log/zap"
40+
"sigs.k8s.io/controller-runtime/pkg/manager"
41+
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
42+
crmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
43+
)
44+
45+
var log = logf.Log.WithName("cmd")
46+
47+
func printVersion() {
48+
log.Info("Version",
49+
"Go Version", runtime.Version(),
50+
"GOOS", runtime.GOOS,
51+
"GOARCH", runtime.GOARCH,
52+
"helm-operator", version.GitVersion,
53+
"commit", version.GitCommit)
54+
}
55+
56+
func NewCmd() *cobra.Command {
57+
f := &flags.Flags{}
58+
zapfs := flag.NewFlagSet("zap", flag.ExitOnError)
59+
opts := &zapf.Options{}
60+
opts.BindFlags(zapfs)
61+
62+
cmd := &cobra.Command{
63+
Use: "run",
64+
Short: "Run the operator",
65+
Run: func(cmd *cobra.Command, _ []string) {
66+
logf.SetLogger(zapf.New(zapf.UseFlagOptions(opts)))
67+
run(cmd, f)
68+
},
69+
}
70+
71+
f.AddTo(cmd.Flags())
72+
cmd.Flags().AddGoFlagSet(zapfs)
73+
return cmd
74+
}
75+
76+
func run(cmd *cobra.Command, f *flags.Flags) {
77+
printVersion()
78+
metrics.RegisterBuildInfo(crmetrics.Registry)
79+
80+
// Load config options from the config at f.ManagerConfigPath.
81+
// These options will not override those set by flags.
82+
var (
83+
options manager.Options
84+
err error
85+
)
86+
if f.ManagerConfigPath != "" {
87+
cfgLoader := ctrl.ConfigFile().AtPath(f.ManagerConfigPath)
88+
if options, err = options.AndFrom(cfgLoader); err != nil {
89+
log.Error(err, "Unable to load the manager config file")
90+
os.Exit(1)
91+
}
92+
}
93+
exitIfUnsupported(options)
94+
95+
cfg, err := config.GetConfig()
96+
if err != nil {
97+
log.Error(err, "Failed to get config.")
98+
os.Exit(1)
99+
}
100+
101+
// TODO(2.0.0): remove
102+
// Deprecated: OPERATOR_NAME environment variable is an artifact of the
103+
// legacy operator-sdk project scaffolding. Flag `--leader-election-id`
104+
// should be used instead.
105+
if operatorName, found := os.LookupEnv("OPERATOR_NAME"); found {
106+
log.Info("Environment variable OPERATOR_NAME has been deprecated, use --leader-election-id instead.")
107+
if cmd.Flags().Changed("leader-election-id") {
108+
log.Info("Ignoring OPERATOR_NAME environment variable since --leader-election-id is set")
109+
} else if options.LeaderElectionID == "" {
110+
// Only set leader election ID using OPERATOR_NAME if unset everywhere else,
111+
// since this env var is deprecated.
112+
options.LeaderElectionID = operatorName
113+
}
114+
}
115+
116+
//TODO(2.0.0): remove the following checks. they are required just because of the flags deprecation
117+
if cmd.Flags().Changed("leader-elect") && cmd.Flags().Changed("enable-leader-election") {
118+
log.Error(errors.New("only one of --leader-elect and --enable-leader-election may be set"), "invalid flags usage")
119+
os.Exit(1)
120+
}
121+
122+
if cmd.Flags().Changed("metrics-addr") && cmd.Flags().Changed("metrics-bind-address") {
123+
log.Error(errors.New("only one of --metrics-addr and --metrics-bind-address may be set"), "invalid flags usage")
124+
os.Exit(1)
125+
}
126+
127+
// Set default manager options
128+
options = f.ToManagerOptions(options)
129+
130+
if options.NewClient == nil {
131+
options.NewClient = helmmgr.NewCachingClientFunc()
132+
}
133+
namespace, found := os.LookupEnv(helmmgr.WatchNamespaceEnvVar)
134+
log = log.WithValues("Namespace", namespace)
135+
if found {
136+
log.V(1).Info(fmt.Sprintf("Setting namespace with value in %s", helmmgr.WatchNamespaceEnvVar))
137+
if namespace == metav1.NamespaceAll {
138+
log.Info("Watching all namespaces.")
139+
options.Namespace = metav1.NamespaceAll
140+
} else {
141+
if strings.Contains(namespace, ",") {
142+
log.Info("Watching multiple namespaces.")
143+
options.NewCache = cache.MultiNamespacedCacheBuilder(strings.Split(namespace, ","))
144+
} else {
145+
log.Info("Watching single namespace.")
146+
options.Namespace = namespace
147+
}
148+
}
149+
} else if options.Namespace == "" {
150+
log.Info(fmt.Sprintf("Watch namespaces not configured by environment variable %s or file. "+
151+
"Watching all namespaces.", helmmgr.WatchNamespaceEnvVar))
152+
options.Namespace = metav1.NamespaceAll
153+
}
154+
155+
mgr, err := manager.New(cfg, options)
156+
if err != nil {
157+
log.Error(err, "Failed to create a new manager")
158+
os.Exit(1)
159+
}
160+
161+
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
162+
log.Error(err, "Unable to set up health check")
163+
os.Exit(1)
164+
}
165+
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
166+
log.Error(err, "Unable to set up ready check")
167+
os.Exit(1)
168+
}
169+
170+
ws, err := watches.Load(f.WatchesFile)
171+
if err != nil {
172+
log.Error(err, "Failed to create new manager factories.")
173+
os.Exit(1)
174+
}
175+
176+
for _, w := range ws {
177+
// Register the controller with the factory.
178+
err := controller.Add(mgr, controller.WatchOptions{
179+
Namespace: namespace,
180+
GVK: w.GroupVersionKind,
181+
ManagerFactory: release.NewManagerFactory(mgr, w.ChartDir),
182+
ReconcilePeriod: f.ReconcilePeriod,
183+
WatchDependentResources: *w.WatchDependentResources,
184+
OverrideValues: w.OverrideValues,
185+
MaxConcurrentReconciles: f.MaxConcurrentReconciles,
186+
Selector: w.Selector,
187+
})
188+
if err != nil {
189+
log.Error(err, "Failed to add manager factory to controller.")
190+
os.Exit(1)
191+
}
192+
}
193+
194+
// Start the Cmd
195+
if err = mgr.Start(signals.SetupSignalHandler()); err != nil {
196+
log.Error(err, "Manager exited non-zero.")
197+
os.Exit(1)
198+
}
199+
200+
}
201+
202+
// exitIfUnsupported prints an error containing unsupported field names and exits
203+
// if any of those fields are not their default values.
204+
func exitIfUnsupported(options manager.Options) {
205+
var keys []string
206+
// The below options are webhook-specific, which is not supported by ansible.
207+
if options.CertDir != "" {
208+
keys = append(keys, "certDir")
209+
}
210+
if options.Host != "" {
211+
keys = append(keys, "host")
212+
}
213+
if options.Port != 0 {
214+
keys = append(keys, "port")
215+
}
216+
217+
if len(keys) > 0 {
218+
log.Error(fmt.Errorf("%s set in manager options", strings.Join(keys, ", ")), "unsupported fields")
219+
os.Exit(1)
220+
}
221+
}
File renamed without changes.

0 commit comments

Comments
 (0)