Skip to content

Commit

Permalink
Merge pull request #1790 from christopherhein/feature/component-confi…
Browse files Browse the repository at this point in the history
…g-implementation

⚠ (go/v3-alpha) Adding support for scaffolding with a versioned ComponentConfig
  • Loading branch information
k8s-ci-robot authored Nov 18, 2020
2 parents a23d5aa + 55b8fd7 commit 4e1828b
Show file tree
Hide file tree
Showing 101 changed files with 2,861 additions and 20 deletions.
1 change: 1 addition & 0 deletions generate_testdata.sh
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,4 @@ scaffold_test_project project-v2-addon --project-version=2
scaffold_test_project project-v3 --project-version=3-alpha --plugins=go/v3-alpha
scaffold_test_project project-v3-multigroup --project-version=3-alpha --plugins=go/v3-alpha
scaffold_test_project project-v3-addon --project-version=3-alpha --plugins=go/v3-alpha
scaffold_test_project project-v3-config --project-version=3-alpha --plugins=go/v3-alpha --component-config
4 changes: 4 additions & 0 deletions pkg/model/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ type Config struct {
// Multigroup tracks if the project has more than one group
MultiGroup bool `json:"multigroup,omitempty"`

// ComponentConfig tracks if the project uses a config file for configuring
// the ctrl.Manager
ComponentConfig bool `json:"componentConfig,omitempty"`

// Layout contains a key specifying which plugin created a project.
Layout string `json:"layout,omitempty"`

Expand Down
6 changes: 6 additions & 0 deletions pkg/model/file/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ type HasMultiGroup interface {
InjectMultiGroup(bool)
}

// HasComponentConfig allows the component-config flag to be used on a template
type HasComponentConfig interface {
// InjectComponentConfig sets the template component-config flag
InjectComponentConfig(bool)
}

// HasBoilerplate allows a boilerplate to be used on a template
type HasBoilerplate interface {
// InjectBoilerplate sets the template boilerplate
Expand Down
11 changes: 11 additions & 0 deletions pkg/model/file/mixins.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ func (m *MultiGroupMixin) InjectMultiGroup(flag bool) {
m.MultiGroup = flag
}

// ComponentConfigMixin provides templates with a injectable component-config flag field
type ComponentConfigMixin struct {
// ComponentConfig is the component-config flag
ComponentConfig bool
}

// InjectComponentConfig implements HasComponentConfig
func (m *ComponentConfigMixin) InjectComponentConfig(flag bool) {
m.ComponentConfig = flag
}

// BoilerplateMixin provides templates with a injectable boilerplate field
type BoilerplateMixin struct {
// Boilerplate is the contents of a Boilerplate go header file
Expand Down
3 changes: 3 additions & 0 deletions pkg/model/universe.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ func (u Universe) InjectInto(builder file.Builder) {
if builderWithMultiGroup, hasMultiGroup := builder.(file.HasMultiGroup); hasMultiGroup {
builderWithMultiGroup.InjectMultiGroup(u.Config.MultiGroup)
}
if builderWithComponentConfig, hasComponentConfig := builder.(file.HasComponentConfig); hasComponentConfig {
builderWithComponentConfig.InjectComponentConfig(u.Config.ComponentConfig)
}
if builderWithProjectName, hasProjectName := builder.(file.HasProjectName); hasProjectName {
builderWithProjectName.InjectProjectName(u.Config.ProjectName)
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/plugins/golang/v3/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ func (p *initSubcommand) BindFlags(fs *pflag.FlagSet) {
fs.StringVar(&p.license, "license", "apache2",
"license to use to boilerplate, may be one of 'apache2', 'none'")
fs.StringVar(&p.owner, "owner", "", "owner to add to the copyright")
fs.BoolVar(&p.config.ComponentConfig, "component-config", false,
"create a versioned ComponentConfig file, may be 'true' or 'false'")

// project args
fs.StringVar(&p.config.Repo, "repo", "", "name to use for go module (e.g., github.com/user/repo), "+
Expand Down
2 changes: 2 additions & 0 deletions pkg/plugins/golang/v3/scaffolds/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func (s *initScaffolder) scaffold() error {
&rbac.LeaderElectionRoleBinding{},
&manager.Kustomization{},
&manager.Config{Image: imageName},
&manager.ControllerManagerConfig{},
&templates.Main{},
&templates.GoMod{ControllerRuntimeVersion: ControllerRuntimeVersion},
&templates.GitIgnore{},
Expand All @@ -121,6 +122,7 @@ func (s *initScaffolder) scaffold() error {
&templates.DockerIgnore{},
&kdefault.Kustomization{},
&kdefault.ManagerAuthProxyPatch{},
&kdefault.ManagerConfigPatch{},
&prometheus.Kustomization{},
&prometheus.Monitor{},
&certmanager.Certificate{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var _ file.Template = &Kustomization{}
type Kustomization struct {
file.TemplateMixin
file.ProjectNameMixin
file.ComponentConfigMixin
}

// SetTemplateDefaults implements file.Template
Expand Down Expand Up @@ -70,11 +71,15 @@ bases:
#- ../prometheus
patchesStrategicMerge:
# Protect the /metrics endpoint by putting it behind auth.
# If you want your controller-manager to expose the /metrics
# endpoint w/o any authn/z, please comment the following line.
# Protect the /metrics endpoint by putting it behind auth.
# If you want your controller-manager to expose the /metrics
# endpoint w/o any authn/z, please comment the following line.
- manager_auth_proxy_patch.yaml
# Mount the controller config file for loading manager configurations
# through a ComponentConfig type
{{ if not .ComponentConfig }}#{{ end }}- manager_config_patch.yaml
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
# crd/kustomization.yaml
#- manager_webhook_patch.yaml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var _ file.Template = &ManagerAuthProxyPatch{}
// ManagerAuthProxyPatch scaffolds a file that defines the patch that enables prometheus metrics for the manager
type ManagerAuthProxyPatch struct {
file.TemplateMixin
file.ComponentConfigMixin
}

// SetTemplateDefaults implements file.Template
Expand All @@ -42,7 +43,7 @@ func (f *ManagerAuthProxyPatch) SetTemplateDefaults() error {
return nil
}

const kustomizeAuthProxyPatchTemplate = `# This patch inject a sidecar container which is a HTTP proxy for the
const kustomizeAuthProxyPatchTemplate = `# This patch inject a sidecar container which is a HTTP proxy for the
# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews.
apiVersion: apps/v1
kind: Deployment
Expand All @@ -63,8 +64,10 @@ spec:
ports:
- containerPort: 8443
name: https
{{- if not .ComponentConfig }}
- name: manager
args:
- "--metrics-addr=127.0.0.1:8080"
- "--enable-leader-election"
{{- end }}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package kdefault

import (
"path/filepath"

"sigs.k8s.io/kubebuilder/v2/pkg/model/file"
)

var _ file.Template = &ManagerConfigPatch{}

// ManagerConfigPatch scaffolds a ManagerConfigPatch for a Resource
type ManagerConfigPatch struct {
file.TemplateMixin
}

// SetTemplateDefaults implements input.Template
func (f *ManagerConfigPatch) SetTemplateDefaults() error {
if f.Path == "" {
f.Path = filepath.Join("config", "default", "manager_config_patch.yaml")
}

f.TemplateBody = managerConfigPatchTemplate

return nil
}

const managerConfigPatchTemplate = `apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
args:
- "--config=controller_manager_config.yaml"
volumeMounts:
- name: manager-config
mountPath: /controller_manager_config.yaml
subPath: controller_manager_config.yaml
volumes:
- name: manager-config
configMap:
name: manager-config
`
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var _ file.Template = &Config{}
// Config scaffolds a file that defines the namespace and the manager deployment
type Config struct {
file.TemplateMixin
file.ComponentConfigMixin

// Image is controller manager image name
Image string
Expand Down Expand Up @@ -72,8 +73,10 @@ spec:
containers:
- command:
- /manager
{{- if not .ComponentConfig }}
args:
- --enable-leader-election
{{- end }}
image: {{ .Image }}
name: manager
securityContext:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package manager

import (
"path/filepath"

"sigs.k8s.io/kubebuilder/v2/pkg/model/file"
)

var _ file.Template = &ControllerManagerConfig{}

// ControllerManagerConfig scaffolds the config file in config/manager folder.
type ControllerManagerConfig struct {
file.TemplateMixin
file.DomainMixin
file.RepositoryMixin
}

// SetTemplateDefaults implements input.Template
func (f *ControllerManagerConfig) SetTemplateDefaults() error {
if f.Path == "" {
f.Path = filepath.Join("config", "manager", "controller_manager_config.yaml")
}

f.TemplateBody = controllerManagerConfigTemplate

f.IfExistsAction = file.Error

return nil
}

const controllerManagerConfigTemplate = `apiVersion: controller-runtime.sigs.k8s.io/v1alpha1
kind: ControllerManagerConfig
metrics:
bindAddress: 127.0.0.1:8080
webhook:
port: 9443
leaderElection:
leaderElect: true
resourceName: {{ hashFNV .Repo }}.{{ .Domain }}
`
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,12 @@ func (f *Kustomization) SetTemplateDefaults() error {

const kustomizeManagerTemplate = `resources:
- manager.yaml
generatorOptions:
disableNameSuffixHash: true
configMapGenerator:
- name: manager-config
files:
- controller_manager_config.yaml
`
24 changes: 23 additions & 1 deletion pkg/plugins/golang/v3/scaffolds/internal/templates/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Main struct {
file.BoilerplateMixin
file.DomainMixin
file.RepositoryMixin
file.ComponentConfigMixin
}

// SetTemplateDefaults implements file.Template
Expand Down Expand Up @@ -213,13 +214,20 @@ func init() {
}
func main() {
{{- if not .ComponentConfig }}
var metricsAddr string
var enableLeaderElection bool
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
"Enable leader election for controller manager. " +
"Enabling this will ensure there is only one active controller manager.")
{{- else }}
var configFile string
flag.StringVar(&configFile, "config", "",
"The controller will load its initial configuration from this file. " +
"Omit this flag to use the default configuration values. " +
"Command-line flags override configuration from this file.")
{{- end }}
opts := zap.Options{
Development: true,
}
Expand All @@ -228,13 +236,27 @@ func main() {
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
{{ if not .ComponentConfig }}
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Port: 9443,
LeaderElection: enableLeaderElection,
LeaderElectionID: "{{ hashFNV .Repo }}.{{ .Domain }}",
})
{{- else }}
var err error
options := ctrl.Options{Scheme: scheme}
if configFile != "" {
options, err = options.AndFrom(ctrl.ConfigFile().AtPath(configFile))
if err != nil {
setupLog.Error(err, "unable to load the config file")
os.Exit(1)
}
}
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options)
{{- end }}
if err != nil {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var _ file.Template = &Makefile{}
// Makefile scaffolds a file that defines project management CLI commands
type Makefile struct {
file.TemplateMixin
file.ComponentConfigMixin

// Image is controller manager image name
Image string
Expand Down
10 changes: 7 additions & 3 deletions testdata/project-v3-addon/config/default/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ bases:
#- ../prometheus

patchesStrategicMerge:
# Protect the /metrics endpoint by putting it behind auth.
# If you want your controller-manager to expose the /metrics
# endpoint w/o any authn/z, please comment the following line.
# Protect the /metrics endpoint by putting it behind auth.
# If you want your controller-manager to expose the /metrics
# endpoint w/o any authn/z, please comment the following line.
- manager_auth_proxy_patch.yaml

# Mount the controller config file for loading manager configurations
# through a ComponentConfig type
#- manager_config_patch.yaml

# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
# crd/kustomization.yaml
#- manager_webhook_patch.yaml
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This patch inject a sidecar container which is a HTTP proxy for the
# This patch inject a sidecar container which is a HTTP proxy for the
# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews.
apiVersion: apps/v1
kind: Deployment
Expand Down
Loading

0 comments on commit 4e1828b

Please sign in to comment.