Skip to content

Commit 489ce9c

Browse files
committed
Add OpenStackMachineTemplate controller
Add OSMT controller behind a feature flag with basic skeleton
1 parent 8225d5f commit 489ce9c

File tree

3 files changed

+125
-23
lines changed

3 files changed

+125
-23
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
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+
package controllers
17+
18+
import (
19+
"context"
20+
21+
apierrors "k8s.io/apimachinery/pkg/api/errors"
22+
"k8s.io/client-go/tools/record"
23+
ctrl "sigs.k8s.io/controller-runtime"
24+
"sigs.k8s.io/controller-runtime/pkg/client"
25+
"sigs.k8s.io/controller-runtime/pkg/controller"
26+
27+
"sigs.k8s.io/cluster-api/util/predicates"
28+
29+
infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
30+
"sigs.k8s.io/cluster-api-provider-openstack/pkg/scope"
31+
)
32+
33+
// OpenStackMachineTemplateReconciler reconciles a OpenStackMachineTemplate object.
34+
// it only updates the .status field to allow auto-scaling
35+
type OpenStackMachineTemplateReconciler struct {
36+
Client client.Client
37+
Recorder record.EventRecorder
38+
WatchFilterValue string
39+
ScopeFactory scope.Factory
40+
CaCertificates []byte // PEM encoded ca certificates.
41+
}
42+
43+
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=openstackmachinetemplatess,verbs=get;list;watch;create;
44+
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=openstackmachinetemplatess/status,verbs=get;update;patch
45+
46+
func (r *OpenStackMachineTemplateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, reterr error) {
47+
log := ctrl.LoggerFrom(ctx)
48+
49+
// Fetch the OpenStackMachine instance.
50+
openStackMachineTemplate := &infrav1.OpenStackMachine{}
51+
err := r.Client.Get(ctx, req.NamespacedName, openStackMachineTemplate)
52+
if err != nil {
53+
if apierrors.IsNotFound(err) {
54+
return ctrl.Result{}, nil
55+
}
56+
return ctrl.Result{}, err
57+
}
58+
59+
log = log.WithValues("openStackMachineTemplate", openStackMachineTemplate.Name)
60+
log.V(4).Info("Reconciling openStackMachineTemplate")
61+
62+
return ctrl.Result{}, nil
63+
}
64+
65+
func (r *OpenStackMachineTemplateReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error {
66+
log := ctrl.LoggerFrom(ctx)
67+
68+
return ctrl.NewControllerManagedBy(mgr).
69+
WithOptions(options).
70+
For(&infrav1.OpenStackMachineTemplate{}).
71+
WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(mgr.GetScheme(), log, r.WatchFilterValue)).
72+
// The filter below is required as we only want to reconcile objects created by cluster-api
73+
// and not users'
74+
WithEventFilter(predicates.ResourceIsTopologyOwned(mgr.GetScheme(), log)).
75+
Complete(r)
76+
}

feature/feature.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ const (
3434
//
3535
// alpha: v0.14
3636
PriorityQueue featuregate.Feature = "PriorityQueue"
37+
38+
// AutoScaleFromZero is a feature gate that enables the OpenStackMachineTemplate controller that adds
39+
// information in OpenStackMachineTemplate.status required by the cluster-autoscaler to scale from zero
40+
// without the addition of labels
41+
//
42+
// alpha: v0.14
43+
AutoScaleFromZero featuregate.Feature = "AutoScaleFromZero"
3744
)
3845

3946
func init() {
@@ -44,5 +51,6 @@ func init() {
4451
// To add a new feature, define a key for it above and add it here.
4552
var defaultCAPOFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
4653
// Every feature should be initiated here:
47-
PriorityQueue: {Default: false, PreRelease: featuregate.Alpha},
54+
PriorityQueue: {Default: false, PreRelease: featuregate.Alpha},
55+
AutoScaleFromZero: {Default: false, PreRelease: featuregate.Alpha},
4856
}

main.go

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -77,28 +77,29 @@ var (
7777
setupLog = ctrl.Log.WithName("setup")
7878

7979
// flags.
80-
managerOptions = flags.ManagerOptions{}
81-
enableLeaderElection bool
82-
leaderElectionLeaseDuration time.Duration
83-
leaderElectionRenewDeadline time.Duration
84-
leaderElectionRetryPeriod time.Duration
85-
watchNamespace string
86-
watchFilterValue string
87-
profilerAddress string
88-
openStackClusterConcurrency int
89-
openStackMachineConcurrency int
90-
syncPeriod time.Duration
91-
restConfigQPS float32
92-
restConfigBurst int
93-
webhookPort int
94-
webhookCertDir string
95-
healthAddr string
96-
lbProvider string
97-
caCertsPath string
98-
showVersion bool
99-
scopeCacheMaxSize int
100-
skipCRDMigrationPhases []string
101-
logOptions = logs.NewOptions()
80+
managerOptions = flags.ManagerOptions{}
81+
enableLeaderElection bool
82+
leaderElectionLeaseDuration time.Duration
83+
leaderElectionRenewDeadline time.Duration
84+
leaderElectionRetryPeriod time.Duration
85+
watchNamespace string
86+
watchFilterValue string
87+
profilerAddress string
88+
openStackClusterConcurrency int
89+
openStackMachineConcurrency int
90+
openStackMachineTemplateConcurrency int
91+
syncPeriod time.Duration
92+
restConfigQPS float32
93+
restConfigBurst int
94+
webhookPort int
95+
webhookCertDir string
96+
healthAddr string
97+
lbProvider string
98+
caCertsPath string
99+
showVersion bool
100+
scopeCacheMaxSize int
101+
skipCRDMigrationPhases []string
102+
logOptions = logs.NewOptions()
102103
)
103104

104105
func init() {
@@ -148,6 +149,9 @@ func InitFlags(fs *pflag.FlagSet) {
148149
fs.IntVar(&openStackMachineConcurrency, "openstackmachine-concurrency", 10,
149150
"Number of OpenStackMachines to process simultaneously")
150151

152+
fs.IntVar(&openStackMachineTemplateConcurrency, "openstackmachinetemplate-concurrency", 10,
153+
"Number of OpenStackMachineTemplates to process simultaneously")
154+
151155
fs.DurationVar(&syncPeriod, "sync-period", 10*time.Minute,
152156
"The minimum interval at which watched resources are reconciled (e.g. 15m)")
153157

@@ -395,6 +399,20 @@ func setupReconcilers(ctx context.Context, mgr ctrl.Manager, caCerts []byte) {
395399
setupLog.Error(err, "unable to create controller", "controller", "OpenStackServer")
396400
os.Exit(1)
397401
}
402+
403+
if feature.Gates.Enabled(feature.AutoScaleFromZero) {
404+
if err := (&controllers.OpenStackMachineTemplateReconciler{
405+
Client: mgr.GetClient(),
406+
Recorder: mgr.GetEventRecorderFor("openstackmachinetemplate-controller"),
407+
WatchFilterValue: watchFilterValue,
408+
ScopeFactory: scopeFactory,
409+
CaCertificates: caCerts,
410+
}).SetupWithManager(ctx, mgr, concurrency(openStackMachineTemplateConcurrency)); err != nil {
411+
setupLog.Error(err, "unable to create controller", "controller", "OpenStackMachineTemplate")
412+
os.Exit(1)
413+
}
414+
}
415+
398416
}
399417

400418
func setupWebhooks(mgr ctrl.Manager) {

0 commit comments

Comments
 (0)