Skip to content

Commit

Permalink
✨ Support uninstall built-in addon (#435)
Browse files Browse the repository at this point in the history
* Support uninstall built-in addon

Signed-off-by: Jian Qiu <[email protected]>

* Update deployment file structure

Signed-off-by: Jian Qiu <[email protected]>

---------

Signed-off-by: Jian Qiu <[email protected]>
  • Loading branch information
qiujian16 authored Jun 21, 2024
1 parent 753a33a commit 261c92a
Show file tree
Hide file tree
Showing 11 changed files with 380 additions and 112 deletions.
6 changes: 4 additions & 2 deletions cmd/clusteradm/clusteradm.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ import (
deletecmd "open-cluster-management.io/clusteradm/pkg/cmd/delete"
"open-cluster-management.io/clusteradm/pkg/cmd/get"
inithub "open-cluster-management.io/clusteradm/pkg/cmd/init"
install "open-cluster-management.io/clusteradm/pkg/cmd/install"
"open-cluster-management.io/clusteradm/pkg/cmd/install"
joinhub "open-cluster-management.io/clusteradm/pkg/cmd/join"
"open-cluster-management.io/clusteradm/pkg/cmd/proxy"
unjoin "open-cluster-management.io/clusteradm/pkg/cmd/unjoin"
"open-cluster-management.io/clusteradm/pkg/cmd/uninstall"
"open-cluster-management.io/clusteradm/pkg/cmd/unjoin"
"open-cluster-management.io/clusteradm/pkg/cmd/upgrade"
"open-cluster-management.io/clusteradm/pkg/cmd/version"
)
Expand Down Expand Up @@ -96,6 +97,7 @@ func main() {
deletecmd.NewCmd(clusteradmFlags, streams),
get.NewCmd(clusteradmFlags, streams),
install.NewCmd(clusteradmFlags, streams),
uninstall.NewCmd(clusteradmFlags, streams),
upgrade.NewCmd(clusteradmFlags, streams),
version.NewCmd(clusteradmFlags, streams),
},
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/install/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
)

