Skip to content

Commit

Permalink
Expose hosted info to be customized
Browse files Browse the repository at this point in the history
Signed-off-by: Jian Qiu <[email protected]>
  • Loading branch information
qiujian16 committed Mar 27, 2024
1 parent b0ef02a commit 5930571
Show file tree
Hide file tree
Showing 14 changed files with 224 additions and 133 deletions.
10 changes: 10 additions & 0 deletions pkg/addonfactory/addonfactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/klog/v2"
"open-cluster-management.io/addon-framework/pkg/addonmanager/constants"
addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
clusterclientset "open-cluster-management.io/api/client/cluster/clientset/versioned"
clusterv1 "open-cluster-management.io/api/cluster/v1"
Expand Down Expand Up @@ -59,6 +60,8 @@ func NewAgentAddonFactory(addonName string, fs embed.FS, dir string) *AgentAddon
Registration: nil,
HealthProber: nil,
SupportedConfigGVRs: []schema.GroupVersionResource{},
// Set a default hosted mode info func.
HostedModeInfoFunc: constants.GetHostedModeInfo,
},
trimCRDDescription: false,
scheme: s,
Expand Down Expand Up @@ -100,6 +103,13 @@ func (f *AgentAddonFactory) WithAgentHostedModeEnabledOption() *AgentAddonFactor
return f
}

// WithAgentHostedInfoFn sets the function to get the hosting cluster of an addon in the hosted mode.
func (f *AgentAddonFactory) WithAgentHostedInfoFn(
infoFn func(*addonapiv1alpha1.ManagedClusterAddOn, *clusterv1.ManagedCluster) (string, string)) *AgentAddonFactory {
f.agentAddonOptions.HostedModeInfoFunc = infoFn
return f
}

// WithTrimCRDDescription is to enable trim the description of CRDs in manifestWork.
func (f *AgentAddonFactory) WithTrimCRDDescription() *AgentAddonFactory {
f.trimCRDDescription = true
Expand Down
5 changes: 2 additions & 3 deletions pkg/addonfactory/helm_agentaddon.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
clusterclientset "open-cluster-management.io/api/client/cluster/clientset/versioned"
clusterv1 "open-cluster-management.io/api/cluster/v1"

"open-cluster-management.io/addon-framework/pkg/addonmanager/constants"
"open-cluster-management.io/addon-framework/pkg/agent"
)

