Skip to content

Commit 6c2a96c

Browse files
committed
add olm bundle generation logic
1 parent 5f4c5d4 commit 6c2a96c

File tree

14 files changed

+674
-0
lines changed

14 files changed

+674
-0
lines changed

cmd/ack-generate/command/olm.go

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package command
15+
16+
import (
17+
"fmt"
18+
"io/ioutil"
19+
"path/filepath"
20+
"strings"
21+
22+
"github.com/ghodss/yaml"
23+
"github.com/spf13/cobra"
24+
25+
generate "github.com/aws-controllers-k8s/code-generator/pkg/generate"
26+
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
27+
olmgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/olm"
28+
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
29+
)
30+
31+
const (
32+
olmConfigFileSuffix = "olmconfig.yaml"
33+
)
34+
35+
// optOLMConfigPath
36+
var optOLMConfigPath string
37+
var optDisableCommonLinks bool
38+
var optDisableCommonKeywords bool
39+
40+
// olmCmd is the command that generates a service ClusterServiceVersion base
41+
// for generating an operator lifecycle manager bundle.
42+
var olmCmd = &cobra.Command{
43+
Use: "olm <service> <version>",
44+
Short: `Generate an Operator Lifecycle Manager's ClusterServiceVersion
45+
resources for AWS service API. Expects a configuration file to be passed in
46+
via the --olm-config option, or otherwise reads the config at the root of the
47+
project with the filename <servicealias>-olmconfig.yaml`,
48+
RunE: generateOLMAssets,
49+
}
50+
51+
func init() {
52+
olmCmd.PersistentFlags().StringVar(
53+
&optOLMConfigPath, "olm-config", "", "the OLM configuration file to inform how OLM assets are generated.",
54+
)
55+
// optionally disable common links in the resulting manifest
56+
olmCmd.PersistentFlags().BoolVar(
57+
&optDisableCommonLinks, "no-common-links", false, "does not include common links in the rendered cluster service version.",
58+
)
59+
// optionally disable common keywords in the resulting manifest
60+
olmCmd.PersistentFlags().BoolVar(
61+
&optDisableCommonKeywords, "no-common-keywords", false, "does not include common keywords in the rendered cluster service version",
62+
)
63+
64+
rootCmd.AddCommand(olmCmd)
65+
}
66+
67+
// generateOLMAssets generates all assets necessary for delivering the
68+
// service controllers via operator lifecycle manager ("OLM").
69+
func generateOLMAssets(cmd *cobra.Command, args []string) error {
70+
if len(args) != 2 {
71+
return fmt.Errorf(
72+
"please specify the service alias and version " +
73+
"for the AWS service API to generate",
74+
)
75+
}
76+
svcAlias := strings.ToLower(args[0])
77+
if optOutputPath == "" {
78+
optOutputPath = filepath.Join(optServicesDir, svcAlias)
79+
}
80+
81+
version := args[1]
82+
83+
// get the generator inputs
84+
if err := ensureSDKRepo(optCacheDir); err != nil {
85+
return err
86+
}
87+
sdkHelper := ackmodel.NewSDKHelper(sdkDir)
88+
sdkAPI, err := sdkHelper.API(svcAlias)
89+
if err != nil {
90+
newSvcAlias, err := FallBackFindServiceID(sdkDir, svcAlias)
91+
if err != nil {
92+
return err
93+
}
94+
sdkAPI, err = sdkHelper.API(newSvcAlias) // retry with serviceID
95+
if err != nil {
96+
return fmt.Errorf("service %s not found", svcAlias)
97+
}
98+
}
99+
100+
latestAPIVersion, err = getLatestAPIVersion()
101+
if err != nil {
102+
return err
103+
}
104+
g, err := generate.New(
105+
sdkAPI, latestAPIVersion, optGeneratorConfigPath, ackgenerate.DefaultConfig,
106+
)
107+
if err != nil {
108+
return err
109+
}
110+
111+
if optOLMConfigPath == "" {
112+
optOLMConfigPath = strings.Join([]string{svcAlias, olmConfigFileSuffix}, "-")
113+
}
114+
115+
// read the configuration from file
116+
svcConfigYAML, err := ioutil.ReadFile(optOLMConfigPath)
117+
if err != nil {
118+
fmt.Println("unable to read configuration file at path:", optOLMConfigPath)
119+
return err
120+
}
121+
122+
// set the base metadata and then override values as
123+
// defined by the service config.
124+
svcMeta := ackmodel.NewOLMMetadata() // TODO this can take in variables
125+
if err = yaml.Unmarshal(svcConfigYAML, &svcMeta); err != nil {
126+
fmt.Println("unable to convert olm configuration file to data instance")
127+
return err
128+
}
129+
130+
// prepare the common metadata
131+
commonMeta := ackmodel.OLMCommonMetadata{}
132+
if !optDisableCommonLinks {
133+
commonMeta.Links = ackmodel.CommonLinks
134+
}
135+
136+
if !optDisableCommonKeywords {
137+
commonMeta.Keywords = ackmodel.CommonKeywords
138+
}
139+
140+
// generate templates
141+
ts, err := olmgenerate.BundleAssets(g, commonMeta, svcMeta, version, optTemplatesDir)
142+
if err != nil {
143+
return err
144+
}
145+
146+
if err = ts.Execute(); err != nil {
147+
return err
148+
}
149+
150+
for path, contents := range ts.Executed() {
151+
if optDryRun {
152+
fmt.Printf("============================= %s ======================================\n", path)
153+
fmt.Println(strings.TrimSpace(contents.String()))
154+
continue
155+
}
156+
outPath := filepath.Join(optOutputPath, path)
157+
outDir := filepath.Dir(outPath)
158+
if _, err := ensureDir(outDir); err != nil {
159+
return err
160+
}
161+
if err = ioutil.WriteFile(outPath, contents.Bytes(), 0666); err != nil {
162+
return err
163+
}
164+
}
165+
166+
return nil
167+
}

