diff --git a/CHANGELOG.md b/CHANGELOG.md index fb884709e..805af9186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan - [#124](https://github.com/kobsio/kobs/pull/124): Add `sql` mode for ClickHouse to execute raw SQL queries. - [#126](https://github.com/kobsio/kobs/pull/126): Show request details when gettings logs from ClickHouse. - [#127](https://github.com/kobsio/kobs/pull/127): Allow `ILIKE` queries for ClickHouse logs, using the new `=~` operator. +- [#128](https://github.com/kobsio/kobs/pull/128): Allow users to specify dashboards within a Team or Application via the new `inline` property. ### Fixed diff --git a/deploy/helm/kobs/Chart.yaml b/deploy/helm/kobs/Chart.yaml index 9c86ab7fa..3cb778e1e 100644 --- a/deploy/helm/kobs/Chart.yaml +++ b/deploy/helm/kobs/Chart.yaml @@ -4,5 +4,5 @@ description: Kubernetes Observability Platform type: application home: https://kobs.io icon: https://kobs.io/assets/images/logo.svg -version: 0.5.4 +version: 0.6.0 appVersion: v0.5.0 diff --git a/deploy/helm/kobs/crds/kobs.io_applications.yaml b/deploy/helm/kobs/crds/kobs.io_applications.yaml index 8e7d11e28..67068074a 100644 --- a/deploy/helm/kobs/crds/kobs.io_applications.yaml +++ b/deploy/helm/kobs/crds/kobs.io_applications.yaml @@ -44,6 +44,75 @@ spec: type: string description: type: string + inline: + properties: + rows: + items: + properties: + description: + type: string + panels: + items: + properties: + colSpan: + format: int64 + type: integer + description: + type: string + plugin: + properties: + name: + type: string + options: + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + rowSpan: + format: int64 + type: integer + title: + type: string + required: + - plugin + - title + type: object + type: array + size: + format: int64 + type: integer + title: + type: string + required: + - panels + type: object + type: array + variables: + items: + properties: + hide: + type: boolean + label: + type: string + name: + type: string + plugin: + properties: + name: + type: string + options: + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + required: + - name + - plugin + type: object + type: array + required: + - rows + type: object name: type: string namespace: @@ -55,7 +124,6 @@ spec: title: type: string required: - - name - title type: object type: array diff --git a/deploy/helm/kobs/crds/kobs.io_teams.yaml b/deploy/helm/kobs/crds/kobs.io_teams.yaml index 23aa8e526..0032c04d7 100644 --- a/deploy/helm/kobs/crds/kobs.io_teams.yaml +++ b/deploy/helm/kobs/crds/kobs.io_teams.yaml @@ -44,6 +44,75 @@ spec: type: string description: type: string + inline: + properties: + rows: + items: + properties: + description: + type: string + panels: + items: + properties: + colSpan: + format: int64 + type: integer + description: + type: string + plugin: + properties: + name: + type: string + options: + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + rowSpan: + format: int64 + type: integer + title: + type: string + required: + - plugin + - title + type: object + type: array + size: + format: int64 + type: integer + title: + type: string + required: + - panels + type: object + type: array + variables: + items: + properties: + hide: + type: boolean + label: + type: string + name: + type: string + plugin: + properties: + name: + type: string + options: + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + required: + - name + - plugin + type: object + type: array + required: + - rows + type: object name: type: string namespace: @@ -55,7 +124,6 @@ spec: title: type: string required: - - name - title type: object type: array diff --git a/deploy/kustomize/crds/kobs.io_applications.yaml b/deploy/kustomize/crds/kobs.io_applications.yaml index 8e7d11e28..67068074a 100644 --- a/deploy/kustomize/crds/kobs.io_applications.yaml +++ b/deploy/kustomize/crds/kobs.io_applications.yaml @@ -44,6 +44,75 @@ spec: type: string description: type: string + inline: + properties: + rows: + items: + properties: + description: + type: string + panels: + items: + properties: + colSpan: + format: int64 + type: integer + description: + type: string + plugin: + properties: + name: + type: string + options: + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + rowSpan: + format: int64 + type: integer + title: + type: string + required: + - plugin + - title + type: object + type: array + size: + format: int64 + type: integer + title: + type: string + required: + - panels + type: object + type: array + variables: + items: + properties: + hide: + type: boolean + label: + type: string + name: + type: string + plugin: + properties: + name: + type: string + options: + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + required: + - name + - plugin + type: object + type: array + required: + - rows + type: object name: type: string namespace: @@ -55,7 +124,6 @@ spec: title: type: string required: - - name - title type: object type: array diff --git a/deploy/kustomize/crds/kobs.io_teams.yaml b/deploy/kustomize/crds/kobs.io_teams.yaml index 23aa8e526..0032c04d7 100644 --- a/deploy/kustomize/crds/kobs.io_teams.yaml +++ b/deploy/kustomize/crds/kobs.io_teams.yaml @@ -44,6 +44,75 @@ spec: type: string description: type: string + inline: + properties: + rows: + items: + properties: + description: + type: string + panels: + items: + properties: + colSpan: + format: int64 + type: integer + description: + type: string + plugin: + properties: + name: + type: string + options: + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + rowSpan: + format: int64 + type: integer + title: + type: string + required: + - plugin + - title + type: object + type: array + size: + format: int64 + type: integer + title: + type: string + required: + - panels + type: object + type: array + variables: + items: + properties: + hide: + type: boolean + label: + type: string + name: + type: string + plugin: + properties: + name: + type: string + options: + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + required: + - name + - plugin + type: object + type: array + required: + - rows + type: object name: type: string namespace: @@ -55,7 +124,6 @@ spec: title: type: string required: - - name - title type: object type: array diff --git a/docs/resources/applications.md b/docs/resources/applications.md index dd29ceffa..24b212319 100644 --- a/docs/resources/applications.md +++ b/docs/resources/applications.md @@ -73,10 +73,18 @@ Define the dashboards, which should be used for the application. | ----- | ---- | ----------- | -------- | | cluster | string | Cluster of the dashboard. If this field is omitted kobs will look in the same cluster as the application was created in. | No | | namespace | string | Namespace of the dashboard. If this field is omitted kobs will look in the same namespace as the application was created in. | No | -| name | string | Name of the dashboard. | Yes | +| name | string | Name of the dashboard. **Note:** You have not to provide a name, if you use the **inline** property. | Yes | | title | string | Title for the dashboard | Yes | | description | string | The description can be used to explain the content of the dashboard. | No | | placeholders | map | A map of placeholders, whith the name as key and the value for the placeholder as value. More information for placeholders can be found in the documentation for [Dashboards](./dashboards.md). | No | +| inline | [Inline](#inline) | Specify a complete dashboard within the reference. This can be used if you just use the dashboard within one application. | No | + +### Inline + +| Field | Type | Description | Required | +| ----- | ---- | ----------- | -------- | +| variables | [[]Variable](./dashboards.md#Variable) | A list of variables, where the values are loaded by the specified plugin. | No | +| rows | [[]Row](./dashboards.md#row) | A list of rows for the dashboard. | Yes | ## Example diff --git a/docs/resources/dashboards.md b/docs/resources/dashboards.md index 65e70d645..e576e7b96 100644 --- a/docs/resources/dashboards.md +++ b/docs/resources/dashboards.md @@ -21,7 +21,7 @@ In the following you can found the specification for the Dashboard CRD. On the b | description | string | Provide a descriptions for the dashboard with additional details. | No | | placeholders | [[]Placeholder](#placeholder) | A list of placeholders, which can be directly set by the user. | No | | variables | [[]Variable](#Variable) | A list of variables, where the values are loaded by the specified plugin. | No | -| Rows | [[]Row](#row) | A list of rows for the dashboard. | Yes | +| rows | [[]Row](#row) | A list of rows for the dashboard. | Yes | ### Placeholder diff --git a/docs/resources/teams.md b/docs/resources/teams.md index f2dd8c91b..7ce9137a6 100644 --- a/docs/resources/teams.md +++ b/docs/resources/teams.md @@ -32,10 +32,18 @@ Define the dashboards, which should be used for the team. | ----- | ---- | ----------- | -------- | | cluster | string | Cluster of the dashboard. If this field is omitted kobs will look in the same cluster as the application was created in. | No | | namespace | string | Namespace of the dashboard. If this field is omitted kobs will look in the same namespace as the application was created in. | No | -| name | string | Name of the dashboard. | Yes | +| name | string | Name of the dashboard. **Note:** You have not to provide a name, if you use the **inline** property. | Yes | | title | string | Title for the dashboard | Yes | | description | string | The description can be used to explain the content of the dashboard. | No | | placeholders | map | A map of placeholders, whith the name as key and the value for the placeholder as value. More information for placeholders can be found in the documentation for [Dashboards](./dashboards.md). | No | +| inline | [Inline](#inline) | Specify a complete dashboard within the reference. This can be used if you just use the dashboard within one team. | No | + +### Inline + +| Field | Type | Description | Required | +| ----- | ---- | ----------- | -------- | +| variables | [[]Variable](./dashboards.md#Variable) | A list of variables, where the values are loaded by the specified plugin. | No | +| rows | [[]Row](./dashboards.md#row) | A list of rows for the dashboard. | Yes | ## Example diff --git a/pkg/api/apis/dashboard/v1beta1/types.go b/pkg/api/apis/dashboard/v1beta1/types.go index 4d0fd1759..43f1c4d31 100644 --- a/pkg/api/apis/dashboard/v1beta1/types.go +++ b/pkg/api/apis/dashboard/v1beta1/types.go @@ -72,8 +72,14 @@ type Plugin struct { type Reference struct { Cluster string `json:"cluster,omitempty"` Namespace string `json:"namespace,omitempty"` - Name string `json:"name"` + Name string `json:"name,omitempty"` Title string `json:"title"` Description string `json:"description,omitempty"` Placeholders map[string]string `json:"placeholders,omitempty"` + Inline *ReferenceInline `json:"inline,omitempty"` +} + +type ReferenceInline struct { + Variables []Variable `json:"variables,omitempty"` + Rows []Row `json:"rows"` } diff --git a/pkg/api/apis/dashboard/v1beta1/zz_generated.deepcopy.go b/pkg/api/apis/dashboard/v1beta1/zz_generated.deepcopy.go index d9c7ef3dd..d5f12ef2a 100644 --- a/pkg/api/apis/dashboard/v1beta1/zz_generated.deepcopy.go +++ b/pkg/api/apis/dashboard/v1beta1/zz_generated.deepcopy.go @@ -184,6 +184,11 @@ func (in *Reference) DeepCopyInto(out *Reference) { (*out)[key] = val } } + if in.Inline != nil { + in, out := &in.Inline, &out.Inline + *out = new(ReferenceInline) + (*in).DeepCopyInto(*out) + } return } @@ -197,6 +202,36 @@ func (in *Reference) DeepCopy() *Reference { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReferenceInline) DeepCopyInto(out *ReferenceInline) { + *out = *in + if in.Variables != nil { + in, out := &in.Variables, &out.Variables + *out = make([]Variable, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Rows != nil { + in, out := &in.Rows, &out.Rows + *out = make([]Row, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReferenceInline. +func (in *ReferenceInline) DeepCopy() *ReferenceInline { + if in == nil { + return nil + } + out := new(ReferenceInline) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Row) DeepCopyInto(out *Row) { *out = *in diff --git a/plugins/core/src/components/plugin/PluginPanel.tsx b/plugins/core/src/components/plugin/PluginPanel.tsx index 38b8743ca..27f5abc95 100644 --- a/plugins/core/src/components/plugin/PluginPanel.tsx +++ b/plugins/core/src/components/plugin/PluginPanel.tsx @@ -28,7 +28,7 @@ export const PluginPanel: React.FunctionComponent = ({ if (!pluginDetails || !Component) { return ( - + {pluginDetails ? (

The plugin {pluginDetails.displayName} of tpye {pluginDetails.type} does not implements a diff --git a/plugins/dashboards/dashboards.go b/plugins/dashboards/dashboards.go index 8c9c98383..7a3c98fb7 100644 --- a/plugins/dashboards/dashboards.go +++ b/plugins/dashboards/dashboards.go @@ -98,28 +98,40 @@ func (router *Router) getDashboards(w http.ResponseWriter, r *http.Request) { reference.Namespace = data.Defaults.Namespace } - cluster := router.clusters.GetCluster(reference.Cluster) - if cluster == nil { - errresponse.Render(w, r, nil, http.StatusBadRequest, "Invalid cluster name") - return - } - - dashboard, err := cluster.GetDashboard(r.Context(), reference.Namespace, reference.Name) - if err != nil { - errresponse.Render(w, r, err, http.StatusBadRequest, "Could not get dashboard") - return - } + if reference.Inline != nil { + dashboards = append(dashboards, &dashboard.DashboardSpec{ + Cluster: "-", + Namespace: "-", + Name: "-", + Title: reference.Title, + Description: reference.Description, + Variables: reference.Inline.Variables, + Rows: reference.Inline.Rows, + }) + } else { + cluster := router.clusters.GetCluster(reference.Cluster) + if cluster == nil { + errresponse.Render(w, r, nil, http.StatusBadRequest, "Invalid cluster name") + return + } - if reference.Placeholders != nil { - dashboard, err = placeholders.Replace(reference.Placeholders, *dashboard) + dashboard, err := cluster.GetDashboard(r.Context(), reference.Namespace, reference.Name) if err != nil { - errresponse.Render(w, r, err, http.StatusBadRequest, "Could not replace placeholders") + errresponse.Render(w, r, err, http.StatusBadRequest, "Could not get dashboard") return } - } - dashboard.Title = reference.Title - dashboards = append(dashboards, dashboard) + if reference.Placeholders != nil { + dashboard, err = placeholders.Replace(reference.Placeholders, *dashboard) + if err != nil { + errresponse.Render(w, r, err, http.StatusBadRequest, "Could not replace placeholders") + return + } + } + + dashboard.Title = reference.Title + dashboards = append(dashboards, dashboard) + } } log.WithFields(logrus.Fields{"count": len(dashboards)}).Tracef("getDashboards") diff --git a/plugins/dashboards/src/utils/interfaces.ts b/plugins/dashboards/src/utils/interfaces.ts index 99bba877c..fef274b39 100644 --- a/plugins/dashboards/src/utils/interfaces.ts +++ b/plugins/dashboards/src/utils/interfaces.ts @@ -50,16 +50,22 @@ export interface IPlugin { export interface IReference { cluster?: string; namespace?: string; - name: string; + name?: string; title: string; description?: string; placeholders?: IPlaceholders; + inline?: IReferenceInline; } export interface IPlaceholders { [key: string]: string; } +export interface IReferenceInline { + variables?: IVariable[]; + rows: IRow[]; +} + // IVariableValues is an extension of the IVariable interface. It contains the additional fields for the selected // variable value and all possible variable values. export interface IVariableValues extends IVariable {