Skip to content

Commit 0e3eaf6

Browse files
hasbro17estroz
andauthored
Remove CSVConfig and use CSV Generator for configurable inputs and output (#2511)
Replaces config file for input and output flags Co-authored-by: Eric Stroczynski <[email protected]>
1 parent 9aed734 commit 0e3eaf6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2614
-1320
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
### Added
44

5+
- Added the [`generate csv --deploy-dir --apis-dir --crd-dir`](doc/cli/operator-sdk_generate_csv.md#options) flags to allow configuring input locations for operator manifests and API types directories to the CSV generator in lieu of a config. See the CLI reference doc or `generate csv -h` help text for more details. ([#2511](https://github.com/operator-framework/operator-sdk/pull/2511))
6+
- Added the [`generate csv --output-dir`](doc/cli/operator-sdk_generate_csv.md#options) flag to allow configuring the output location for the catalog directory. ([#2511](https://github.com/operator-framework/operator-sdk/pull/2511))
57
- The flag `--watch-namespace` and `--operator-namespace` was added to `operator-sdk run --local`, `operator-sdk test --local` and `operator-sdk cleanup` commands in order to replace the flag `--namespace` which was deprecated.([#2617](https://github.com/operator-framework/operator-sdk/pull/2617))
68
- The methods `ctx.GetOperatorNamespace()` and `ctx.GetWatchNamespace()` was added `pkg/test` in order to replace `ctx.GetNamespace()` which is deprecated. ([#2617](https://github.com/operator-framework/operator-sdk/pull/2617))
79
- The `--crd-version` flag was added to the `new`, `add api`, `add crd`, and `generate crds` commands so that users can opt-in to `v1` CRDs. ([#2684](https://github.com/operator-framework/operator-sdk/pull/2684))
@@ -29,6 +31,7 @@
2931

3032
- **Breaking Change:** remove `pkg/restmapper` which was deprecated in `v0.14.0`. Projects that use this package must switch to the `DynamicRESTMapper` implementation in [controller-runtime](https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/client/apiutil#NewDynamicRESTMapper). ([#2544](https://github.com/operator-framework/operator-sdk/pull/2544))
3133
- **Breaking Change:** remove deprecated `operator-sdk generate openapi` subcommand. ([#2740](https://github.com/operator-framework/operator-sdk/pull/2740))
34+
- **Breaking Change:** Removed CSV configuration file support (defaulting to deploy/olm-catalog/csv-config.yaml) in favor of specifying inputs to the generator via [`generate csv --deploy-dir --apis-dir --crd-dir`](doc/cli/operator-sdk_generate_csv.md#options), and configuring output locations via [`generate csv --output-dir`](doc/cli/operator-sdk_generate_csv.md#options). ([#2511](https://github.com/operator-framework/operator-sdk/pull/2511))
3235

3336
### Bug Fixes
3437

cmd/operator-sdk/bundle/create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"os"
2323
"path/filepath"
2424

25-
catalog "github.com/operator-framework/operator-sdk/internal/scaffold/olm-catalog"
25+
catalog "github.com/operator-framework/operator-sdk/internal/generate/olm-catalog"
2626
"github.com/operator-framework/operator-sdk/internal/util/projutil"
2727

2828
"github.com/operator-framework/operator-registry/pkg/lib/bundle"

cmd/operator-sdk/generate/csv.go

Lines changed: 169 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ package generate
1717
import (
1818
"fmt"
1919
"io/ioutil"
20+
"os"
2021
"path/filepath"
2122

2223
"github.com/operator-framework/operator-sdk/internal/generate/gen"
2324
gencatalog "github.com/operator-framework/operator-sdk/internal/generate/olm-catalog"
2425
"github.com/operator-framework/operator-sdk/internal/scaffold"
25-
"github.com/operator-framework/operator-sdk/internal/scaffold/input"
26-
catalog "github.com/operator-framework/operator-sdk/internal/scaffold/olm-catalog"
2726
"github.com/operator-framework/operator-sdk/internal/util/fileutil"
2827
"github.com/operator-framework/operator-sdk/internal/util/k8sutil"
2928
"github.com/operator-framework/operator-sdk/internal/util/projutil"
@@ -37,8 +36,11 @@ type csvCmd struct {
3736
csvVersion string
3837
csvChannel string
3938
fromVersion string
40-
csvConfigPath string
4139
operatorName string
40+
outputDir string
41+
deployDir string
42+
apisDir string
43+
crdDir string
4244
updateCRDs bool
4345
defaultChannel bool
4446
}
@@ -55,33 +57,133 @@ A CSV semantic version is supplied via the --csv-version flag. If your operator
5557
has already generated a CSV manifest you want to use as a base, supply its
5658
version to --from-version. Otherwise the SDK will scaffold a new CSV manifest.
5759
58-
Configure CSV generation by writing a config file 'deploy/olm-catalog/csv-config.yaml`,
59-
RunE: func(cmd *cobra.Command, args []string) error {
60-
// The CSV generator assumes that the deploy and pkg directories are
61-
// present at runtime, so this command must be run in a project's root.
62-
projutil.MustInProjectRoot()
60+
CSV input flags:
61+
--deploy-dir:
62+
The CSV's install strategy and permissions will be generated from the operator manifests
63+
(Deployment and Role/ClusterRole) present in this directory.
64+
65+
--apis-dir:
66+
The CSV annotation comments will be parsed from the Go types under this path to
67+
fill out metadata for owned APIs in spec.customresourcedefinitions.owned.
68+
69+
--crd-dir:
70+
The CSV's spec.customresourcedefinitions.owned field is generated from the CRD manifests
71+
in this path.These CRD manifests are also copied over to the bundle directory if --update-crds is set.
72+
Additionally the CR manifests will be used to populate the CSV example CRs.
73+
`,
74+
Example: `
75+
##### Generate CSV from default input paths #####
76+
$ tree pkg/apis/ deploy/
77+
pkg/apis/
78+
├── ...
79+
└── cache
80+
├── group.go
81+
└── v1alpha1
82+
├── ...
83+
└── memcached_types.go
84+
deploy/
85+
├── crds
86+
│   ├── cache.example.com_memcacheds_crd.yaml
87+
│   └── cache.example.com_v1alpha1_memcached_cr.yaml
88+
├── operator.yaml
89+
├── role.yaml
90+
├── role_binding.yaml
91+
└── service_account.yaml
92+
93+
$ operator-sdk generate csv --csv-version=0.0.1 --update-crds
94+
INFO[0000] Generating CSV manifest version 0.0.1
95+
...
96+
97+
$ tree deploy/
98+
deploy/
99+
...
100+
├── olm-catalog
101+
│   └── memcached-operator
102+
│   ├── 0.0.1
103+
│   │   ├── cache.example.com_memcacheds_crd.yaml
104+
│   │   └── memcached-operator.v0.0.1.clusterserviceversion.yaml
105+
│   └── memcached-operator.package.yaml
106+
...
107+
108+
63109
110+
##### Generate CSV from custom input paths #####
111+
$ operator-sdk generate csv --csv-version=0.0.1 --update-crds \
112+
--deploy-dir=config --apis-dir=api --output-dir=production
113+
INFO[0000] Generating CSV manifest version 0.0.1
114+
...
115+
116+
$ tree config/ api/ production/
117+
config/
118+
├── crds
119+
│   ├── cache.example.com_memcacheds_crd.yaml
120+
│   └── cache.example.com_v1alpha1_memcached_cr.yaml
121+
├── operator.yaml
122+
├── role.yaml
123+
├── role_binding.yaml
124+
└── service_account.yaml
125+
api/
126+
├── ...
127+
└── cache
128+
├── group.go
129+
└── v1alpha1
130+
├── ...
131+
└── memcached_types.go
132+
production/
133+
└── olm-catalog
134+
└── memcached-operator
135+
├── 0.0.1
136+
│   ├── cache.example.com_memcacheds_crd.yaml
137+
│   └── memcached-operator.v0.0.1.clusterserviceversion.yaml
138+
└── memcached-operator.package.yaml
139+
`,
140+
141+
RunE: func(cmd *cobra.Command, args []string) error {
64142
if len(args) != 0 {
65143
return fmt.Errorf("command %s doesn't accept any arguments", cmd.CommandPath())
66144
}
67145
if err := c.validate(); err != nil {
68146
return fmt.Errorf("error validating command flags: %v", err)
69147
}
148+
149+
if err := projutil.CheckProjectRoot(); err != nil {
150+
log.Warn("Could not detect project root. Ensure that this command " +
151+
"runs from the project root directory.")
152+
}
153+
154+
// Default for crd dir if unset
155+
if c.crdDir == "" {
156+
c.crdDir = c.deployDir
157+
}
70158
if err := c.run(); err != nil {
71159
log.Fatal(err)
72160
}
73161
return nil
74162
},
75163
}
76164

77-
cmd.Flags().StringVar(&c.csvVersion, "csv-version", "", "Semantic version of the CSV")
165+
cmd.Flags().StringVar(&c.csvVersion, "csv-version", "",
166+
"Semantic version of the CSV")
78167
if err := cmd.MarkFlagRequired("csv-version"); err != nil {
79168
log.Fatalf("Failed to mark `csv-version` flag for `generate csv` subcommand as required: %v", err)
80169
}
81170
cmd.Flags().StringVar(&c.fromVersion, "from-version", "",
82171
"Semantic version of an existing CSV to use as a base")
83-
cmd.Flags().StringVar(&c.csvConfigPath, "csv-config", "",
84-
"Path to CSV config file. Defaults to deploy/olm-catalog/csv-config.yaml")
172+
173+
// TODO: Allow multiple paths
174+
// Deployment and RBAC manifests might be in different dirs e.g kubebuilder
175+
cmd.Flags().StringVar(&c.deployDir, "deploy-dir", "deploy",
176+
`Project relative path to root directory for operator manifests (Deployment and RBAC)`)
177+
cmd.Flags().StringVar(&c.apisDir, "apis-dir", filepath.Join("pkg", "apis"),
178+
`Project relative path to root directory for API type defintions`)
179+
// TODO: Allow multiple paths
180+
// CRD and CR manifests might be in different dirs e.g kubebuilder
181+
cmd.Flags().StringVar(&c.crdDir, "crd-dir", filepath.Join("deploy", "crds"),
182+
`Project relative path to root directory for CRD and CR manifests`)
183+
184+
cmd.Flags().StringVar(&c.outputDir, "output-dir", scaffold.DeployDir,
185+
"Base directory to output generated CSV. The resulting CSV bundle directory "+
186+
"will be \"<output-dir>/olm-catalog/<operator-name>/<csv-version>\".")
85187
cmd.Flags().BoolVar(&c.updateCRDs, "update-crds", false,
86188
"Update CRD manifests in deploy/{operator-name}/{csv-version} the using latest API's")
87189
cmd.Flags().StringVar(&c.operatorName, "operator-name", "",
@@ -96,61 +198,45 @@ Configure CSV generation by writing a config file 'deploy/olm-catalog/csv-config
96198
}
97199

98200
func (c csvCmd) run() error {
99-
100-
absProjectPath := projutil.MustGetwd()
101-
cfg := &input.Config{
102-
AbsProjectPath: absProjectPath,
103-
ProjectName: filepath.Base(absProjectPath),
104-
}
105-
if projutil.IsOperatorGo() {
106-
cfg.Repo = projutil.GetGoPkg()
107-
}
108-
109201
log.Infof("Generating CSV manifest version %s", c.csvVersion)
110202

111-
csvCfg, err := catalog.GetCSVConfig(c.csvConfigPath)
112-
if err != nil {
113-
return err
114-
}
115203
if c.operatorName == "" {
116-
// Use config operator name if not set by CLI, i.e. prefer CLI value over
117-
// config value.
118-
if c.operatorName = csvCfg.OperatorName; c.operatorName == "" {
119-
// Default to using project name if both are empty.
120-
c.operatorName = filepath.Base(absProjectPath)
121-
}
122-
}
123-
124-
s := &scaffold.Scaffold{}
125-
csv := &catalog.CSV{
126-
CSVVersion: c.csvVersion,
127-
FromVersion: c.fromVersion,
128-
ConfigFilePath: c.csvConfigPath,
129-
OperatorName: c.operatorName,
204+
c.operatorName = filepath.Base(projutil.MustGetwd())
130205
}
131-
err = s.Execute(cfg, csv)
132-
if err != nil {
133-
return fmt.Errorf("catalog scaffold failed: %v", err)
206+
cfg := gen.Config{
207+
OperatorName: c.operatorName,
208+
// TODO(hasbro17): Remove the Input key map when the Generator input keys
209+
// are removed in favour of config fields in the csvGenerator
210+
Inputs: map[string]string{
211+
gencatalog.DeployDirKey: c.deployDir,
212+
gencatalog.APIsDirKey: c.apisDir,
213+
gencatalog.CRDsDirKey: c.crdDir,
214+
},
215+
OutputDir: c.outputDir,
134216
}
135217

136-
gcfg := gen.Config{
137-
OperatorName: c.operatorName,
138-
OutputDir: filepath.Join(gencatalog.OLMCatalogDir, c.operatorName),
218+
csv := gencatalog.NewCSV(cfg, c.csvVersion, c.fromVersion)
219+
if err := csv.Generate(); err != nil {
220+
return fmt.Errorf("error generating CSV: %v", err)
139221
}
140-
pkg := gencatalog.NewPackageManifest(gcfg, c.csvVersion, c.csvChannel, c.defaultChannel)
222+
pkg := gencatalog.NewPackageManifest(cfg, c.csvVersion, c.csvChannel, c.defaultChannel)
141223
if err := pkg.Generate(); err != nil {
142224
return fmt.Errorf("error generating package manifest: %v", err)
143225
}
144226

145227
// Write CRD's to the new or updated CSV package dir.
146228
if c.updateCRDs {
147-
input, err := csv.GetInput()
229+
crdManifestSet, err := findCRDFileSet(c.crdDir)
148230
if err != nil {
149-
return err
231+
return fmt.Errorf("failed to update CRD's: %v", err)
150232
}
151-
err = writeCRDsToDir(csvCfg.CRDCRPaths, filepath.Dir(input.Path))
152-
if err != nil {
153-
return err
233+
// TODO: This path should come from the CSV generator field csvOutputDir
234+
bundleDir := filepath.Join(c.outputDir, gencatalog.OLMCatalogChildDir, c.operatorName, c.csvVersion)
235+
for path, b := range crdManifestSet {
236+
path = filepath.Join(bundleDir, path)
237+
if err = ioutil.WriteFile(path, b, fileutil.DefaultFileMode); err != nil {
238+
return fmt.Errorf("failed to update CRD's: %v", err)
239+
}
154240
}
155241
}
156242

@@ -191,25 +277,45 @@ func validateVersion(version string) error {
191277
return nil
192278
}
193279

194-
func writeCRDsToDir(crdPaths []string, toDir string) error {
195-
for _, p := range crdPaths {
196-
b, err := ioutil.ReadFile(p)
280+
// findCRDFileSet searches files in the given directory path for CRD manifests,
281+
// returning a map of paths to file contents.
282+
func findCRDFileSet(crdDir string) (map[string][]byte, error) {
283+
crdFileSet := map[string][]byte{}
284+
info, err := os.Stat(crdDir)
285+
if err != nil {
286+
return nil, err
287+
}
288+
if !info.IsDir() {
289+
return nil, fmt.Errorf("crd's must be read from a directory. %s is a file", crdDir)
290+
}
291+
files, err := ioutil.ReadDir(crdDir)
292+
if err != nil {
293+
return nil, err
294+
}
295+
296+
wd := projutil.MustGetwd()
297+
for _, f := range files {
298+
if f.IsDir() {
299+
continue
300+
}
301+
302+
crdPath := filepath.Join(wd, crdDir, f.Name())
303+
b, err := ioutil.ReadFile(crdPath)
197304
if err != nil {
198-
return err
305+
return nil, fmt.Errorf("error reading manifest %s: %v", crdPath, err)
199306
}
307+
// Skip files in crdsDir that aren't k8s manifests since we do not know
308+
// what other files are in crdsDir.
200309
typeMeta, err := k8sutil.GetTypeMetaFromBytes(b)
201310
if err != nil {
202-
return fmt.Errorf("error in %s : %v", p, err)
311+
log.Debugf("Skipping non-manifest file %s: %v", crdPath, err)
312+
continue
203313
}
204314
if typeMeta.Kind != "CustomResourceDefinition" {
315+
log.Debugf("Skipping non CRD manifest %s", crdPath)
205316
continue
206317
}
207-
208-
path := filepath.Join(toDir, filepath.Base(p))
209-
err = ioutil.WriteFile(path, b, fileutil.DefaultFileMode)
210-
if err != nil {
211-
return err
212-
}
318+
crdFileSet[filepath.Base(crdPath)] = b
213319
}
214-
return nil
320+
return crdFileSet, nil
215321
}

cmd/operator-sdk/run/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import (
1919
"fmt"
2020
"path/filepath"
2121

22+
olmcatalog "github.com/operator-framework/operator-sdk/internal/generate/olm-catalog"
2223
olmoperator "github.com/operator-framework/operator-sdk/internal/olm/operator"
23-
olmcatalog "github.com/operator-framework/operator-sdk/internal/scaffold/olm-catalog"
2424
k8sinternal "github.com/operator-framework/operator-sdk/internal/util/k8sutil"
2525
"github.com/operator-framework/operator-sdk/internal/util/projutil"
2626
aoflags "github.com/operator-framework/operator-sdk/pkg/ansible/flags"

0 commit comments

Comments
 (0)