Skip to content

Commit

Permalink
feat: Initialize the grafana plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Kavinjsir committed Jun 28, 2022
1 parent ade165e commit f3a6ba4
Show file tree
Hide file tree
Showing 40 changed files with 2,253 additions and 9 deletions.
2 changes: 2 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
deployimagev1alpha1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/deploy-image/v1alpha1"
golangv2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2"
golangv3 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3"
grafana "sigs.k8s.io/kubebuilder/v3/pkg/plugins/optional/grafana/alphav1"
)

func main() {
Expand Down Expand Up @@ -62,6 +63,7 @@ func main() {
&kustomizecommonv2alpha.Plugin{},
&declarativev1.Plugin{},
&deployimagev1alpha1.Plugin{},
&grafana.Plugin{},
),
cli.WithPlugins(externalPlugins...),
cli.WithDefaultPlugins(cfgv2.Version, golangv2.Plugin{}),
Expand Down
1 change: 1 addition & 0 deletions docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
- [go/v2 plugin (Deprecated)](./plugins/go-v2-plugin.md)
- [go/v3 plugin](./plugins/go-v3-plugin.md)
- [Declarative V1](./plugins/declarative-v1.md)
- [Grafana V1](./plugins/grafana-v1-alpha.md)
- [Kustomize V1](./plugins/kustomize-v1.md)
- [Plugins Versioning](./plugins/plugins-versioning.md)

Expand Down
19 changes: 10 additions & 9 deletions docs/book/src/plugins/available-plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@

This section describes the plugins supported and shipped in with the Kubebuilder project.

| Plugin | Key | Description |
|---|---|---|
| [go.kubebuilder.io/v2 - (Deprecated)](go-v2-plugin.md) | `go/v2` | Golang plugin responsible for scaffolding the legacy layout provided with Kubebuilder CLI >= `2.0.0` and < `3.0.0`. |
| [go.kubebuilder.io/v3 - (Default scaffold with Kubebuilder init)](go-v3-plugin.md) | `go/v3` | Default scaffold used for creating a project when no plugin(s) are provided. Responsible for scaffolding Golang projects and its configurations. |
| [declarative.go.kubebuilder.io/v1](declarative-v1.md) | `declarative/v1` | Optional plugin used to scaffold APIs/controllers using the [kubebuilder-declarative-pattern][kubebuilder-declarative-pattern] project. |
| [kustomize.common.kubebuilder.io/v1](kustomize-v1.md) | `kustomize/v1` | Responsible for scaffold all manifests to configure the projects with [kustomize(v3)][kustomize]. (create and update the the `config/` directory). This plugin is used in the composition to create the plugin (`go/v3`). |
| [kustomize.common.kubebuilder.io/v2-alpha](kustomize-v2-alpha.md) | `kustomize/v2-alpha` | It has the same purpose of `kustomize/v1`. However, it works with [kustomize][kustomize] version `v4` and addresses the required changes for future kustomize configurations. It will probably be used with the future `go/v4-alpha` plugin. |
| `base.go.kubebuilder.io/v3` | `base/v3` | Responsible for scaffold all files which specific requires Golang. This plugin is used in the composition to create the plugin (`go/v3`) |
| Plugin | Key | Description |
| ---------------------------------------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [go.kubebuilder.io/v2 - (Deprecated)](go-v2-plugin.md) | `go/v2` | Golang plugin responsible for scaffolding the legacy layout provided with Kubebuilder CLI >= `2.0.0` and < `3.0.0`. |
| [go.kubebuilder.io/v3 - (Default scaffold with Kubebuilder init)](go-v3-plugin.md) | `go/v3` | Default scaffold used for creating a project when no plugin(s) are provided. Responsible for scaffolding Golang projects and its configurations. |
| [declarative.go.kubebuilder.io/v1](declarative-v1.md) | `declarative/v1` | Optional plugin used to scaffold APIs/controllers using the [kubebuilder-declarative-pattern][kubebuilder-declarative-pattern] project. |
| [kustomize.common.kubebuilder.io/v1](kustomize-v1.md) | `kustomize/v1` | Responsible for scaffold all manifests to configure the projects with [kustomize(v3)][kustomize]. (create and update the the `config/` directory). This plugin is used in the composition to create the plugin (`go/v3`). |
| [kustomize.common.kubebuilder.io/v2-alpha](kustomize-v2-alpha.md) | `kustomize/v2-alpha` | It has the same purpose of `kustomize/v1`. However, it works with [kustomize][kustomize] version `v4` and addresses the required changes for future kustomize configurations. It will probably be used with the future `go/v4-alpha` plugin. |
| `base.go.kubebuilder.io/v3` | `base/v3` | Responsible for scaffold all files which specific requires Golang. This plugin is used in the composition to create the plugin (`go/v3`) |
| [grafana.kubebuilder.io/v1-alpha](grafana-v1-alpha.md) | `grafana/v1-alpha` | Optional plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. |

<aside class="note">

<h1>You can also create your own plugins, see:</h1>

- [Creating your own plugins][create-plugins].
- [Creating your own plugins][create-plugins].

</aside>

Expand Down
86 changes: 86 additions & 0 deletions docs/book/src/plugins/grafana-v1-alpha.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Grafana Plugin (`grafana/v1-alpha`)

The Grafana plugin is an optional plugin that can be used to scaffold Grafana Dashboards to allow you to check out the default metrics which are exported by projects using [controller-runtime][controller-runtime].

<aside class="note">
<h1>Examples</h1>

You can check its default scaffold by looking at the `project-v3-with-grafana` projects under the [testdata][testdata] directory on the root directory of the Kubebuilder project.

</aside>

## When to use it ?

- If you are looking to observe the metrics exported by [controller metrics][controller-metrics] and collected by Prometheus via [Grafana][grafana].

## How to use it ?

### Prerequisites:

- Access to [Grafana](https://grafana.com/docs/grafana/latest/setup-grafana/installation/).
- Make sure you have [dashboard edit permission](https://grafana.com/docs/grafana/next/administration/roles-and-permissions/#dashboard-permissions).
- Your project must be using [controller-runtime][controller-runtime] to expose the metrics via the [controller default metrics][controller-metrics] and they need to be collected by Prometheus.
- Access to [Prometheus][prometheus].
- Prometheus should have an endpoint exposed. (For `prometheus-operator`, this is similar as: http://prometheus-k8s.monitoring.svc:9090 )
- The endpoint is ready to/already become the datasource of your Grafana. See [Add a data source](https://grafana.com/docs/grafana/latest/datasources/add-a-data-source/)

<aside class="note">

Check the [metrics][reference-metrics-doc] to know how to enable the metrics for your projects scaffold with Kubebuilder.

See that in the [config/prometheus][kustomize-plugin] you will find the ServiceMonitor to enable the metrics in the default endpoint `/metrics`.

</aside>

### Basic Usage

The Grafana plugin is attached to the `init` subcommand and the `edit` subcommand:

```sh
# Initialize a new project with grafana plugin
kubebuilder init --plugins grafana.kubebuilder.io/v1-alpha

# Enable grafana plugin to an existing project
kubebuilder edit --plugins grafana.kubebuilder.io/v1-alpha
```

The plugin will create a new directory and scaffold the JSON files under it (i.e. `grafana/controller-runtime-metrics.json`).

Once the JSON file is scaffolded, you can just copy the content.
Then, visit `<your-grafana-url>/dashboard/import` to [import a new dashboard](https://grafana.com/docs/grafana/latest/dashboards/export-import/#import-dashboard).

![output](https://user-images.githubusercontent.com/18136486/175382307-9a6c3b8b-6cc7-4339-b221-2539d0fec042.gif)

## Subcommands

The Grafana plugin implements the following subcommands:

- edit (`$ kubebuilder edit [OPTIONS]`)

- init (`$ kubebuilder init [OPTIONS]`)

## Affected files

The following scaffolds will be created or updated by this plugin:

- `grafana/*.json`

## Further resources

- Refer to a sample of `servicemonitor` provided by [kustomize plugin][kustomize-plugin]
- Check the [plugin implementation][plugin-implementation]
- [Grafana Docs][grafana-docs] of importing JSON file
- The usage of servicemonitor by [Prometheus Operator][servicemonitor]

[controller-metrics]: https://book.kubebuilder.io/reference/metrics-reference.html
[controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime
[grafana]: https://grafana.com/docs/grafana/next/
[grafana-docs]: https://grafana.com/docs/grafana/latest/dashboards/export-import/#import-dashboard
[kustomize-plugin]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/testdata/project-v3/config/prometheus/monitor.yaml
[kube-prometheus]: https://github.com/prometheus-operator/kube-prometheus
[plugin-implementation]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/pkg/plugins/optional/grafana/alphav1
[prometheus]: https://prometheus.io/docs/introduction/overview/
[prom-operator]: https://prometheus-operator.dev/docs/prologue/introduction/
[reference-metrics-doc]: https://book.kubebuilder.io/reference/metrics.html#exporting-metrics-for-prometheus
[servicemonitor]: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md#related-resources
[testdata]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata
73 changes: 73 additions & 0 deletions pkg/plugins/optional/grafana/alphav1/edit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
Copyright 2022 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 alphav1

import (
"errors"
"fmt"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/optional/grafana/alphav1/scaffolds"
)

var _ plugin.EditSubcommand = &editSubcommand{}

type editSubcommand struct {
config config.Config
}

// nolint: lll
func (p *editSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) {
subcmdMeta.Description = `This command will add Grafana manifests to the project:
- A JSON file includes dashboard manifest that can be directly copied to Grafana Web UI.
('grafana/controller-runtime-metrics.json')
NOTE: This plugin requires:
- Access to Prometheus
- Your project must be using controller-runtime to expose the metrics via the controller metrics and they need to be collected by Prometheus.
- Access to Grafana (https://grafana.com/docs/grafana/latest/setup-grafana/installation/)
Check how to enable the metrics for your project by looking at the doc: https://book.kubebuilder.io/reference/metrics.html
`
subcmdMeta.Examples = fmt.Sprintf(` # Initialize a common project with this plugin
%[1]s edit --plugins=grafana.kubebuilder.io/v1-alpha
`, cliMeta.CommandName)
}

func (p *editSubcommand) InjectConfig(c config.Config) error {
p.config = c
return nil
}

func (p *editSubcommand) Scaffold(fs machinery.Filesystem) error {
cfg := pluginConfig{}
err := p.config.DecodePluginConfig(pluginKey, cfg)
if !errors.As(err, &config.UnsupportedFieldError{}) {
if err != nil && !errors.As(err, &config.PluginKeyNotFoundError{}) {
return err
}

if err = p.config.EncodePluginConfig(pluginKey, cfg); err != nil {
return err
}
}

scaffolder := scaffolds.NewEditScaffolder()
scaffolder.InjectFS(fs)
return scaffolder.Scaffold()
}
77 changes: 77 additions & 0 deletions pkg/plugins/optional/grafana/alphav1/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
Copyright 2022 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 alphav1

import (
"errors"
"fmt"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/optional/grafana/alphav1/scaffolds"
)

var _ plugin.InitSubcommand = &initSubcommand{}

type initSubcommand struct {
config config.Config
}

// nolint: lll
func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) {
subcmdMeta.Description = `Initialize a project with this Grafana Plugin includes the following files:
- A JSON file includes dashboard manifest that can be directly copied to Grafana Web UI.
('grafana/controller-runtime-metrics.json')
NOTE: This plugin requires:
- Access to Prometheus
- Your project must be using controller-runtime to expose the metrics via the controller metrics and they need to be collected by Prometheus.
- Access to Grafana (https://grafana.com/docs/grafana/latest/setup-grafana/installation/)
Check how to enable the metrics for your project by looking at the doc: https://book.kubebuilder.io/reference/metrics.html
`

subcmdMeta.Examples = fmt.Sprintf(` # Initialize a common project with this plugin
%[1]s init --plugins=grafana.kubebuilder.io/v1-alpha
`, cliMeta.CommandName)
}

func (p *initSubcommand) InjectConfig(c config.Config) error {
p.config = c
return nil
}

func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error {
cfg := pluginConfig{}

err := p.config.DecodePluginConfig(pluginKey, cfg)
if !errors.As(err, &config.UnsupportedFieldError{}) {

if err != nil && !errors.As(err, &config.PluginKeyNotFoundError{}) {
return err
}

if err = p.config.EncodePluginConfig(pluginKey, cfg); err != nil {
return err
}

}

scaffolder := scaffolds.NewInitScaffolder()
scaffolder.InjectFS(fs)
return scaffolder.Scaffold()
}
60 changes: 60 additions & 0 deletions pkg/plugins/optional/grafana/alphav1/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Copyright 2022 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 alphav1

import (
"sigs.k8s.io/kubebuilder/v3/pkg/config"
cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3"
"sigs.k8s.io/kubebuilder/v3/pkg/model/stage"
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins"
)

const pluginName = "grafana." + plugins.DefaultNameQualifier

var (
pluginVersion = plugin.Version{Number: 1, Stage: stage.Alpha}
supportedProjectVersions = []config.Version{cfgv3.Version}
pluginKey = plugin.KeyFor(Plugin{})
)

// Plugin implements the plugin.Full interface
type Plugin struct {
initSubcommand
editSubcommand
}

var (
_ plugin.Init = Plugin{}
)

// Name returns the name of the plugin
func (Plugin) Name() string { return pluginName }

// Version returns the version of the grafana plugin
func (Plugin) Version() plugin.Version { return pluginVersion }

// SupportedProjectVersions returns an array with all project versions supported by the plugin
func (Plugin) SupportedProjectVersions() []config.Version { return supportedProjectVersions }

// GetInitSubcommand will return the subcommand which is responsible for initializing and scaffolding grafana manifests
func (p Plugin) GetInitSubcommand() plugin.InitSubcommand { return &p.initSubcommand }

// GetEditSubcommand will return the subcommand which is responsible for adding grafana manifests
func (p Plugin) GetEditSubcommand() plugin.EditSubcommand { return &p.editSubcommand }

type pluginConfig struct{}
Loading

0 comments on commit f3a6ba4

Please sign in to comment.