Expand Down Expand Up @@ -237,7 +236,7 @@ func (a *HelmAgentAddon) getBuiltinValues(

builtinValues.AddonInstallNamespace = a.getValueAgentInstallNamespace(addon)

builtinValues.InstallMode, _ = constants.GetHostedModeInfo(addon.GetAnnotations())
builtinValues.InstallMode, _ = a.agentAddonOptions.HostedModeInfoFunc(addon, cluster)

helmBuiltinValues, err := JsonStructToValues(builtinValues)
if err != nil {
Expand Down Expand Up @@ -268,7 +267,7 @@ func (a *HelmAgentAddon) getDefaultValues(
if a.hostingCluster != nil {
defaultValues.HostingClusterCapabilities = *a.capabilities(a.hostingCluster, addon)
} else if a.clusterClient != nil {
hostingClusterName := addon.GetAnnotations()[addonapiv1alpha1.HostingClusterNameAnnotationKey]
_, hostingClusterName := a.agentAddonOptions.HostedModeInfoFunc(addon, cluster)
if len(hostingClusterName) > 0 {
hostingCluster, err := a.clusterClient.ClusterV1().ManagedClusters().
Get(context.TODO(), hostingClusterName, metav1.GetOptions{})
Expand Down
3 changes: 1 addition & 2 deletions pkg/addonfactory/template_agentaddon.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
clusterv1 "open-cluster-management.io/api/cluster/v1"

"open-cluster-management.io/addon-framework/pkg/addonmanager/constants"
"open-cluster-management.io/addon-framework/pkg/agent"
"open-cluster-management.io/addon-framework/pkg/assets"
)
Expand Down Expand Up @@ -133,7 +132,7 @@ func (a *TemplateAgentAddon) getBuiltinValues(
}
builtinValues.AddonInstallNamespace = installNamespace

builtinValues.InstallMode, _ = constants.GetHostedModeInfo(addon.GetAnnotations())
builtinValues.InstallMode, _ = a.agentAddonOptions.HostedModeInfoFunc(addon, cluster)

return StructToValues(builtinValues)
}
Expand Down
8 changes: 6 additions & 2 deletions pkg/addonmanager/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
clusterv1 "open-cluster-management.io/api/cluster/v1"
)

const (
Expand Down Expand Up @@ -35,8 +36,11 @@ func PreDeleteHookHostingWorkName(addonNamespace, addonName string) string {
}

// GetHostedModeInfo returns addon installation mode and hosting cluster name.
func GetHostedModeInfo(annotations map[string]string) (string, string) {
hostingClusterName, ok := annotations[addonv1alpha1.HostingClusterNameAnnotationKey]
func GetHostedModeInfo(addon *addonv1alpha1.ManagedClusterAddOn, _ *clusterv1.ManagedCluster) (string, string) {
if len(addon.Annotations) == 0 {
return InstallModeDefault, ""
}
hostingClusterName, ok := addon.Annotations[addonv1alpha1.HostingClusterNameAnnotationKey]
if !ok {
return InstallModeDefault, ""
}
Expand Down
204 changes: 111 additions & 93 deletions pkg/addonmanager/controllers/agentdeploy/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,25 +252,37 @@ func (c *addonDeployController) sync(ctx context.Context, syncCtx factory.SyncCo

syncers := []addonDeploySyncer{
&defaultSyncer{
buildWorks: c.buildDeployManifestWorks,
buildWorks: c.buildDeployManifestWorksFunc(
newAddonWorksBuilder(agentAddon.GetAgentAddonOptions().HostedModeEnabled, c.workBuilder),
addonapiv1alpha1.ManagedClusterAddOnManifestApplied,
),
applyWork: c.applyWork,
getWorkByAddon: c.getWorksByAddonFn(index.ManifestWorkByAddon),
deleteWork: c.workApplier.Delete,
agentAddon: agentAddon,
},
&hostedSyncer{
buildWorks: c.buildDeployManifestWorks,
buildWorks: c.buildDeployManifestWorksFunc(
newHostingAddonWorksBuilder(agentAddon.GetAgentAddonOptions().HostedModeEnabled, c.workBuilder),
addonapiv1alpha1.ManagedClusterAddOnHostingManifestApplied,
),
applyWork: c.applyWork,
deleteWork: c.workApplier.Delete,
getCluster: c.managedClusterLister.Get,
getWorkByAddon: c.getWorksByAddonFn(index.ManifestWorkByHostedAddon),
agentAddon: agentAddon},
&defaultHookSyncer{
buildWorks: c.buildHookManifestWork,
buildWorks: c.buildHookManifestWorkFunc(
newAddonWorksBuilder(agentAddon.GetAgentAddonOptions().HostedModeEnabled, c.workBuilder),
addonapiv1alpha1.ManagedClusterAddOnManifestApplied,
),
applyWork: c.applyWork,
agentAddon: agentAddon},
&hostedHookSyncer{
buildWorks: c.buildHookManifestWork,
buildWorks: c.buildHookManifestWorkFunc(
newHostingAddonWorksBuilder(agentAddon.GetAgentAddonOptions().HostedModeEnabled, c.workBuilder),
addonapiv1alpha1.ManagedClusterAddOnHostingManifestApplied,
),
applyWork: c.applyWork,
deleteWork: c.workApplier.Delete,
getCluster: c.managedClusterLister.Get,
Expand Down Expand Up @@ -354,103 +366,109 @@ func (c *addonDeployController) applyWork(ctx context.Context, appliedType strin
return work, nil
}

func (c *addonDeployController) buildDeployManifestWorks(installMode, workNamespace string,
type buildDeployWorkFunc func(
workNamespace string,
cluster *clusterv1.ManagedCluster, existingWorks []*workapiv1.ManifestWork,
addon *addonapiv1alpha1.ManagedClusterAddOn) (appliedWorks, deleteWorks []*workapiv1.ManifestWork, err error) {
var appliedType string
var addonWorkBuilder *addonWorksBuilder

agentAddon := c.agentAddons[addon.Name]
if agentAddon == nil {
return nil, nil, fmt.Errorf("failed to get agentAddon")
}
addon *addonapiv1alpha1.ManagedClusterAddOn) (appliedWorks, deleteWorks []*workapiv1.ManifestWork, err error)

func (c *addonDeployController) buildDeployManifestWorksFunc(addonWorkBuilder *addonWorksBuilder, appliedType string) buildDeployWorkFunc {
return func(
workNamespace string,
cluster *clusterv1.ManagedCluster, existingWorks []*workapiv1.ManifestWork,
addon *addonapiv1alpha1.ManagedClusterAddOn) (appliedWorks, deleteWorks []*workapiv1.ManifestWork, err error) {
agentAddon := c.agentAddons[addon.Name]
if agentAddon == nil {
return nil, nil, fmt.Errorf("failed to get agentAddon")
}

switch installMode {
case constants.InstallModeHosted:
appliedType = addonapiv1alpha1.ManagedClusterAddOnHostingManifestApplied
addonWorkBuilder = newHostingAddonWorksBuilder(agentAddon.GetAgentAddonOptions().HostedModeEnabled, c.workBuilder)
case constants.InstallModeDefault:
appliedType = addonapiv1alpha1.ManagedClusterAddOnManifestApplied
addonWorkBuilder = newAddonWorksBuilder(agentAddon.GetAgentAddonOptions().HostedModeEnabled, c.workBuilder)
default:
return nil, nil, fmt.Errorf("invalid install mode %v", installMode)
}
objects, err := agentAddon.Manifests(cluster, addon)
if err != nil {
meta.SetStatusCondition(&addon.Status.Conditions, metav1.Condition{
Type: appliedType,
Status: metav1.ConditionFalse,
Reason: addonapiv1alpha1.AddonManifestAppliedReasonWorkApplyFailed,
Message: fmt.Sprintf("failed to get manifest from agent interface: %v", err),
})
return nil, nil, err
}
if len(objects) == 0 {
return nil, nil, nil
}

objects, err := agentAddon.Manifests(cluster, addon)
if err != nil {
meta.SetStatusCondition(&addon.Status.Conditions, metav1.Condition{
Type: appliedType,
Status: metav1.ConditionFalse,
Reason: addonapiv1alpha1.AddonManifestAppliedReasonWorkApplyFailed,
Message: fmt.Sprintf("failed to get manifest from agent interface: %v", err),
})
return nil, nil, err
}
if len(objects) == 0 {
return nil, nil, nil
}
// this is to retrieve the intended mode of the addon.
var mode string
if agentAddon.GetAgentAddonOptions().HostedModeInfoFunc == nil {
mode = constants.InstallModeDefault
} else {
mode, _ = agentAddon.GetAgentAddonOptions().HostedModeInfoFunc(addon, cluster)
}

manifestOptions := getManifestConfigOption(agentAddon, cluster, addon)
existingWorksCopy := []workapiv1.ManifestWork{}
for _, work := range existingWorks {
existingWorksCopy = append(existingWorksCopy, *work)
}
appliedWorks, deleteWorks, err = addonWorkBuilder.BuildDeployWorks(workNamespace, addon, existingWorksCopy, objects, manifestOptions)
if err != nil {
meta.SetStatusCondition(&addon.Status.Conditions, metav1.Condition{
Type: appliedType,
Status: metav1.ConditionFalse,
Reason: addonapiv1alpha1.AddonManifestAppliedReasonWorkApplyFailed,
Message: fmt.Sprintf("failed to build manifestwork: %v", err),
})
return nil, nil, err
manifestOptions := getManifestConfigOption(agentAddon, cluster, addon)
existingWorksCopy := []workapiv1.ManifestWork{}
for _, work := range existingWorks {
existingWorksCopy = append(existingWorksCopy, *work)
}
appliedWorks, deleteWorks, err = addonWorkBuilder.BuildDeployWorks(
mode, workNamespace, addon, existingWorksCopy, objects, manifestOptions)
if err != nil {
meta.SetStatusCondition(&addon.Status.Conditions, metav1.Condition{
Type: appliedType,
Status: metav1.ConditionFalse,
Reason: addonapiv1alpha1.AddonManifestAppliedReasonWorkApplyFailed,
Message: fmt.Sprintf("failed to build manifestwork: %v", err),
})
return nil, nil, err
}
return appliedWorks, deleteWorks, nil
}
return appliedWorks, deleteWorks, nil
}
func (c *addonDeployController) buildHookManifestWork(installMode, workNamespace string,
cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn) (*workapiv1.ManifestWork, error) {
var appliedType string
var addonWorkBuilder *addonWorksBuilder

agentAddon := c.agentAddons[addon.Name]
if agentAddon == nil {
return nil, fmt.Errorf("failed to get agentAddon")
}

switch installMode {
case constants.InstallModeHosted:
appliedType = addonapiv1alpha1.ManagedClusterAddOnHostingManifestApplied
addonWorkBuilder = newHostingAddonWorksBuilder(agentAddon.GetAgentAddonOptions().HostedModeEnabled, c.workBuilder)
case constants.InstallModeDefault:
appliedType = addonapiv1alpha1.ManagedClusterAddOnManifestApplied
addonWorkBuilder = newAddonWorksBuilder(agentAddon.GetAgentAddonOptions().HostedModeEnabled, c.workBuilder)
default:
return nil, fmt.Errorf("invalid install mode %v", installMode)
}
type buildDeployHookFunc func(
workNamespace string,
cluster *clusterv1.ManagedCluster,
addon *addonapiv1alpha1.ManagedClusterAddOn) (*workapiv1.ManifestWork, error)

objects, err := agentAddon.Manifests(cluster, addon)
if err != nil {
meta.SetStatusCondition(&addon.Status.Conditions, metav1.Condition{
Type: appliedType,
Status: metav1.ConditionFalse,
Reason: addonapiv1alpha1.AddonManifestAppliedReasonWorkApplyFailed,
Message: fmt.Sprintf("failed to get manifest from agent interface: %v", err),
})
return nil, err
}
if len(objects) == 0 {
return nil, nil
}
func (c *addonDeployController) buildHookManifestWorkFunc(addonWorkBuilder *addonWorksBuilder, appliedType string) buildDeployHookFunc {
return func(
workNamespace string,
cluster *clusterv1.ManagedCluster,
addon *addonapiv1alpha1.ManagedClusterAddOn) (*workapiv1.ManifestWork, error) {
agentAddon := c.agentAddons[addon.Name]
if agentAddon == nil {
return nil, fmt.Errorf("failed to get agentAddon")
}

hookWork, err := addonWorkBuilder.BuildHookWork(workNamespace, addon, objects)
if err != nil {
meta.SetStatusCondition(&addon.Status.Conditions, metav1.Condition{
Type: appliedType,
Status: metav1.ConditionFalse,
Reason: addonapiv1alpha1.AddonManifestAppliedReasonWorkApplyFailed,
Message: fmt.Sprintf("failed to build manifestwork: %v", err),
})
return nil, err
objects, err := agentAddon.Manifests(cluster, addon)
if err != nil {
meta.SetStatusCondition(&addon.Status.Conditions, metav1.Condition{
Type: appliedType,
Status: metav1.ConditionFalse,
Reason: addonapiv1alpha1.AddonManifestAppliedReasonWorkApplyFailed,
Message: fmt.Sprintf("failed to get manifest from agent interface: %v", err),
})
return nil, err
}
if len(objects) == 0 {
return nil, nil
}

// this is to retrieve the intended mode of the addon.
var mode string
if agentAddon.GetAgentAddonOptions().HostedModeInfoFunc == nil {
mode = constants.InstallModeDefault
} else {
mode, _ = agentAddon.GetAgentAddonOptions().HostedModeInfoFunc(addon, cluster)
}
hookWork, err := addonWorkBuilder.BuildHookWork(mode, workNamespace, addon, objects)
if err != nil {
meta.SetStatusCondition(&addon.Status.Conditions, metav1.Condition{
Type: appliedType,
Status: metav1.ConditionFalse,
Reason: addonapiv1alpha1.AddonManifestAppliedReasonWorkApplyFailed,
Message: fmt.Sprintf("failed to build manifestwork: %v", err),
})
return nil, err
}
return hookWork, nil
}
return hookWork, nil
}
8 changes: 3 additions & 5 deletions pkg/addonmanager/controllers/agentdeploy/default_hook_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ import (
clusterv1 "open-cluster-management.io/api/cluster/v1"
workapiv1 "open-cluster-management.io/api/work/v1"

"open-cluster-management.io/addon-framework/pkg/addonmanager/constants"
"open-cluster-management.io/addon-framework/pkg/agent"
"open-cluster-management.io/addon-framework/pkg/basecontroller/factory"
)

type defaultHookSyncer struct {
buildWorks func(installMode, workNamespace string, cluster *clusterv1.ManagedCluster,
addon *addonapiv1alpha1.ManagedClusterAddOn) (*workapiv1.ManifestWork, error)
applyWork func(ctx context.Context, appliedType string,
buildWorks buildDeployHookFunc
applyWork func(ctx context.Context, appliedType string,
work *workapiv1.ManifestWork, addon *addonapiv1alpha1.ManagedClusterAddOn) (*workapiv1.ManifestWork, error)
agentAddon agent.AgentAddon
}
Expand All @@ -29,7 +27,7 @@ func (s *defaultHookSyncer) sync(ctx context.Context,
addon *addonapiv1alpha1.ManagedClusterAddOn) (*addonapiv1alpha1.ManagedClusterAddOn, error) {
deployWorkNamespace := addon.Namespace

hookWork, err := s.buildWorks(constants.InstallModeDefault, deployWorkNamespace, cluster, addon)
hookWork, err := s.buildWorks(deployWorkNamespace, cluster, addon)
if err != nil {
return addon, err
}
Expand Down
6 changes: 2 additions & 4 deletions pkg/addonmanager/controllers/agentdeploy/default_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@ import (
clusterv1 "open-cluster-management.io/api/cluster/v1"
workapiv1 "open-cluster-management.io/api/work/v1"

"open-cluster-management.io/addon-framework/pkg/addonmanager/constants"
"open-cluster-management.io/addon-framework/pkg/agent"
"open-cluster-management.io/addon-framework/pkg/basecontroller/factory"
)

type defaultSyncer struct {
buildWorks func(installMode, workNamespace string, cluster *clusterv1.ManagedCluster, existingWorks []*workapiv1.ManifestWork,
addon *addonapiv1alpha1.ManagedClusterAddOn) (appliedWorks, deleteWorks []*workapiv1.ManifestWork, err error)
buildWorks buildDeployWorkFunc

applyWork func(ctx context.Context, appliedType string,
work *workapiv1.ManifestWork, addon *addonapiv1alpha1.ManagedClusterAddOn) (*workapiv1.ManifestWork, error)
Expand Down Expand Up @@ -54,7 +52,7 @@ func (s *defaultSyncer) sync(ctx context.Context,
return addon, err
}

deployWorks, deleteWorks, err := s.buildWorks(constants.InstallModeDefault, deployWorkNamespace, cluster, currentWorks, addon)
deployWorks, deleteWorks, err := s.buildWorks(deployWorkNamespace, cluster, currentWorks, addon)
if err != nil {
return addon, err
}
Expand Down
Loading

0 comments on commit 5930571

Please sign in to comment.