Skip to content

Commit 5861bca

Browse files
chore: merge main
2 parents 84d833e + bba1109 commit 5861bca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1882
-226
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ Dockerfile.cross
3131
examples/sample_secret.yaml
3232
examples/dynatrace_secret.yaml
3333
examples/secret.yaml
34+
/examples/datasink/dynatrace-prod-setup.yaml

Makefile

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ build: manifests generate fmt vet ## Build manager binary.
7979

8080
.PHONY: run
8181
run: manifests generate fmt vet ## Run a controller from your host.
82-
go run ./cmd/main.go start
82+
OPERATOR_CONFIG_NAMESPACE=metrics-operator-system go run ./cmd/main.go start
8383

8484
.PHONY: build-docker-binary
8585
build-docker-binary: manifests generate fmt vet ## Build manager binary.
@@ -238,13 +238,11 @@ dev-local-all:
238238
$(MAKE) crossplane-provider-sample
239239
$(MAKE) dev-namespace
240240
$(MAKE) dev-secret
241+
$(MAKE) dev-operator-namespace
241242
$(MAKE) dev-basic-metric
242243
$(MAKE) dev-managed-metric
243244

244245

245-
246-
247-
248246
.PHONY: dev-secret
249247
dev-secret:
250248
kubectl apply -f examples/secret.yaml
@@ -253,6 +251,10 @@ dev-secret:
253251
dev-namespace:
254252
kubectl apply -f examples/namespace.yaml
255253

254+
.PHONY: dev-operator-namespace
255+
dev-operator-namespace:
256+
kubectl create namespace metrics-operator-system --dry-run=client -o yaml | kubectl apply -f -
257+
256258
.PHONY: dev-basic-metric
257259
dev-basic-metric:
258260
kubectl apply -f examples/basic_metric.yaml
@@ -261,6 +263,14 @@ dev-basic-metric:
261263
dev-managed-metric:
262264
kubectl apply -f examples/managed_metric.yaml
263265

266+
.PHONY: dev-apply-dynatrace-prod-setup
267+
dev-apply-dynatrace-prod-setup:
268+
kubectl apply -f examples/datasink/dynatrace-prod-setup.yaml
269+
270+
.PHONY: dev-apply-metric-dynatrace-prod
271+
dev-apply-metric-dynatrace-prod:
272+
kubectl apply -f examples/datasink/metric-using-dynatrace-prod.yaml
273+
264274
.PHONY: dev-v1beta1-compmetric
265275
dev-v1beta1-compmetric:
266276
kubectl apply -f examples/v1beta1/compmetric.yaml

README.md

