pkg/generator: Generate all manifests needed for Prometheus integration#241
pkg/generator: Generate all manifests needed for Prometheus integration#241etiennecoutaud wants to merge 25 commits intooperator-framework:masterfrom
Conversation
|
cc @spahl |
| selector: | ||
| matchLabels: | ||
| name: {{.ProjectName}} | ||
| k8s-app: {{.ProjectName}} |
There was a problem hiding this comment.
why change name to k8s-app?
There was a problem hiding this comment.
I introduced k8s-app label for service and servicemonitor. I just changed to have the same label everywhere.
If needed I can change to use name label in service and servicemonitor
There was a problem hiding this comment.
Okay for using name label.
Should I use name label in service and servicemonitor too ?
|
Could you update the commit message title format as shown in https://github.com/operator-framework/operator-sdk/blob/master/CONTRIBUTING.MD#format-of-the-commit-message? |
| - name: {{.ProjectName}} | ||
| image: {{.Image}} | ||
| ports: | ||
| - containerPort: 9090 |
There was a problem hiding this comment.
can we name this port? and then use that in the service as targetPort: name. That leaves us flexibility to change the port in the future without having to change the service.
There was a problem hiding this comment.
containerPort is now name metrics and use in the service as targetPort: metrics
There was a problem hiding this comment.
Make the port number a variable like {{.MetricsPort}} and define a new parameter in gen_deploy.go
type OperatorYaml struct {
ProjectName string
Image string
MetricsPort int
}That way we can set MetricsPort to a constant defined elsewhere.
|
finally change all |
|
This PR LGTM, though it does bother me a little that we have "9090" hard coded in 4 places. Not sure it's worth putting in the template data, but if we really wanted to do a followup. |
|
I agree with you, an another way could be to add a config file pass to the generator when |
|
I'd personally lean pretty hard on 'only give users 1 way to do it and make sure that way is the right way'. I'm definitely in favor of us putting the port into the code and not making it optional. My only (tiny) bit of unease is that it's in the code 4 times instead of 1. Fewer options make users less able to get into weird situations we don't test or aren't able to help them with. |
|
I feel like hard-coding ports is going to a problem if you ever need to run another program that could use that port as a side-car to the operator. |
|
In that case, we cannot prevent futur usage , so user will have to change promport in main.go and metrics port in manifest files |
32862b0 to
00a2432
Compare
|
We should follow up with the discussion at #222 (comment) before we decide if we want to move forward with this approach. |
|
Update done according to #222 |
| ) | ||
|
|
||
| // Prometheus metrics port | ||
| const promPort = ":9090" |
There was a problem hiding this comment.
Can we use a less common port number at a higher range like 90000.
Also can you define the port number as a global constant somewhere other than the test file like in k8sutil/constants.go. That way we can use it everywhere in the generator package without redefining it.
There was a problem hiding this comment.
Or something that's actually in the ephemeral port range like 60K. 90K is out of range.
| valueFrom: | ||
| fieldRef: | ||
| fieldPath: metadata.namespace | ||
| - name: OPERATOR_NAME |
There was a problem hiding this comment.
Similarly can you make the OPERATOR_NAME and WATCH_NAMESPACE strings as variables in the template so we can set them using the namespace constants defined in k8sutil/constants.go.
type OperatorYaml struct {
ProjectName string
Image string
NameEnv string
NamespaceEnv string
MetricsPort int
}|
@hasbro17 according to your review:
|
…der-func pkg/generator: Create generic file rendering function
| image: {{.Image}} | ||
| ports: | ||
| - containerPort: {{.MetricsPort}} | ||
| name: metrics |
There was a problem hiding this comment.
The string metrics is being used here and in InitOperatorService().
We should make this a constant in k8sutil/constants.go.
And then pass it as a parameter name: {{.MetricsPortName}}.
| SDKVersionImport: versionImport, | ||
| APIVersion: apiVersion, | ||
| Kind: kind, | ||
| MetricsPort: k8sutil.GetPrometheusMetricsPort(), |
There was a problem hiding this comment.
I don't think we need to convert this to a string. We can just use k8sutil.PrometheusMetricsPort.
And in the template down below we can change it to:
go http.ListenAndServe(":{{.MetricsPort}}", nil)
| version = "0.0.2" | ||
|
|
||
| [[override]] | ||
| name = "github.com/prometheus/client_golang" |
There was a problem hiding this comment.
This package isn't really used in the SDK itself right now so we can remove this. We'll add it back in later once we actually use this to record default metrics inside the SDK.
For now we can add it to the Gopkg.toml template of the operator:
https://github.com/operator-framework/operator-sdk/blob/master/pkg/generator/templates.go#L372
| sdk "github.com/operator-framework/operator-sdk/pkg/sdk" | ||
| k8sutil "github.com/operator-framework/operator-sdk/pkg/util/k8sutil" | ||
| sdkVersion "github.com/operator-framework/operator-sdk/version" | ||
| stub "github.com/example-inc/app-operator/pkg/stub" |
There was a problem hiding this comment.
We should keep the tab size to 4 as it is for all the other templates.
| sdk "{{.OperatorSDKImport}}" | ||
| k8sutil "{{.K8sutilImport}}" | ||
| sdkVersion "{{.SDKVersionImport}}" | ||
| stub "{{.StubImport}}" |
There was a problem hiding this comment.
Change tab size back to 4
| } | ||
| err = sdk.Create(service) | ||
| if err != nil { | ||
| logrus.Infof("Failed to create operator service: %v", err) |
There was a problem hiding this comment.
We should ignore the error if the service already exists as it's very likely that the operator pod can restart.
import "k8s.io/apimachinery/pkg/api/errors"
...
if err != nil && !errors.IsAlreadyExists(err) {
logrus.Infof("Failed to create operator service: %v", err)
return
}| logrus.Infof("Failed to create operator service: %v", err) | ||
| return | ||
| } | ||
| logrus.Infof("Service %s have been created", service.Name) |
There was a problem hiding this comment.
logrus.Infof("Metrics service %s created", service.Name)|
@etiennecoutaud Thanks for the update. I've tested this out locally and it works fine. |
pkg/generator: final cleanup of generator.go
|
@hasbro17 I completley failed my rebase 😄, anyway the refactor was too heavy. I will close this PR and reopen a clean one. Is it normally that generator refactor remove all unit tests ? |
|
@etiennecoutaud No that was my mistake. We removed them by accident as part of the refactor. We're going to revert that #315 |
|
No problem, I close this PR and wait for #315. |
|
@etiennecoutaud Can you reopen this in another PR. I think #315 will only change the main template unit test which should be easy to rebase once it's merged. Also looking back I think it's best if we keep the generated code to a minimum and keep the port exposing and service creation utility in the SDK. So the generated main.go should look like: func main() {
printVersion()
sdk.ExposeMetricsPort()
resource := "app.example.com/v1alpha1"
kind := "App"
namespace, err := k8sutil.GetWatchNamespace()
if err != nil {
logrus.Fatalf("Failed to get watch namespace: %v", err)
}
resyncPeriod := 5
logrus.Infof("Watching %s, %s, %s, %d", resource, kind, namespace, resyncPeriod)
sdk.Watch(resource, kind, namespace, resyncPeriod)
sdk.Handle(stub.NewHandler())
sdk.Run(context.TODO())
}And sdk.ExposeMetricsPort() can be defined in func ExposeMetricsPort() {
http.Handle("/"+k8sutil.PrometheusMetricsPortName, promhttp.Handler())
go http.ListenAndServe(":"+k8sutil. PrometheusMetricsPort, nil)
service, err := k8sutil.InitOperatorService()
if err != nil {
logrus.Fatalf("Failed to init operator service: %v", err)
}
err = sdk.Create(service)
if err != nil && !errors.IsAlreadyExists(err) {
logrus.Infof("Failed to create operator service: %v", err)
return
}
logrus.Infof("Metrics service %s created", service.Name)
}This way we can actually use the constants for the metrics port and not have them generated as a number and string in the operator's main.go. It also keeps main.go small. |
|
Yes sure, I will before the end of the week. |
Refer to #222
Generate kubernetes manifest files to integrate operator with Prometheus