Skip to content

Commit 32862b0

Browse files
pkg/generator: Generate all manifests needed for Prometheus integration
1 parent 6623f0b commit 32862b0

8 files changed

+185
-5
lines changed

Gopkg.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
name = "github.com/spf13/cobra"
77
version = "0.0.2"
88

9+
[[override]]
10+
name = "github.com/prometheus/client_golang"
11+
version = "0.8.0"
12+
913
[[override]]
1014
name = "k8s.io/api"
1115
version = "kubernetes-1.9.3"

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ $ kubectl create -f deploy/rbac.yaml
5656
$ kubectl create -f deploy/crd.yaml
5757
$ kubectl create -f deploy/operator.yaml
5858

59+
# Monitor the app-operator using prometheus and serviceMonitor CRD
60+
$ kubectl create -f deploy/service.yaml
61+
$ kubectl create -f deploy/serviceMonitor.yaml
62+
5963
# By default, creating a custom resource (App) triggers the app-operator to deploy a busybox pod
6064
$ kubectl create -f deploy/cr.yaml
6165

@@ -68,6 +72,8 @@ busy-box 1/1 Running 0 50s
6872
$ kubectl delete -f deploy/cr.yaml
6973
$ kubectl delete -f deploy/operator.yaml
7074
$ kubectl delete -f deploy/rbac.yaml
75+
$ kubectl delete -f deploy/service.yaml
76+
$ kubectl delete -f deploy.serviceMonitor.yaml
7177
```
7278

7379
To learn more about the operator-sdk, see the [user guide][guide].

pkg/generator/deploy_tmpl.go

+33
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ const operatorYamlTmpl = `apiVersion: apps/v1
3333
kind: Deployment
3434
metadata:
3535
name: {{.ProjectName}}
36+
labels:
37+
name: {{.ProjectName}}
3638
spec:
3739
replicas: 1
3840
selector:
@@ -46,6 +48,9 @@ spec:
4648
containers:
4749
- name: {{.ProjectName}}
4850
image: {{.Image}}
51+
ports:
52+
- containerPort: 9090
53+
name: metrics
4954
command:
5055
- {{.ProjectName}}
5156
imagePullPolicy: Always
@@ -109,3 +114,31 @@ kind: "{{.Kind}}"
109114
metadata:
110115
name: "example"
111116
`
117+
118+
const serviceYamlTmpl = `apiVersion: v1
119+
kind: Service
120+
metadata:
121+
name: {{.ProjectName}}
122+
labels:
123+
name: {{.ProjectName}}
124+
spec:
125+
selector:
126+
name: {{.ProjectName}}
127+
ports:
128+
- protocol: TCP
129+
targetPort: metrics
130+
port: 9090
131+
name: metrics`
132+
133+
const serviceMonitorYamlTmpl = `apiVersion: monitoring.coreos.com/v1
134+
kind: ServiceMonitor
135+
metadata:
136+
name: {{.ProjectName}}
137+
labels:
138+
name: {{.ProjectName}}
139+
spec:
140+
selector:
141+
matchLabels:
142+
name: {{.ProjectName}}
143+
endpoints:
144+
- port: metrics`

pkg/generator/gen_deploy.go

+47-4
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ import (
2222
)
2323

2424
const (
25-
crdTmplName = "deploy/crd.yaml"
26-
operatorTmplName = "deploy/operator.yaml"
27-
rbacTmplName = "deploy/rbac.yaml"
28-
crTmplName = "deploy/cr.yaml"
25+
crdTmplName = "deploy/crd.yaml"
26+
operatorTmplName = "deploy/operator.yaml"
27+
rbacTmplName = "deploy/rbac.yaml"
28+
crTmplName = "deploy/cr.yaml"
29+
serviceTmplName = "deploy/service.yaml"
30+
serviceMonitorTmplName = "deploy/serviceMonitor.yaml"
2931
)
3032

3133
// CRDYaml contains data needed to generate deploy/crd.yaml
@@ -77,6 +79,47 @@ func renderOperatorYaml(w io.Writer, projectName, image string) error {
7779
return t.Execute(w, o)
7880
}
7981

82+
// ServiceYaml contains all the customized data needed to generate deploy/service.yaml for a new operator
83+
// This service will be monitor by prometheus
84+
// when pairing with serviceYamlTmpl template.
85+
type ServiceYaml struct {
86+
ProjectName string
87+
}
88+
89+
// renderServiceYaml generates deploy/service.yaml.
90+
func renderServiceYaml(w io.Writer, projectName string) error {
91+
t := template.New(serviceTmplName)
92+
t, err := t.Parse(serviceYamlTmpl)
93+
if err != nil {
94+
return fmt.Errorf("Failed to parse service yaml template: %v", err)
95+
}
96+
97+
s := ServiceYaml{
98+
ProjectName: projectName,
99+
}
100+
return t.Execute(w, s)
101+
}
102+
103+
// ServiceMonitorYaml contains all the customized data needed to generate deploy/serviceMonitor.yaml for a new operator
104+
// when pairing with serviceMonitorYamlTmpl template.
105+
type ServiceMonitorYaml struct {
106+
ProjectName string
107+
}
108+
109+
// renderServiceYaml generates deploy/service.yaml.
110+
func renderServiceMonitorYaml(w io.Writer, projectName string) error {
111+
t := template.New(serviceMonitorTmplName)
112+
t, err := t.Parse(serviceMonitorYamlTmpl)
113+
if err != nil {
114+
return fmt.Errorf("Failed to parse serviceMonitor yaml template: %v", err)
115+
}
116+
117+
s := ServiceYaml{
118+
ProjectName: projectName,
119+
}
120+
return t.Execute(w, s)
121+
}
122+
80123
// RBACYaml contains all the customized data needed to generate deploy/rbac.yaml for a new operator
81124
// when pairing with rbacYamlTmpl template.
82125
type RBACYaml struct {

pkg/generator/gen_deploy_test.go

+49
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const operatorYamlExp = `apiVersion: apps/v1
2424
kind: Deployment
2525
metadata:
2626
name: app-operator
27+
labels:
28+
name: app-operator
2729
spec:
2830
replicas: 1
2931
selector:
@@ -37,6 +39,9 @@ spec:
3739
containers:
3840
- name: app-operator
3941
image: quay.io/example-inc/app-operator:0.0.1
42+
ports:
43+
- containerPort: 9090
44+
name: metrics
4045
command:
4146
- app-operator
4247
imagePullPolicy: Always
@@ -95,6 +100,34 @@ roleRef:
95100
apiGroup: rbac.authorization.k8s.io
96101
`
97102

103+
const serviceYamlExp = `apiVersion: v1
104+
kind: Service
105+
metadata:
106+
name: app-operator
107+
labels:
108+
name: app-operator
109+
spec:
110+
selector:
111+
name: app-operator
112+
ports:
113+
- protocol: TCP
114+
targetPort: metrics
115+
port: 9090
116+
name: metrics`
117+
118+
const serviceMonitorYamlExp = `apiVersion: monitoring.coreos.com/v1
119+
kind: ServiceMonitor
120+
metadata:
121+
name: app-operator
122+
labels:
123+
name: app-operator
124+
spec:
125+
selector:
126+
matchLabels:
127+
name: app-operator
128+
endpoints:
129+
- port: metrics`
130+
98131
func TestGenDeploy(t *testing.T) {
99132
buf := &bytes.Buffer{}
100133
if err := renderCRDYaml(buf, appKind, appAPIVersion); err != nil {
@@ -119,4 +152,20 @@ func TestGenDeploy(t *testing.T) {
119152
if rbacYamlExp != buf.String() {
120153
t.Errorf("want %v, got %v", rbacYamlExp, buf.String())
121154
}
155+
156+
buf = &bytes.Buffer{}
157+
if err := renderServiceYaml(buf, appProjectName); err != nil {
158+
t.Error(err)
159+
}
160+
if serviceYamlExp != buf.String() {
161+
t.Errorf("want %v, got %v", serviceYamlExp, buf.String())
162+
}
163+
164+
buf = &bytes.Buffer{}
165+
if err := renderServiceMonitorYaml(buf, appProjectName); err != nil {
166+
t.Error(err)
167+
}
168+
if serviceMonitorYamlExp != buf.String() {
169+
t.Errorf("want %v, got %v", serviceMonitorYamlExp, buf.String())
170+
}
122171
}

pkg/generator/generator.go

+36
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ const (
5454
gopkglock = "Gopkg.lock"
5555
config = "config.yaml"
5656
operatorYaml = deployDir + "/operator.yaml"
57+
serviceYaml = "service.yaml"
58+
serviceMonitorYaml = "serviceMonitor.yaml"
5759
rbacYaml = "rbac.yaml"
5860
crYaml = "cr.yaml"
5961
catalogPackageYaml = "package.yaml"
@@ -206,6 +208,22 @@ func renderDeployFiles(deployDir, projectName, apiVersion, kind string) error {
206208
return err
207209
}
208210

211+
buf = &bytes.Buffer{}
212+
if err := renderServiceYaml(buf, projectName); err != nil {
213+
return err
214+
}
215+
if err := writeFileAndPrint(filepath.Join(deployDir, serviceYaml), buf.Bytes(), defaultFileMode); err != nil {
216+
return err
217+
}
218+
219+
buf = &bytes.Buffer{}
220+
if err := renderServiceMonitorYaml(buf, projectName); err != nil {
221+
return err
222+
}
223+
if err := writeFileAndPrint(filepath.Join(deployDir, serviceMonitorYaml), buf.Bytes(), defaultFileMode); err != nil {
224+
return err
225+
}
226+
209227
buf = &bytes.Buffer{}
210228
if err := renderCRDYaml(buf, kind, apiVersion); err != nil {
211229
return err
@@ -230,6 +248,24 @@ func RenderOperatorYaml(c *Config, image string) error {
230248
return ioutil.WriteFile(operatorYaml, buf.Bytes(), defaultFileMode)
231249
}
232250

251+
// RenderServiceYaml generates "deploy/service.yaml"
252+
func RenderServiceYaml(c *Config) error {
253+
buf := &bytes.Buffer{}
254+
if err := renderServiceYaml(buf, c.ProjectName); err != nil {
255+
return err
256+
}
257+
return ioutil.WriteFile(serviceYaml, buf.Bytes(), defaultFileMode)
258+
}
259+
260+
// RenderServiceMonitorYaml generates "deploy/serviceMonitor.yaml"
261+
func RenderServiceMonitorYaml(c *Config) error {
262+
buf := &bytes.Buffer{}
263+
if err := renderServiceMonitorYaml(buf, c.ProjectName); err != nil {
264+
return err
265+
}
266+
return ioutil.WriteFile(serviceMonitorYaml, buf.Bytes(), defaultFileMode)
267+
}
268+
233269
// RenderOlmCatalog generates catalog manifests "deploy/olm-catalog/*"
234270
// The current working directory must be the project repository root
235271
func RenderOlmCatalog(c *Config, image, version string) error {

pkg/generator/main_tmpl.go

+9
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,33 @@ const mainTmpl = `package main
2020
import (
2121
"context"
2222
"runtime"
23+
"net/http"
2324
2425
stub "{{.StubImport}}"
2526
sdk "{{.OperatorSDKImport}}"
2627
k8sutil "{{.K8sutilImport}}"
2728
sdkVersion "{{.SDKVersionImport}}"
2829
30+
"github.com/prometheus/client_golang/prometheus/promhttp"
2931
"github.com/sirupsen/logrus"
3032
)
3133
34+
// Prometheus metrics port
35+
const promPort = ":9090"
36+
3237
func printVersion() {
3338
logrus.Infof("Go Version: %s", runtime.Version())
3439
logrus.Infof("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)
3540
logrus.Infof("operator-sdk Version: %v", sdkVersion.Version)
41+
logrus.Infof("operator prometheus port :%s", promPort)
3642
}
3743
3844
func main() {
3945
printVersion()
4046
47+
http.Handle("/metrics", promhttp.Handler())
48+
logrus.Fatalf("%s", http.ListenAndServe(promPort, nil))
49+
4150
resource := "{{.APIVersion}}"
4251
kind := "{{.Kind}}"
4352
namespace, err := k8sutil.GetWatchNamespace()

0 commit comments

Comments
 (0)