pkg/generate/olm/olm.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package olm
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
ttpl "text/template"
7+
"time"
8+
9+
"github.com/aws-controllers-k8s/code-generator/pkg/generate"
10+
"github.com/aws-controllers-k8s/code-generator/pkg/generate/templateset"
11+
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
12+
)
13+
14+
var (
15+
csvTemplatePaths = []string{
16+
"config/controller/user-env.yaml.tpl",
17+
"config/samples/sample.yaml.tpl",
18+
"Makefile.tpl", // this is a subset of the operator-sdk makefile
19+
}
20+
21+
csvIncludePaths = []string{
22+
"config/controller/kustomization_def.yaml.tpl",
23+
}
24+
25+
csvCopyPaths = []string{
26+
"config/manifests/kustomization.yaml",
27+
"config/scorecard/bases/config.yaml",
28+
"config/scorecard/kustomization.yaml",
29+
"config/scorecard/patches/basic.config.yaml",
30+
"config/scorecard/patches/olm.config.yaml",
31+
"config/samples/kustomization.yaml",
32+
}
33+
34+
csvFuncMap = ttpl.FuncMap{
35+
"ToLower": strings.ToLower,
36+
}
37+
)
38+
39+
// BundleAssets generates the assets necessary to generate
40+
// a bundle used for deploying a service via OLM.
41+
func BundleAssets(
42+
g *generate.Generator,
43+
commonMeta ackmodel.OLMCommonMetadata,
44+
serviceMeta ackmodel.OLMMetadata,
45+
vers string,
46+
templateBasePath string,
47+
) (*templateset.TemplateSet, error) {
48+
49+
createdAt := time.Now().Format("2006-01-02 15:04:05")
50+
51+
ts := templateset.New(
52+
templateBasePath,
53+
csvIncludePaths,
54+
csvCopyPaths,
55+
csvFuncMap,
56+
)
57+
58+
crds, err := g.GetCRDs()
59+
if err != nil {
60+
return nil, err
61+
}
62+
63+
olmVars := templateOLMVars{
64+
vers,
65+
createdAt,
66+
g.MetaVars(),
67+
commonMeta,
68+
serviceMeta,
69+
crds,
70+
}
71+
72+
for _, path := range csvTemplatePaths {
73+
outPath := strings.TrimSuffix(path, ".tpl")
74+
if err := ts.Add(outPath, path, olmVars); err != nil {
75+
return nil, err
76+
}
77+
}
78+
79+
if err := ts.Add("config/controller/kustomization.yaml", "config/controller/olm-kustomization.yaml.tpl", olmVars); err != nil {
80+
return nil, err
81+
}
82+
83+
csvBaseOutPath := fmt.Sprintf(
84+
"config/manifests/bases/ack-%s-controller.clusterserviceversion.yaml",
85+
g.MetaVars().ServiceIDClean)
86+
if err := ts.Add(csvBaseOutPath, "config/manifests/bases/clusterserviceversion.yaml.tpl", olmVars); err != nil {
87+
return nil, err
88+
}
89+
90+
return ts, nil
91+
}
92+
93+
type templateOLMVars struct {
94+
Version string
95+
CreatedAt string
96+
templateset.MetaVars
97+
Common ackmodel.OLMCommonMetadata
98+
ackmodel.OLMMetadata
99+
CRDs []*ackmodel.CRD
100+
}

0 commit comments

Comments
 (0)