Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement reporting for Flux installation status and statistics #46

Merged
merged 8 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,13 @@ resources:
kind: FluxInstance
path: github.com/controlplaneio-fluxcd/flux-operator/api/v1
version: v1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: controlplane.io
group: fluxcd
kind: FluxReport
path: github.com/controlplaneio-fluxcd/flux-operator/api/v1
version: v1
version: "3"
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ the lifecycle of CNCF [Flux CD](https://fluxcd.io) and the
- Automates the patching of hotfixes and CVEs affecting the Flux controllers container images.
- Simplifies the configuration of multi-tenancy lockdown on shared Kubernetes clusters.
- Allows syncing the cluster state from Git repositories, OCI artifacts and S3-compatible storage.
- Generates detailed reports about the Flux deployment readiness status and reconcilers statistics.
- Provides a security-first approach to the Flux deployment and FIPS compliance.
- Incorporates best practices for running Flux at scale with persistent storage and vertical scaling.
- Manages the update of Flux custom resources and prevents disruption during the upgrade process.
Expand All @@ -32,6 +33,7 @@ the lifecycle of CNCF [Flux CD](https://fluxcd.io) and the

- [Flux operator installation](https://fluxcd.control-plane.io/operator/install/)
- [Flux controllers configuration](https://fluxcd.control-plane.io/operator/flux-config/)
- [Flux instance customization](https://fluxcd.control-plane.io/operator/flux-kustomize/)
- [Cluster sync configuration](https://fluxcd.control-plane.io/operator/flux-sync/)
- [Migration of bootstrapped clusters](https://fluxcd.control-plane.io/operator/flux-bootstrap-migration/)
- [FluxInstance API reference](https://fluxcd.control-plane.io/operator/fluxinstance/)
Expand All @@ -55,7 +57,7 @@ helm install flux-operator oci://ghcr.io/controlplaneio-fluxcd/charts/flux-opera
### Install the Flux Controllers

Create a [FluxInstance](https://fluxcd.control-plane.io/operator/fluxinstance/) resource
in the `flux-system` namespace to install the latest Flux stable version:
named `flux` in the `flux-system` namespace to install the latest Flux stable version:

```yaml
apiVersion: fluxcd.controlplane.io/v1
Expand Down Expand Up @@ -136,6 +138,20 @@ flux create secret git flux-system \
> container registries and S3-compatible storage, refer to the
> [cluster sync guide](https://fluxcd.control-plane.io/operator/flux-sync/).

### Monitor the Flux Installation

To monitor the Flux deployment status, check the
[FluxReport](https://fluxcd.control-plane.io/operator/fluxreport/)
resource in the `flux-system` namespace:

```shell
kubectl get fluxreport/flux -n flux-system -o yaml
```

The report is update at regular intervals and contains information about the deployment
readiness status, the distribution details, reconcilers statistics, Flux CRDs versions,
the cluster sync status and more.

## License

The Flux Operator is an open-source project licensed under the
Expand Down
8 changes: 5 additions & 3 deletions api/v1/fluxinstance_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import (
)

const (
FluxInstanceKind = "FluxInstance"
EnabledValue = "enabled"
DisabledValue = "disabled"
DefaultInstanceName = "flux"
DefaultNamespace = "flux-system"
FluxInstanceKind = "FluxInstance"
EnabledValue = "enabled"
DisabledValue = "disabled"
)

var (
Expand Down
211 changes: 211 additions & 0 deletions api/v1/fluxreport_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
// Copyright 2024 Stefan Prodan.
// SPDX-License-Identifier: AGPL-3.0

package v1

import (
"strings"
"time"

"github.com/fluxcd/pkg/apis/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const FluxReportKind = "FluxReport"

// FluxReportSpec defines the observed state of a Flux installation.
type FluxReportSpec struct {
// Distribution is the version information of the Flux installation.
// +required
Distribution FluxDistributionStatus `json:"distribution"`

// ComponentsStatus is the status of the Flux controller deployments.
// +optional
ComponentsStatus []FluxComponentStatus `json:"components,omitempty"`

// ReconcilersStatus is the list of Flux reconcilers and
// their statistics grouped by API kind.
// +optional
ReconcilersStatus []FluxReconcilerStatus `json:"reconcilers,omitempty"`

// SyncStatus is the status of the cluster sync
// Source and Kustomization resources.
// +optional
SyncStatus *FluxSyncStatus `json:"sync,omitempty"`
}

// FluxDistributionStatus defines the version information of the Flux instance.
type FluxDistributionStatus struct {
// Entitlement is the entitlement verification status.
// +required
Entitlement string `json:"entitlement"`

// Status is a human-readable message indicating details
// about the distribution observed state.
// +required
Status string `json:"status"`

// Version is the version of the Flux instance.
// +optional
Version string `json:"version,omitempty"`

// ManagedBy is the name of the operator managing the Flux instance.
// +optional
ManagedBy string `json:"managedBy,omitempty"`
}

// FluxComponentStatus defines the observed state of a Flux component.
type FluxComponentStatus struct {
// Name is the name of the Flux component.
// +required
Name string `json:"name"`

// Ready is the readiness status of the Flux component.
// +required
Ready bool `json:"ready"`
stefanprodan marked this conversation as resolved.
Show resolved Hide resolved

// Status is a human-readable message indicating details
// about the Flux component observed state.
// +required
Status string `json:"status"`

// Image is the container image of the Flux component.
// +required
Image string `json:"image"`
}

// FluxReconcilerStatus defines the observed state of a Flux reconciler.
type FluxReconcilerStatus struct {
// APIVersion is the API version of the Flux resource.
// +required
APIVersion string `json:"apiVersion"`

// Kind is the kind of the Flux resource.
// +required
Kind string `json:"kind"`

// Stats is the reconcile statics of the Flux resource kind.
// +optional
Stats FluxReconcilerStats `json:"stats,omitempty"`
}

// FluxReconcilerStats defines the reconcile statistics.
type FluxReconcilerStats struct {
// Running is the number of reconciled
// resources in the Running state.
// +required
Running int `json:"running"`

// Failing is the number of reconciled
// resources in the Failing state.
// +required
Failing int `json:"failing"`

// Suspended is the number of reconciled
// resources in the Suspended state.
// +required
Suspended int `json:"suspended"`

// TotalSize is the total size of the artifacts in storage.
// +optional
TotalSize string `json:"totalSize,omitempty"`
}

// FluxSyncStatus defines the observed state of the cluster sync.
type FluxSyncStatus struct {
// ID is the identifier of the sync.
// +required
ID string `json:"id"`

// Path is the kustomize path of the sync.
// +optional
Path string `json:"path,omitempty"`

// Ready is the readiness status of the sync.
// +required
Ready bool `json:"ready"`

// Status is a human-readable message indicating details
// about the sync observed state.
// +required
Status string `json:"status"`

// Source is the URL of the source repository.
// +optional
Source string `json:"source,omitempty"`
}

// FluxReportStatus defines the readiness of a FluxReport.
type FluxReportStatus struct {
meta.ReconcileRequestStatus `json:",inline"`

// Conditions contains the readiness conditions of the object.
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Entitlement",type="string",JSONPath=".spec.distribution.entitlement",description="",priority=10
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
// +kubebuilder:printcolumn:name="LastUpdated",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].lastTransitionTime",description=""

// FluxReport is the Schema for the fluxreports API.
type FluxReport struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec FluxReportSpec `json:"spec,omitempty"`
Status FluxReportStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// FluxReportList contains a list of FluxReport.
type FluxReportList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []FluxReport `json:"items"`
}

// GetConditions returns the status conditions of the object.
func (in *FluxReport) GetConditions() []metav1.Condition {
return in.Status.Conditions
}

// SetConditions sets the status conditions on the object.
func (in *FluxReport) SetConditions(conditions []metav1.Condition) {
in.Status.Conditions = conditions
}

// IsDisabled returns true if the object has the reconcile annotation set to 'disabled'.
func (in *FluxReport) IsDisabled() bool {
val, ok := in.GetAnnotations()[ReconcileAnnotation]
return ok && strings.ToLower(val) == DisabledValue
}

// GetInterval returns the interval at which the object should be reconciled.
// If no interval is set, the default is 10 minutes.
func (in *FluxReport) GetInterval() time.Duration {
val, ok := in.GetAnnotations()[ReconcileAnnotation]
if ok && strings.ToLower(val) == DisabledValue {
return 0
}
defaultInterval := 10 * time.Minute
val, ok = in.GetAnnotations()[ReconcileEveryAnnotation]
if !ok {
return defaultInterval
}
interval, err := time.ParseDuration(val)
if err != nil {
return defaultInterval
}
return interval
}

func init() {
SchemeBuilder.Register(&FluxReport{}, &FluxReportList{})
}
Loading