Lines changed: 106 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ The Metrics Operator is a powerful tool designed to monitor and provide insights
1212
- [Usage](#usage)
1313
- [RBAC Configuration](#rbac-configuration)
1414
- [Remote Cluster Access](#remote-cluster-access)
15+
- [DataSink Configuration](#datasink-configuration)
1516
- [Data Sink Integration](#data-sink-integration)
1617

1718
## Key Features
@@ -124,7 +125,7 @@ graph LR
124125
### Prerequisites
125126

126127
1. Create a namespace for the Metrics Operator.
127-
2. Create a secret containing the data sink credentials in the operator's namespace.
128+
2. Create a DataSink resource and associated authentication secret for your metrics destination.
128129

129130
### Deployment
130131

@@ -139,6 +140,8 @@ helm upgrade --install metrics-operator ghcr.io/sap/github.com/sap/metrics-opera
139140

140141
Replace `<operator-namespace>` and `<version>` with appropriate values.
141142

143+
After deployment, create your DataSink configuration as described in the [DataSink Configuration](#datasink-configuration) section.
144+
142145
## Usage
143146

144147
### Metric
@@ -320,13 +323,113 @@ kubectl apply -f rbac-config.yaml
320323
Remember to update this RBAC configuration whenever you add new resource types to monitor.
321324

322325

326+
## DataSink Configuration
327+
328+
The Metrics Operator uses DataSink custom resources to define where and how metrics data should be sent. This provides a flexible and secure way to configure data destinations.
329+
330+
### Creating a DataSink
331+
332+
Define a DataSink resource to specify the connection details and authentication for your metrics destination:
333+
334+
```yaml
335+
apiVersion: metrics.cloud.sap/v1alpha1
336+
kind: DataSink
337+
metadata:
338+
name: default
339+
namespace: metrics-operator-system
340+
spec:
341+
connection:
342+
endpoint: "https://your-tenant.live.dynatrace.com/api/v2/metrics/ingest"
343+
protocol: "http"
344+
insecureSkipVerify: false
345+
authentication:
346+
apiKey:
347+
secretKeyRef:
348+
name: dynatrace-credentials
349+
key: api-token
350+
```
351+
352+
### DataSink Specification
353+
354+
The `DataSinkSpec` contains the following fields:
355+
356+
#### Connection
357+
- **endpoint**: The target endpoint URL where metrics will be sent
358+
- **protocol**: Communication protocol (`http` or `grpc`)
359+
- **insecureSkipVerify**: (Optional) Skip TLS certificate verification
360+
361+
#### Authentication
362+
- **apiKey**: API key authentication configuration
363+
- **secretKeyRef**: Reference to a Kubernetes Secret containing the API key
364+
- **name**: Name of the Secret
365+
- **key**: Key within the Secret containing the API token
366+
367+
### Using DataSink in Metrics
368+
369+
All metric types support the `dataSinkRef` field to specify which DataSink to use:
370+
371+
```yaml
372+
apiVersion: metrics.cloud.sap/v1alpha1
373+
kind: Metric
374+
metadata:
375+
name: pod-count
376+
spec:
377+
name: "pods.count"
378+
target:
379+
kind: Pod
380+
group: ""
381+
version: v1
382+
dataSinkRef:
383+
name: default # References the DataSink named "default"
384+
```
385+
386+
### Default Behavior
387+
388+
If no `dataSinkRef` is specified in a metric resource, the operator will automatically use a DataSink named "default" in the operator's namespace. This provides backward compatibility and simplifies configuration for single data sink deployments.
389+
390+
### Supported Metric Types
391+
392+
The `dataSinkRef` field is available in all metric resource types:
393+
394+
- [`Metric`](#metric): Basic metrics for Kubernetes resources
395+
- [`ManagedMetric`](#managed-metric): Metrics for Crossplane managed resources
396+
- [`FederatedMetric`](#federated-metric): Metrics across multiple clusters
397+
- [`FederatedManagedMetric`](#federated-managed-metric): Managed resource metrics across multiple clusters
398+
399+
### Examples and Detailed Documentation
400+
401+
For complete examples and more detailed configuration options:
402+
403+
- See the [`examples/datasink/`](examples/datasink/) directory for practical examples
404+
- Read the comprehensive [DataSink Configuration Guide](docs/datasink-configuration.md) for detailed documentation
405+
406+
The examples directory contains:
407+
- Basic DataSink configuration examples
408+
- Examples showing DataSink usage with different metric types
409+
- Migration guidance from legacy configurations
410+
411+
The detailed guide covers:
412+
- Complete specification reference
413+
- Multiple DataSink scenarios
414+
- Advanced configuration options
415+
- Troubleshooting and best practices
416+
417+
### Migration from Legacy Configuration
418+
419+
**Important**: The old method of using hardcoded secret names (such as `co-dynatrace-credentials`) has been deprecated and removed. You must now use DataSink resources to configure your metrics destinations.
420+
421+
To migrate:
422+
1. Create a DataSink resource pointing to your existing authentication secret
423+
2. Update your metric resources to reference the DataSink using `dataSinkRef`
424+
3. Remove any hardcoded secret references from your configuration
425+
323426
## Data Sink Integration
324427

325-
The Metrics Operator sends collected data to a configured data sink for storage and analysis. The data sink (e.g., Dynatrace) provides tools for data aggregation, filtering, and visualization.
428+
The Metrics Operator sends collected data to configured data sinks for storage and analysis. Data sinks (e.g., Dynatrace) provide tools for data aggregation, filtering, and visualization.
326429

327430
To make the most of your metrics:
328431

329-
1. Configure your data sink according to its documentation.
432+
1. Configure your DataSink resources according to your data sink's documentation.
330433
2. Use the data sink's query language or UI to create custom views of your metrics.
331434
3. Set up alerts based on metric thresholds or patterns.
332435
4. Leverage the data sink's analysis tools to gain insights into your system's behavior and performance.

api/v1alpha1/conditions.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,14 @@ const (
3333

3434
// TypeError is a generic condition type that indicates an error has occurred
3535
TypeError = "Error"
36+
37+
// TypeReady is a condition type that indicates the resource is ready
38+
TypeReady = "Ready"
39+
40+
// StatusStringTrue represents the True status string.
41+
StatusStringTrue string = "True"
42+
// StatusStringFalse represents the False status string.
43+
StatusStringFalse string = "False"
44+
// StatusStringUnknown represents the Unknown status string.
45+
StatusStringUnknown string = "Unknown"
3646
)

api/v1alpha1/datasink_types.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
Copyright 2024.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha1
18+
19+
import (
20+
corev1 "k8s.io/api/core/v1"
21+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+
)
23+
24+
// Connection defines the connection details for the DataSink
25+
type Connection struct {
26+
// Endpoint specifies the target endpoint URL
27+
Endpoint string `json:"endpoint"`
28+
}
29+
30+
// APIKeyAuthentication defines API key authentication configuration
31+
type APIKeyAuthentication struct {
32+
// SecretKeyRef references a key in a Kubernetes Secret containing the API key
33+
SecretKeyRef corev1.SecretKeySelector `json:"secretKeyRef"`
34+
}
35+
36+
// Authentication defines authentication mechanisms for the DataSink
37+
type Authentication struct {
38+
// APIKey specifies API key authentication configuration
39+
// +optional
40+
APIKey *APIKeyAuthentication `json:"apiKey,omitempty"`
41+
}
42+
43+
// DataSinkSpec defines the desired state of DataSink
44+
type DataSinkSpec struct {
45+
// Connection specifies the connection details for the data sink
46+
Connection Connection `json:"connection"`
47+
// Authentication specifies the authentication configuration
48+
// +optional
49+
Authentication *Authentication `json:"authentication,omitempty"`
50+
}
51+
52+
// DataSinkStatus defines the observed state of DataSink
53+
type DataSinkStatus struct {
54+
// Conditions represent the latest available observations of an object's state
55+
// +optional
56+
Conditions []metav1.Condition `json:"conditions,omitempty"`
57+
}
58+
59+
// DataSink is the Schema for the datasinks API
60+
// +kubebuilder:object:root=true
61+
// +kubebuilder:subresource:status
62+
// +kubebuilder:printcolumn:name="ENDPOINT",type="string",JSONPath=".spec.connection.endpoint"
63+
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
64+
type DataSink struct {
65+
metav1.TypeMeta `json:",inline"`
66+
metav1.ObjectMeta `json:"metadata,omitempty"`
67+
68+
Spec DataSinkSpec `json:"spec,omitempty"`
69+
Status DataSinkStatus `json:"status,omitempty"`
70+
}
71+
72+
// DataSinkList contains a list of DataSink
73+
// +kubebuilder:object:root=true
74+
type DataSinkList struct {
75+
metav1.TypeMeta `json:",inline"`
76+
metav1.ListMeta `json:"metadata,omitempty"`
77+
Items []DataSink `json:"items"`
78+
}
79+
80+
func init() {
81+
SchemeBuilder.Register(&DataSink{}, &DataSinkList{})
82+
}

api/v1alpha1/federatedmanagedmetric_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ type FederatedManagedMetricSpec struct {
4141
// +kubebuilder:default:="10m"
4242
Interval metav1.Duration `json:"interval,omitempty"`
4343

44+
// DataSinkRef specifies the DataSink to be used for this federated managed metric.
45+
// If not specified, the DataSink named "default" in the operator's
46+
// namespace will be used.
47+
// +optional
48+
DataSinkRef *DataSinkReference `json:"dataSinkRef,omitempty"`
49+
4450
FederatedClusterAccessRef FederateClusterAccessRef `json:"federateClusterAccessRef,omitempty"`
4551
}
4652

api/v1alpha1/federatedmetric_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ type FederatedMetricSpec struct {
4444
// +kubebuilder:default:="10m"
4545
Interval metav1.Duration `json:"interval,omitempty"`
4646

47+
// DataSinkRef specifies the DataSink to be used for this federated metric.
48+
// If not specified, the DataSink named "default" in the operator's
49+
// namespace will be used.
50+
// +optional
51+
DataSinkRef *DataSinkReference `json:"dataSinkRef,omitempty"`
52+
4753
FederatedClusterAccessRef FederateClusterAccessRef `json:"federateClusterAccessRef,omitempty"`
4854
}
4955

api/v1alpha1/managedmetric_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ type ManagedMetricSpec struct {
4646
// +kubebuilder:default:="10m"
4747
Interval metav1.Duration `json:"interval,omitempty"`
4848

49+
// DataSinkRef specifies the DataSink to be used for this managed metric.
50+
// If not specified, the DataSink named "default" in the operator's
51+
// namespace will be used.
52+
// +optional
53+
DataSinkRef *DataSinkReference `json:"dataSinkRef,omitempty"`
54+
4955
// +optional
5056
*RemoteClusterAccessRef `json:"remoteClusterAccessRef,omitempty"`
5157
}

api/v1alpha1/metric_types.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ const (
3636
PhasePending PhaseType = "Pending"
3737
)
3838

39+
// DataSinkReference holds a reference to a DataSink resource.
40+
type DataSinkReference struct {
41+
// Name is the name of the DataSink resource.
42+
// +kubebuilder:validation:Required
43+
Name string `json:"name"`
44+
}
45+
3946
// MetricSpec defines the desired state of Metric
4047
type MetricSpec struct {
4148
// Sets the name that will be used to identify the metric in Dynatrace(or other providers)
@@ -55,6 +62,12 @@ type MetricSpec struct {
5562
// +kubebuilder:default:="10m"
5663
Interval metav1.Duration `json:"interval,omitempty"`
5764

65+
// DataSinkRef specifies the DataSink to be used for this metric.
66+
// If not specified, the DataSink named "default" in the operator's
67+
// namespace will be used.
68+
// +optional
69+
DataSinkRef *DataSinkReference `json:"dataSinkRef,omitempty"`
70+
5871
// +optional
5972
*RemoteClusterAccessRef `json:"remoteClusterAccessRef,omitempty"`
6073

0 commit comments

Comments
 (0)