Skip to content
Draft
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
72 changes: 59 additions & 13 deletions mgmt-agent/cmd/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"golang.org/x/sync/errgroup"

kubeinformers "k8s.io/client-go/informers"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
Expand All @@ -36,7 +37,11 @@ import (

"github.com/Azure/azure-sdk-for-go/sdk/azidentity"

hypershiftclient "github.com/openshift/hypershift/client/clientset/clientset"
hypershiftinformers "github.com/openshift/hypershift/client/informers/externalversions"

"github.com/Azure/ARO-HCP/mgmt-agent/pkg/controller"
"github.com/Azure/ARO-HCP/mgmt-agent/pkg/controller/ksmhcp"
)

const (
Expand All @@ -48,6 +53,7 @@ type RawControllerOptions struct {
Kubeconfig string
Namespace string
Workers int
KSMImage string
}

func DefaultControllerOptions() *RawControllerOptions {
Expand All @@ -64,6 +70,7 @@ func (o *RawControllerOptions) BindFlags(cmd *cobra.Command) error {
cmd.Flags().StringVar(&o.Kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Optional.")
cmd.Flags().StringVar(&o.Namespace, "namespace", os.Getenv("POD_NAMESPACE"), "The namespace where the mgmt-agent controller is deployed.")
cmd.Flags().IntVar(&o.Workers, "workers", o.Workers, "Number of reconcile workers to run")
cmd.Flags().StringVar(&o.KSMImage, "ksm-image", o.KSMImage, "Container image for kube-state-metrics deployed per HCP namespace")
cmd.Flags().AddGoFlagSet(flag.CommandLine)

return nil
Expand All @@ -78,11 +85,13 @@ type ValidatedControllerOptions struct {
}

type completedControllerOptions struct {
ctrl *controller.SwiftNICController
kubeInformers kubeinformers.SharedInformerFactory
workers int
healthAddress string
leaderElectionCfg *controller.LeaderElectionConfig
ctrl *controller.SwiftNICController
ksmCtrl *ksmhcp.KSMHCPController
kubeInformers kubeinformers.SharedInformerFactory
hypershiftInformers hypershiftinformers.SharedInformerFactory
workers int
healthAddress string
leaderElectionCfg *controller.LeaderElectionConfig
}

type ControllerOptions struct {
Expand Down Expand Up @@ -119,6 +128,11 @@ func (o *ValidatedControllerOptions) Complete(ctx context.Context) (*ControllerO
return nil, fmt.Errorf("failed to create kubernetes clientset: %w", err)
}

dynamicClient, err := dynamic.NewForConfig(kubeConfig)
if err != nil {
return nil, fmt.Errorf("failed to create dynamic client: %w", err)
}

kubeInformers := kubeinformers.NewSharedInformerFactory(kubeClientset, 10*time.Minute)

ctrl, err := controller.NewSwiftNICController(
Expand All @@ -131,6 +145,22 @@ func (o *ValidatedControllerOptions) Complete(ctx context.Context) (*ControllerO
return nil, fmt.Errorf("failed to create controller: %w", err)
}

hsClient, err := hypershiftclient.NewForConfig(kubeConfig)
if err != nil {
return nil, fmt.Errorf("failed to create hypershift clientset: %w", err)
}
hsInformers := hypershiftinformers.NewSharedInformerFactory(hsClient, 10*time.Minute)

ksmCtrl, err := ksmhcp.NewKSMHCPController(
kubeClientset,
dynamicClient,
hsInformers.Hypershift().V1beta1().HostedControlPlanes(),
o.KSMImage,
)
if err != nil {
return nil, fmt.Errorf("failed to create KSM HCP controller: %w", err)
}

leaderElectionCfg := &controller.LeaderElectionConfig{
LockName: LeaderElectionLockName,
LeaseDuration: 15 * time.Second,
Expand All @@ -142,11 +172,13 @@ func (o *ValidatedControllerOptions) Complete(ctx context.Context) (*ControllerO

return &ControllerOptions{
completedControllerOptions: &completedControllerOptions{
ctrl: ctrl,
kubeInformers: kubeInformers,
workers: o.Workers,
healthAddress: o.HealthAddress,
leaderElectionCfg: leaderElectionCfg,
ctrl: ctrl,
ksmCtrl: ksmCtrl,
kubeInformers: kubeInformers,
hypershiftInformers: hsInformers,
workers: o.Workers,
healthAddress: o.HealthAddress,
leaderElectionCfg: leaderElectionCfg,
},
}, nil
}
Expand Down Expand Up @@ -179,6 +211,7 @@ func (o *ControllerOptions) Run(ctx context.Context) error {
logger := klog.FromContext(ctx)

o.kubeInformers.Start(ctx.Done())
o.hypershiftInformers.Start(ctx.Done())
logger.V(6).Info("Informer factories started")

g, ctx := errgroup.WithContext(ctx)
Expand Down Expand Up @@ -207,16 +240,29 @@ func (o *ControllerOptions) Run(ctx context.Context) error {
return nil
})

// controller with leader election
// swift-nic controller with leader election
g.Go(func() error {
logger.Info("Starting swift-nic controller")
if err := controller.RunWithLeaderElection(ctx, "swift-nic", o.leaderElectionCfg, func(leaderCtx context.Context) error {
return o.ctrl.Run(leaderCtx, o.workers)
}); err != nil {
logger.Error(err, "Controller stopped with error")
logger.Error(err, "Swift NIC controller stopped with error")
return err
}
logger.Info("Swift NIC controller stopped")
return nil
})

// ksm-hcp controller with leader election
g.Go(func() error {
logger.Info("Starting KSM HCP controller")
if err := controller.RunWithLeaderElection(ctx, "ksm-hcp", o.leaderElectionCfg, func(leaderCtx context.Context) error {
return o.ksmCtrl.Run(leaderCtx, o.workers)
Comment on lines +256 to +260
}); err != nil {
logger.Error(err, "KSM HCP controller stopped with error")
return err
}
logger.Info("Controller stopped")
logger.Info("KSM HCP controller stopped")
return nil
})

Expand Down
44 changes: 44 additions & 0 deletions mgmt-agent/deploy/templates/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,47 @@ rules:
verbs:
- patch
- update
- apiGroups:
- hypershift.openshift.io
resources:
- hostedcontrolplanes
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- deployments
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- monitoring.coreos.com
resources:
- servicemonitors
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
1 change: 1 addition & 0 deletions mgmt-agent/deploy/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ spec:
args:
- controller
- "--health-address=:{{ .Values.health.port }}"
- "--ksm-image={{ .Values.ksmImage.registry }}/{{ .Values.ksmImage.repository }}@{{ .Values.ksmImage.digest }}"
- "-v={{ .Values.logLevel }}"
image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}@{{ .Values.image.digest }}"
name: mgmt-agent-controller
Expand Down
29 changes: 28 additions & 1 deletion mgmt-agent/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,80 @@ module github.com/Azure/ARO-HCP/mgmt-agent

go 1.25.7

replace (
github.com/aws/karpenter-provider-aws => github.com/aws/karpenter-provider-aws v1.0.0
github.com/openshift/hypershift/api => github.com/openshift/hypershift/api v0.0.0-20260226113135-8ab86680f975
sigs.k8s.io/karpenter => sigs.k8s.io/karpenter v1.0.0
)
Comment on lines +5 to +9

require (
github.com/Azure/ARO-HCP/internal v0.0.0-20260512110147-2543c657a16a
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.3.0
github.com/openshift/hypershift v0.1.70
github.com/openshift/hypershift/api v0.0.0-20260424195428-c1a8bb61ff14
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.85.0
github.com/spf13/cobra v1.10.2
golang.org/x/sync v0.20.0
k8s.io/api v0.35.3
k8s.io/apimachinery v0.35.3
k8s.io/client-go v0.35.3
k8s.io/component-base v0.35.3
k8s.io/klog/v2 v2.140.0
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5
)

require (
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/v3 v3.0.1 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0 // indirect
github.com/aws/aws-sdk-go v1.55.7 // indirect
github.com/aws/karpenter-provider-aws v1.8.6 // indirect
github.com/awslabs/operatorpkg v0.0.0-20250909182303-e8e550b6f339 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/openshift/api v0.0.0-20260304122341-cf5d8996109f // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.1 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/samber/lo v1.51.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/otel v1.43.0 // indirect
go.opentelemetry.io/otel/trace v1.43.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.50.0 // indirect
Expand All @@ -62,13 +85,17 @@ require (
golang.org/x/term v0.42.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.15.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.35.0-alpha.0 // indirect
k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 // indirect
knative.dev/pkg v0.0.0-20231010144348-ca8c009405dd // indirect
sigs.k8s.io/controller-runtime v0.22.4 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/karpenter v1.8.2 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
Expand Down
Loading
Loading