Skip to content

Commit 6202f38

Browse files
feat: emit the cluster profile objects (#941)
1 parent 381e56e commit 6202f38

File tree

20 files changed

+944
-58
lines changed

20 files changed

+944
-58
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ install-hub-agent-helm:
165165
--set webhookClientConnectionType=service \
166166
--set enableV1Alpha1APIs=true \
167167
--set enableV1Beta1APIs=false \
168+
--set enableClusterInventoryAPI=true \
168169
--set logFileMaxSize=1000000
169170

170171
.PHONY: e2e-v1alpha1-hub-kubeconfig-secret
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../config/crd/bases/multicluster.x-k8s.io_clusterprofiles.yaml

charts/hub-agent/templates/deployment.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@ spec:
3030
- -add_dir_header
3131
- --enable-v1alpha1-apis={{ .Values.enableV1Alpha1APIs }}
3232
- --enable-v1beta1-apis={{ .Values.enableV1Beta1APIs }}
33+
- --enable-cluster-inventory-apis={{ .Values.enableClusterInventoryAPI }}
3334
- --max-concurrent-cluster-placement={{ .Values.MaxConcurrentClusterPlacement }}
3435
- --concurrent-resource-change-syncs={{ .Values.ConcurrentResourceChangeSyncs }}
3536
- --log_file_max_size={{ .Values.logFileMaxSize }}
3637
- --max-fleet-size={{ .Values.MaxFleetSizeSupported }}
3738
- --hub-api-qps={{ .Values.hubAPIQPS }}
3839
- --hub-api-burst={{ .Values.hubAPIBurst }}
3940
- --force-delete-wait-time={{ .Values.forceDeleteWaitTime }}
41+
- --cluster-unhealthy-threshold={{ .Values.clusterUnhealthyThreshold }}
4042
ports:
4143
- name: metrics
4244
containerPort: 8080

charts/hub-agent/values.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ webhookServiceName: fleetwebhook
1717
enableGuardRail: true
1818
webhookClientConnectionType: service
1919
forceDeleteWaitTime: 15m0s
20-
20+
clusterUnhealthyThreshold: 3m0s
2121
namespace:
2222
fleet-system
2323

@@ -35,10 +35,11 @@ affinity: {}
3535

3636
enableV1Alpha1APIs: false
3737
enableV1Beta1APIs: true
38+
enableClusterInventoryAPI: true
3839

3940
hubAPIQPS: 250
4041
hubAPIBurst: 1000
4142
MaxConcurrentClusterPlacement: 100
4243
ConcurrentResourceChangeSyncs: 20
43-
logFileMaxSize: 1000000
44+
logFileMaxSize: 10000000
4445
MaxFleetSizeSupported: 100

cmd/hubagent/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
1818
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
1919
"k8s.io/klog/v2"
20+
clusterinventory "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1"
2021
ctrl "sigs.k8s.io/controller-runtime"
2122
"sigs.k8s.io/controller-runtime/pkg/cache"
2223
"sigs.k8s.io/controller-runtime/pkg/healthz"
@@ -67,6 +68,7 @@ func init() {
6768
utilruntime.Must(apiextensionsv1.AddToScheme(scheme))
6869
utilruntime.Must(fleetnetworkingv1alpha1.AddToScheme(scheme))
6970
utilruntime.Must(placementv1alpha1.AddToScheme(scheme))
71+
utilruntime.Must(clusterinventory.AddToScheme(scheme))
7072
// +kubebuilder:scaffold:scheme
7173
klog.InitFlags(nil)
7274

cmd/hubagent/options/options.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ type Options struct {
7979
EnableV1Alpha1APIs bool
8080
// EnableV1Beta1APIs enables the agents to watch the v1beta1 CRs.
8181
EnableV1Beta1APIs bool
82+
// EnableClusterInventoryAPIs enables the agents to watch the cluster inventory CRs.
83+
EnableClusterInventoryAPIs bool
8284
// ForceDeleteWaitTime is the duration the hub agent waits before force deleting a member cluster.
8385
ForceDeleteWaitTime metav1.Duration
8486
}
@@ -96,6 +98,7 @@ func NewOptions() *Options {
9698
ConcurrentResourceChangeSyncs: 1,
9799
MaxFleetSizeSupported: 100,
98100
EnableV1Alpha1APIs: false,
101+
EnableClusterInventoryAPIs: false,
99102
}
100103
}
101104

@@ -135,6 +138,7 @@ func (o *Options) AddFlags(flags *flag.FlagSet) {
135138
flags.IntVar(&o.MaxFleetSizeSupported, "max-fleet-size", 100, "The max number of member clusters supported in this fleet")
136139
flags.BoolVar(&o.EnableV1Alpha1APIs, "enable-v1alpha1-apis", false, "If set, the agents will watch for the v1alpha1 APIs.")
137140
flags.BoolVar(&o.EnableV1Beta1APIs, "enable-v1beta1-apis", true, "If set, the agents will watch for the v1beta1 APIs.")
141+
flags.BoolVar(&o.EnableClusterInventoryAPIs, "enable-cluster-inventory-apis", false, "If set, the agents will watch for the ClusterInventory APIs.")
138142
flags.DurationVar(&o.ForceDeleteWaitTime.Duration, "force-delete-wait-time", 15*time.Minute, "The duration the hub agent waits before force deleting a member cluster.")
139143

140144
o.RateLimiterOpts.AddFlags(flags)

cmd/hubagent/options/validation_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func newTestOptions(modifyOptions ModifyOptions) Options {
2222
option := Options{
2323
SkippedPropagatingAPIs: "fleet.azure.com;multicluster.x-k8s.io",
2424
WorkPendingGracePeriod: metav1.Duration{Duration: 10 * time.Second},
25-
ClusterUnhealthyThreshold: metav1.Duration{Duration: 1 * time.Second},
25+
ClusterUnhealthyThreshold: metav1.Duration{Duration: 60 * time.Second},
2626
WebhookClientConnectionType: "url",
2727
EnableV1Alpha1APIs: true,
2828
}

cmd/hubagent/workload/setup.go

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"k8s.io/client-go/dynamic"
1717
"k8s.io/client-go/rest"
1818
"k8s.io/klog/v2"
19+
clusterinventory "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1"
1920
ctrl "sigs.k8s.io/controller-runtime"
2021
workv1alpha1 "sigs.k8s.io/work-api/pkg/apis/v1alpha1"
2122

@@ -24,6 +25,7 @@ import (
2425
placementv1beta1 "go.goms.io/fleet/apis/placement/v1beta1"
2526
fleetv1alpha1 "go.goms.io/fleet/apis/v1alpha1"
2627
"go.goms.io/fleet/cmd/hubagent/options"
28+
"go.goms.io/fleet/pkg/controllers/clusterinventory/clusterprofile"
2729
"go.goms.io/fleet/pkg/controllers/clusterresourcebindingwatcher"
2830
"go.goms.io/fleet/pkg/controllers/clusterresourceplacement"
2931
"go.goms.io/fleet/pkg/controllers/clusterresourceplacementwatcher"
@@ -81,6 +83,10 @@ var (
8183
placementv1alpha1.GroupVersion.WithKind(placementv1alpha1.ResourceOverrideKind),
8284
placementv1alpha1.GroupVersion.WithKind(placementv1alpha1.ResourceOverrideSnapshotKind),
8385
}
86+
87+
clusterInventoryGVKs = []schema.GroupVersionKind{
88+
clusterinventory.GroupVersion.WithKind("ClusterProfile"),
89+
}
8490
)
8591

8692
// SetupControllers set up the customized controllers we developed
@@ -92,33 +98,14 @@ func SetupControllers(ctx context.Context, wg *sync.WaitGroup, mgr ctrl.Manager,
9298
}
9399

94100
discoverClient := discovery.NewDiscoveryClientForConfigOrDie(config)
95-
// Verify CRD installation status.
96-
if opts.EnableV1Alpha1APIs {
97-
for _, gvk := range v1Alpha1RequiredGVKs {
98-
if err = utils.CheckCRDInstalled(discoverClient, gvk); err != nil {
99-
klog.ErrorS(err, "unable to find the required CRD", "GVK", gvk)
100-
return err
101-
}
102-
}
103-
}
104-
105-
if opts.EnableV1Beta1APIs {
106-
for _, gvk := range v1Beta1RequiredGVKs {
107-
if err = utils.CheckCRDInstalled(discoverClient, gvk); err != nil {
108-
klog.ErrorS(err, "unable to find the required CRD", "GVK", gvk)
109-
return err
110-
}
111-
}
112-
}
113-
114101
// AllowedPropagatingAPIs and SkippedPropagatingAPIs are mutually exclusive.
115102
// If none of them are set, the resourceConfig by default stores a list of skipped propagation APIs.
116103
resourceConfig := utils.NewResourceConfig(opts.AllowedPropagatingAPIs != "")
117-
if err := resourceConfig.Parse(opts.AllowedPropagatingAPIs); err != nil {
104+
if err = resourceConfig.Parse(opts.AllowedPropagatingAPIs); err != nil {
118105
// The program will never go here because the parameters have been checked.
119106
return err
120107
}
121-
if err := resourceConfig.Parse(opts.SkippedPropagatingAPIs); err != nil {
108+
if err = resourceConfig.Parse(opts.SkippedPropagatingAPIs); err != nil {
122109
// The program will never go here because the parameters have been checked
123110
return err
124111
}
@@ -154,32 +141,16 @@ func SetupControllers(ctx context.Context, wg *sync.WaitGroup, mgr ctrl.Manager,
154141
rateLimiter := options.DefaultControllerRateLimiter(opts.RateLimiterOpts)
155142
var clusterResourcePlacementControllerV1Alpha1 controller.Controller
156143
var clusterResourcePlacementControllerV1Beta1 controller.Controller
157-
144+
var memberClusterPlacementController controller.Controller
158145
if opts.EnableV1Alpha1APIs {
146+
for _, gvk := range v1Alpha1RequiredGVKs {
147+
if err = utils.CheckCRDInstalled(discoverClient, gvk); err != nil {
148+
klog.ErrorS(err, "unable to find the required CRD", "GVK", gvk)
149+
return err
150+
}
151+
}
159152
klog.Info("Setting up clusterResourcePlacement v1alpha1 controller")
160153
clusterResourcePlacementControllerV1Alpha1 = controller.NewController(crpControllerV1Alpha1Name, controller.NamespaceKeyFunc, crpc.ReconcileV1Alpha1, rateLimiter)
161-
}
162-
163-
if opts.EnableV1Beta1APIs {
164-
klog.Info("Setting up clusterResourcePlacement v1beta1 controller")
165-
clusterResourcePlacementControllerV1Beta1 = controller.NewController(crpControllerV1Beta1Name, controller.NamespaceKeyFunc, crpc.Reconcile, rateLimiter)
166-
}
167-
168-
// Set up a new controller to reconcile any resources in the cluster
169-
klog.Info("Setting up resource change controller")
170-
rcr := &resourcechange.Reconciler{
171-
DynamicClient: dynamicClient,
172-
Recorder: mgr.GetEventRecorderFor(resourceChangeControllerName),
173-
RestMapper: mgr.GetRESTMapper(),
174-
InformerManager: dynamicInformerManager,
175-
PlacementControllerV1Alpha1: clusterResourcePlacementControllerV1Alpha1,
176-
PlacementControllerV1Beta1: clusterResourcePlacementControllerV1Beta1,
177-
}
178-
179-
resourceChangeController := controller.NewController(resourceChangeControllerName, controller.ClusterWideKeyFunc, rcr.Reconcile, rateLimiter)
180-
181-
var memberClusterPlacementController controller.Controller
182-
if opts.EnableV1Alpha1APIs {
183154
klog.Info("Setting up member cluster change controller")
184155
mcp := &memberclusterplacement.Reconciler{
185156
InformerManager: dynamicInformerManager,
@@ -189,6 +160,14 @@ func SetupControllers(ctx context.Context, wg *sync.WaitGroup, mgr ctrl.Manager,
189160
}
190161

191162
if opts.EnableV1Beta1APIs {
163+
for _, gvk := range v1Beta1RequiredGVKs {
164+
if err = utils.CheckCRDInstalled(discoverClient, gvk); err != nil {
165+
klog.ErrorS(err, "unable to find the required CRD", "GVK", gvk)
166+
return err
167+
}
168+
}
169+
klog.Info("Setting up clusterResourcePlacement v1beta1 controller")
170+
clusterResourcePlacementControllerV1Beta1 = controller.NewController(crpControllerV1Beta1Name, controller.NamespaceKeyFunc, crpc.Reconcile, rateLimiter)
192171
klog.Info("Setting up clusterResourcePlacement watcher")
193172
if err := (&clusterresourceplacementwatcher.Reconciler{
194173
PlacementController: clusterResourcePlacementControllerV1Beta1,
@@ -318,7 +297,38 @@ func SetupControllers(ctx context.Context, wg *sync.WaitGroup, mgr ctrl.Manager,
318297
klog.ErrorS(err, "Unable to set up resourceOverride controller")
319298
return err
320299
}
300+
301+
// Verify cluster inventory CRD installation status.
302+
if opts.EnableClusterInventoryAPIs {
303+
for _, gvk := range clusterInventoryGVKs {
304+
if err = utils.CheckCRDInstalled(discoverClient, gvk); err != nil {
305+
klog.ErrorS(err, "unable to find the required CRD", "GVK", gvk)
306+
return err
307+
}
308+
}
309+
klog.Info("Setting up cluster profile controller")
310+
if err = (&clusterprofile.Reconciler{
311+
Client: mgr.GetClient(),
312+
ClusterProfileNamespace: utils.FleetSystemNamespace,
313+
ClusterUnhealthyThreshold: opts.ClusterUnhealthyThreshold.Duration,
314+
}).SetupWithManager(mgr); err != nil {
315+
klog.ErrorS(err, "unable to set up ClusterProfile controller")
316+
return err
317+
}
318+
}
319+
}
320+
321+
// Set up a new controller to reconcile any resources in the cluster
322+
klog.Info("Setting up resource change controller")
323+
rcr := &resourcechange.Reconciler{
324+
DynamicClient: dynamicClient,
325+
Recorder: mgr.GetEventRecorderFor(resourceChangeControllerName),
326+
RestMapper: mgr.GetRESTMapper(),
327+
InformerManager: dynamicInformerManager,
328+
PlacementControllerV1Alpha1: clusterResourcePlacementControllerV1Alpha1,
329+
PlacementControllerV1Beta1: clusterResourcePlacementControllerV1Beta1,
321330
}
331+
resourceChangeController := controller.NewController(resourceChangeControllerName, controller.ClusterWideKeyFunc, rcr.Reconcile, rateLimiter)
322332

323333
// Set up a runner that starts all the custom controllers we created above
324334
resourceChangeDetector := &resourcewatcher.ChangeDetector{

0 commit comments

Comments
 (0)