// NewCmd provides a cobra command wrapping NewCmdImportCluster
// NewCmd provides a cobra command wrapping addon install cmd
func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, streams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{
Use: "install",
Expand Down
114 changes: 22 additions & 92 deletions pkg/cmd/install/hubaddon/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ import (
"open-cluster-management.io/clusteradm/pkg/version"
)

const (
appMgrAddonName = "application-manager"
policyFrameworkAddonName = "governance-policy-framework"
)

func (o *Options) complete(cmd *cobra.Command, args []string) (err error) {
klog.V(1).InfoS("addon options:", "dry-run", o.ClusteradmFlags.DryRun, "names", o.names, "output-file", o.outputFile)
return nil
Expand All @@ -37,12 +32,7 @@ func (o *Options) validate() (err error) {

names := strings.Split(o.names, ",")
for _, n := range names {
switch n {
case appMgrAddonName:
continue
case policyFrameworkAddonName:
continue
default:
if _, ok := scenario.AddonDeploymentFiles[n]; !ok {
return fmt.Errorf("invalid add-on name %s", n)
}
}
Expand All @@ -67,9 +57,9 @@ func (o *Options) run() error {
addons = append(addons, strings.TrimSpace(n))
}
}
o.values.hubAddons = addons
o.values.HubAddons = addons

klog.V(3).InfoS("values:", "addon", o.values.hubAddons)
klog.V(3).InfoS("values:", "addon", o.values.HubAddons)

return o.runWithClient()
}
Expand All @@ -78,86 +68,26 @@ func (o *Options) runWithClient() error {

r := reader.NewResourceReader(o.ClusteradmFlags.KubectlFactory, o.ClusteradmFlags.DryRun, o.Streams)

for _, addon := range o.values.hubAddons {
switch addon {
// Install the Application Management Addon
case appMgrAddonName:
files := []string{
"addon/appmgr/clustermanagementaddon_appmgr.yaml",
"addon/appmgr/clusterrole_agent.yaml",
"addon/appmgr/clusterrole_binding.yaml",
"addon/appmgr/clusterrole.yaml",
"addon/appmgr/crd_channel.yaml",
"addon/appmgr/crd_helmrelease.yaml",
"addon/appmgr/crd_placementrule.yaml",
"addon/appmgr/crd_subscription.yaml",
"addon/appmgr/crd_subscriptionstatuses.yaml",
"addon/appmgr/crd_report.yaml",
"addon/appmgr/crd_clusterreport.yaml",
"addon/appmgr/service_account.yaml",
"addon/appmgr/service_metrics.yaml",
"addon/appmgr/service_operator.yaml",
"addon/appmgr/mutatingwebhookconfiguration.yaml",
}

err := r.Apply(scenario.Files, o.values, files...)
if err != nil {
return err
}

deployments := []string{
"addon/appmgr/deployment_channel.yaml",
"addon/appmgr/deployment_subscription.yaml",
"addon/appmgr/deployment_placementrule.yaml",
"addon/appmgr/deployment_appsubsummary.yaml",
}
err = r.Apply(scenario.Files, o.values, deployments...)
if err != nil {
return err
}

fmt.Fprintf(o.Streams.Out, "Installing built-in %s add-on to the Hub cluster...\n", appMgrAddonName)

// Install the Policy Framework Addon
case policyFrameworkAddonName:
files := []string{
"addon/policy/addon-controller_clusterrole.yaml",
"addon/policy/addon-controller_clusterrolebinding.yaml",
"addon/policy/addon-controller_role.yaml",
"addon/policy/addon-controller_rolebinding.yaml",
"addon/policy/addon-controller_serviceaccount.yaml",
"addon/policy/policy.open-cluster-management.io_placementbindings.yaml",
"addon/policy/policy.open-cluster-management.io_policies.yaml",
"addon/policy/policy.open-cluster-management.io_policyautomations.yaml",
"addon/policy/policy.open-cluster-management.io_policysets.yaml",
"addon/policy/propagator_clusterrole.yaml",
"addon/policy/propagator_clusterrolebinding.yaml",
"addon/policy/propagator_role.yaml",
"addon/policy/propagator_rolebinding.yaml",
"addon/policy/propagator_service.yaml",
"addon/policy/propagator_serviceaccount.yaml",
"addon/policy/clustermanagementaddon_configpolicy.yaml",
"addon/policy/clustermanagementaddon_policyframework.yaml",
"addon/appmgr/crd_placementrule.yaml",
}

err := r.Apply(scenario.Files, o.values, files...)
if err != nil {
return fmt.Errorf("Error deploying framework deployment dependencies: %w", err)
}

deployments := []string{
"addon/policy/addon-controller_deployment.yaml",
"addon/policy/propagator_deployment.yaml",
}

err = r.Apply(scenario.Files, o.values, deployments...)
if err != nil {
return fmt.Errorf("Error deploying framework deployments: %w", err)
}

fmt.Fprintf(o.Streams.Out, "Installing built-in %s add-on to the Hub cluster...\n", policyFrameworkAddonName)
for _, addon := range o.values.HubAddons {
files, ok := scenario.AddonDeploymentFiles[addon]
if !ok {
continue
}
err := r.Apply(scenario.Files, o.values, files.CRDFiles...)
if err != nil {
return fmt.Errorf("Error deploying %s CRDs: %w", addon, err)
}
err = r.Apply(scenario.Files, o.values, files.ConfigFiles...)
if err != nil {
return fmt.Errorf("Error deploying %s dependencies: %w", addon, err)
}
err = r.Apply(scenario.Files, o.values, files.DeploymentFiles...)
if err != nil {
return fmt.Errorf("Error deploying %s deployments: %w", addon, err)
}

fmt.Fprintf(o.Streams.Out, "Installing built-in %s add-on to the Hub cluster...\n", addon)

}

if len(o.outputFile) > 0 {
Expand Down
13 changes: 7 additions & 6 deletions pkg/cmd/install/hubaddon/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
"open-cluster-management.io/clusteradm/pkg/cmd/install/hubaddon/scenario"
"open-cluster-management.io/clusteradm/pkg/version"
)

Expand Down Expand Up @@ -76,8 +77,8 @@ var _ = ginkgo.Describe("install hub-addon", func() {
ginkgo.It("Should not create any built-in add-on deployment(s) because it's not a valid add-on name", func() {
o := Options{
ClusteradmFlags: clusteradmFlags,
values: Values{
hubAddons: []string{invalidAddon},
values: scenario.Values{
HubAddons: []string{invalidAddon},
},
}

Expand All @@ -98,9 +99,9 @@ var _ = ginkgo.Describe("install hub-addon", func() {
o := Options{
ClusteradmFlags: clusteradmFlags,
bundleVersion: ocmVersion,
values: Values{
values: scenario.Values{
Namespace: invalidNamespace,
hubAddons: []string{appMgrAddonName},
HubAddons: []string{scenario.AppMgrAddonName},
},
Streams: genericclioptions.IOStreams{Out: os.Stdout, ErrOut: os.Stderr},
}
Expand All @@ -122,9 +123,9 @@ var _ = ginkgo.Describe("install hub-addon", func() {
o := Options{
ClusteradmFlags: clusteradmFlags,
bundleVersion: ocmVersion,
values: Values{
values: scenario.Values{
Namespace: ocmNamespace,
hubAddons: []string{hubAddon},
HubAddons: []string{hubAddon},
BundleVersion: ocmBundleVersion,
},
Streams: genericclioptions.IOStreams{Out: os.Stdout, ErrOut: os.Stderr},
Expand Down
13 changes: 2 additions & 11 deletions pkg/cmd/install/hubaddon/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package hubaddon

import (
"k8s.io/cli-runtime/pkg/genericclioptions"
"open-cluster-management.io/clusteradm/pkg/cmd/install/hubaddon/scenario"
genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
"open-cluster-management.io/clusteradm/pkg/version"
)

type Options struct {
Expand All @@ -14,21 +14,12 @@ type Options struct {
names string
//The file to output the resources will be sent to the file.
outputFile string
values Values
values scenario.Values
bundleVersion string

Streams genericclioptions.IOStreams
}

// Values: The values used in the template
type Values struct {
hubAddons []string
// Namespace to install
Namespace string
// Version to install
BundleVersion version.VersionBundle
}

func newOptions(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, streams genericclioptions.IOStreams) *Options {
return &Options{
ClusteradmFlags: clusteradmFlags,
Expand Down
82 changes: 82 additions & 0 deletions pkg/cmd/install/hubaddon/scenario/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,89 @@ package scenario

import (
"embed"

"open-cluster-management.io/clusteradm/pkg/version"
)

//go:embed addon
var Files embed.FS

const (
AppMgrAddonName = "application-manager"
PolicyFrameworkAddonName = "governance-policy-framework"
)

type AddonDeploymentFile struct {
ConfigFiles []string
DeploymentFiles []string
CRDFiles []string
}

// Values: The values used in the template
type Values struct {
HubAddons []string
// Namespace to install
Namespace string
// Version to install
BundleVersion version.VersionBundle
}

var (
AddonDeploymentFiles = map[string]AddonDeploymentFile{
PolicyFrameworkAddonName: {
ConfigFiles: []string{
"addon/policy/addon-controller_clusterrole.yaml",
"addon/policy/addon-controller_clusterrolebinding.yaml",
"addon/policy/addon-controller_role.yaml",
"addon/policy/addon-controller_rolebinding.yaml",
"addon/policy/addon-controller_serviceaccount.yaml",
"addon/policy/propagator_clusterrole.yaml",
"addon/policy/propagator_clusterrolebinding.yaml",
"addon/policy/propagator_role.yaml",
"addon/policy/propagator_rolebinding.yaml",
"addon/policy/propagator_service.yaml",
"addon/policy/propagator_serviceaccount.yaml",
"addon/policy/clustermanagementaddon_configpolicy.yaml",
"addon/policy/clustermanagementaddon_policyframework.yaml",
},
CRDFiles: []string{
"addon/policy/policy.open-cluster-management.io_placementbindings.yaml",
"addon/policy/policy.open-cluster-management.io_policies.yaml",
"addon/policy/policy.open-cluster-management.io_policyautomations.yaml",
"addon/policy/policy.open-cluster-management.io_policysets.yaml",
"addon/appmgr/crd_placementrule.yaml",
},
DeploymentFiles: []string{
"addon/policy/addon-controller_deployment.yaml",
"addon/policy/propagator_deployment.yaml",
},
},
AppMgrAddonName: {
ConfigFiles: []string{
"addon/appmgr/clustermanagementaddon_appmgr.yaml",
"addon/appmgr/clusterrole_agent.yaml",
"addon/appmgr/clusterrole_binding.yaml",
"addon/appmgr/clusterrole.yaml",
"addon/appmgr/service_account.yaml",
"addon/appmgr/service_metrics.yaml",
"addon/appmgr/service_operator.yaml",
"addon/appmgr/mutatingwebhookconfiguration.yaml",
},
CRDFiles: []string{
"addon/appmgr/crd_channel.yaml",
"addon/appmgr/crd_helmrelease.yaml",
"addon/appmgr/crd_placementrule.yaml",
"addon/appmgr/crd_subscription.yaml",
"addon/appmgr/crd_subscriptionstatuses.yaml",
"addon/appmgr/crd_report.yaml",
"addon/appmgr/crd_clusterreport.yaml",
},
DeploymentFiles: []string{
"addon/appmgr/deployment_channel.yaml",
"addon/appmgr/deployment_subscription.yaml",
"addon/appmgr/deployment_placementrule.yaml",
"addon/appmgr/deployment_appsubsummary.yaml",
},
},
}
)
21 changes: 21 additions & 0 deletions pkg/cmd/uninstall/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright Contributors to the Open Cluster Management project
package uninstall

import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"open-cluster-management.io/clusteradm/pkg/cmd/uninstall/hubaddon"
genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
)

// NewCmd provides a cobra command wrapping addon uninstall cmd
func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, streams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{
Use: "uninstall",
Short: "uninstall a feature",
}

cmd.AddCommand(hubaddon.NewCmd(clusteradmFlags, streams))

return cmd
}
Loading

0 comments on commit 261c92a

Please sign in to comment.