Repository: vmware-tanzu/tanzu-framework (language: go)

Issue:
Integrate configuration of CC package into deployment
**Describe the feature request**

Integrate user configuration into CC package deployment.

As part of installing below clusterclass packages, we will need to pass user configuration to the package installation.

- tkg-clusterclass
    - tkg-clusterclass-docker
    - tkg-clusterclass-aws
    - tkg-clusterclass-azure
    - tkg-clusterclass-vsphere

**Describe alternatives you've considered**
Install clusterclass through ytt templating and applying templates directly. We would like to move toward carvel packaging stuff and hence we would like to use packaging approach.

**Affected product area (please put an X in all that apply)**

- [ ] APIs
- [ ] Addons
- [ ] CLI
- [ ] Docs
- [ ] IAM
- [ ] Installation
- [ ] Plugin
- [ ] Security
- [ ] Test and Release
- [ ] User Experience

**Additional context**



Discussion / hints:

Fix patch:
diff --git a/packages/management/tkg-clusterclass-aws/bundle/config/upstream/aws-clusterclass.yaml b/packages/management/tkg-clusterclass-aws/bundle/config/upstream/aws-clusterclass.yaml
new file mode 100644
index 0000000000..8e4f5b2d29
--- /dev/null
+++ b/packages/management/tkg-clusterclass-aws/bundle/config/upstream/aws-clusterclass.yaml
@@ -0,0 +1,49 @@
+#@ load("@ytt:overlay", "overlay")
+#@ load("@ytt:yaml", "yaml")
+#@ load("@ytt:data", "data")
+
+---
+apiVersion: cluster.x-k8s.io/v1beta1
+kind: ClusterClass
+metadata:
+  name: tkg-aws-clusterclass
+  namespace: default
+spec:
+  controlPlane:
+    ref:
+      apiVersion: controlplane.cluster.x-k8s.io/v1beta1
+      kind: KubeadmControlPlaneTemplate
+      name: tkg-aws-kcp
+    machineInfrastructure:
+      ref:
+        kind: AWSMachineTemplate
+        apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+        name: tkg-controlplane-aws-template
+  infrastructure:
+    ref:
+      apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+      kind: AWSClusterTemplate
+      name: tkg-aws-cluster-template
+  workers:
+    machineDeployments:
+    - class: tkg-worker
+      template:
+        bootstrap:
+          ref:
+            apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
+            kind: KubeadmConfigTemplate
+            name: tkg-aws-bootstrap-worker-template
+        infrastructure:
+          ref:
+            apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+            kind: AWSMachineTemplate
+            name: tkg-aws-worker-template
+  variables:
+  - name: AWS_REGION
+    required: true
+    schema:
+      openAPIV3Schema:
+        type: string
+        #@ if data.values.AWS_REGION:
+        default: #@ data.values.AWS_REGION
+        #@ end
diff --git a/packages/management/tkg-clusterclass-aws/bundle/config/values.yaml b/packages/management/tkg-clusterclass-aws/bundle/config/values.yaml
index c84e60c305..005f1782e3 100644
--- a/packages/management/tkg-clusterclass-aws/bundle/config/values.yaml
+++ b/packages/management/tkg-clusterclass-aws/bundle/config/values.yaml
@@ -4,3 +4,5 @@
 ---
 
 #! User configurable values for tkg-clusterclass-aws
+
+AWS_REGION: ""
diff --git a/packages/management/tkg-clusterclass-azure/bundle/config/upstream/azure-clusterclass.yaml b/packages/management/tkg-clusterclass-azure/bundle/config/upstream/azure-clusterclass.yaml
new file mode 100644
index 0000000000..2b10ed63e9
--- /dev/null
+++ b/packages/management/tkg-clusterclass-azure/bundle/config/upstream/azure-clusterclass.yaml
@@ -0,0 +1,35 @@
+apiVersion: cluster.x-k8s.io/v1beta1
+kind: ClusterClass
+metadata:
+  name: tkg-azure-clusterclass
+  namespace: default
+spec:
+  controlPlane:
+    ref:
+      apiVersion: controlplane.cluster.x-k8s.io/v1beta1
+      kind: KubeadmControlPlaneTemplate
+      name: tkg-azure-kcp
+    machineInfrastructure:
+      ref:
+        kind: AzureMachineTemplate
+        apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+        name: tkg-controlplane-azure-template
+  infrastructure:
+    ref:
+      apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+      kind: AzureClusterTemplate
+      name: tkg-azure-cluster-template
+  workers:
+    machineDeployments:
+    - class: tkg-worker
+      template:
+        bootstrap:
+          ref:
+            apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
+            kind: KubeadmConfigTemplate
+            name: tkg-azure-bootstrap-worker-template
+        infrastructure:
+          ref:
+            apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+            kind: AzureMachineTemplate
+            name: tkg-azure-worker-template
diff --git a/packages/management/tkg-clusterclass-docker/bundle/config/upstream/docker-clusterclass.yaml b/packages/management/tkg-clusterclass-docker/bundle/config/upstream/docker-clusterclass.yaml
new file mode 100644
index 0000000000..33c964359b
--- /dev/null
+++ b/packages/management/tkg-clusterclass-docker/bundle/config/upstream/docker-clusterclass.yaml
@@ -0,0 +1,35 @@
+apiVersion: cluster.x-k8s.io/v1beta1
+kind: ClusterClass
+metadata:
+  name: tkg-docker-clusterclass
+  namespace: default
+spec:
+  controlPlane:
+    ref:
+      apiVersion: controlplane.cluster.x-k8s.io/v1beta1
+      kind: KubeadmControlPlaneTemplate
+      name: tkg-docker-kcp
+    machineInfrastructure:
+      ref:
+        kind: DockerMachineTemplate
+        apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+        name: tkg-controlplane-docker-template
+  infrastructure:
+    ref:
+      apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+      kind: DockerClusterTemplate
+      name: tkg-docker-cluster-template
+  workers:
+    machineDeployments:
+    - class: tkg-worker
+      template:
+        bootstrap:
+          ref:
+            apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
+            kind: KubeadmConfigTemplate
+            name: tkg-docker-bootstrap-worker-template
+        infrastructure:
+          ref:
+            apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+            kind: DockerMachineTemplate
+            name: tkg-docker-worker-template
diff --git a/packages/management/tkg-clusterclass-vsphere/bundle/config/upstream/vsphere-clusterclass.yaml b/packages/management/tkg-clusterclass-vsphere/bundle/config/upstream/vsphere-clusterclass.yaml
new file mode 100644
index 0000000000..1d7e199c48
--- /dev/null
+++ b/packages/management/tkg-clusterclass-vsphere/bundle/config/upstream/vsphere-clusterclass.yaml
@@ -0,0 +1,35 @@
+apiVersion: cluster.x-k8s.io/v1beta1
+kind: ClusterClass
+metadata:
+  name: tkg-vsphere-clusterclass
+  namespace: default
+spec:
+  controlPlane:
+    ref:
+      apiVersion: controlplane.cluster.x-k8s.io/v1beta1
+      kind: KubeadmControlPlaneTemplate
+      name: tkg-vsphere-kcp
+    machineInfrastructure:
+      ref:
+        kind: VsphereMachineTemplate
+        apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+        name: tkg-controlplane-vsphere-template
+  infrastructure:
+    ref:
+      apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+      kind: VSphereClusterTemplate
+      name: tkg-vsphere-cluster-template
+  workers:
+    machineDeployments:
+    - class: tkg-worker
+      template:
+        bootstrap:
+          ref:
+            apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
+            kind: KubeadmConfigTemplate
+            name: tkg-vsphere-bootstrap-worker-template
+        infrastructure:
+          ref:
+            apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
+            kind: VsphereMachineTemplate
+            name: tkg-vsphere-worker-template
diff --git a/pkg/v1/config/clientconfig.go b/pkg/v1/config/clientconfig.go
index c2d092a964..8bf169246d 100644
--- a/pkg/v1/config/clientconfig.go
+++ b/pkg/v1/config/clientconfig.go
@@ -50,6 +50,10 @@ const (
 	// support of ARM should be included when discovering available AWS instance types. Setting feature flag to true
 	// filters out ARM supporting instance types; false allows ARM instance types to be included in results.
 	FeatureFlagAwsInstanceTypesExcludeArm = "features.management-cluster.aws-instance-types-exclude-arm"
+	// PackageBasedLCM feature flag determines whether to use package based lifecycle management of management component
+	// or legacy way of managing management components. This is also used for clusterclass based management and workload
+	// cluster provisioning
+	FeatureFlagPackageBasedLCM = "features.global.package-based-lcm-beta"
 )
 
 // DefaultCliFeatureFlags is used to populate an initially empty config file with default values for feature flags.
@@ -78,6 +82,7 @@ var (
 		FeatureFlagClusterCustomNameservers:                   false,
 		FeatureFlagManagementClusterNetworkSeparation:         false,
 		FeatureFlagAwsInstanceTypesExcludeArm:                 true,
+		FeatureFlagPackageBasedLCM:                            false,
 	}
 )
 
diff --git a/pkg/v1/tkg/client/init.go b/pkg/v1/tkg/client/init.go
index 89bc7738b4..d8eaa82e5e 100644
--- a/pkg/v1/tkg/client/init.go
+++ b/pkg/v1/tkg/client/init.go
@@ -18,6 +18,7 @@ import (
 	clusterctl "sigs.k8s.io/cluster-api/cmd/clusterctl/client"
 	crtclient "sigs.k8s.io/controller-runtime/pkg/client"
 
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/config"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/clusterclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/constants"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/kind"
@@ -201,6 +202,13 @@ func (c *TkgClient) InitRegion(options *InitRegionOptions) error { //nolint:funl
 		return errors.Wrap(err, "unable to initialize providers")
 	}
 
+	// If clusterclass feature flag is enabled then deploy management components
+	if config.IsFeatureActivated(config.FeatureFlagPackageBasedLCM) {
+		if err = c.InstallManagementComponents(bootstrapClusterKubeconfigPath, ""); err != nil {
+			return errors.Wrap(err, "unable to install management components to bootstrap cluster")
+		}
+	}
+
 	isStartedRegionalClusterCreation = true
 
 	targetClusterNamespace := defaultTkgNamespace
@@ -273,6 +281,13 @@ func (c *TkgClient) InitRegion(options *InitRegionOptions) error { //nolint:funl
 		return err
 	}
 
+	// If clusterclass feature flag is enabled then deploy management components to the cluster
+	if config.IsFeatureActivated(config.FeatureFlagPackageBasedLCM) {
+		if err = c.InstallManagementComponents(regionalClusterKubeconfigPath, kubeContext); err != nil {
+			return errors.Wrap(err, "unable to install management components to management cluster")
+		}
+	}
+
 	log.Info("Waiting for the management cluster to get ready for move...")
 	if err := c.WaitForClusterReadyForMove(bootStrapClusterClient, options.ClusterName, targetClusterNamespace); err != nil {
 		return errors.Wrap(err, "unable to wait for cluster getting ready for move")
diff --git a/pkg/v1/tkg/client/management_components.go b/pkg/v1/tkg/client/management_components.go
new file mode 100644
index 0000000000..f6112ce57b
--- /dev/null
+++ b/pkg/v1/tkg/client/management_components.go
@@ -0,0 +1,126 @@
+// Copyright 2021 VMware, Inc. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package client
+
+import (
+	"os"
+
+	"github.com/pkg/errors"
+	"gopkg.in/yaml.v3"
+
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/managementcomponents"
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgconfigreaderwriter"
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/utils"
+)
+
+// InstallManagementComponents install management components to the cluster
+func (c *TkgClient) InstallManagementComponents(kubeconfig, kubecontext string) error {
+	managementPackageRepoImage, err := c.tkgBomClient.GetManagementPackageRepositoryImage()
+	if err != nil {
+		return errors.Wrap(err, "unable to get management package repository image")
+	}
+
+	// Override management package repository image if specified as part of below environment variable
+	// NOTE: this override is only for testing purpose and we don't expect this to be used in production scenario
+	mprImage := os.Getenv("MANAGEMENT_PACKAGE_REPO_IMAGE")
+	if mprImage != "" {
+		managementPackageRepoImage = mprImage
+	}
+
+	tkgPackageValuesFile, err := c.getTKGPackageConfigValuesFile()
+	if err != nil {
+		return err
+	}
+
+	managementcomponentsInstallOptions := managementcomponents.ManagementComponentsInstallOptions{
+		ClusterOptions: managementcomponents.ClusterOptions{
+			Kubeconfig:  kubeconfig,
+			Kubecontext: kubecontext,
+		},
+		// TODO: Install kapp-controller using from the tanzu managed template manifest (https://github.com/vmware-tanzu/tanzu-framework/issues/1672)
+		KappControllerOptions: managementcomponents.KappControllerOptions{
+			KappControllerConfigFile:       "https://github.com/vmware-tanzu/carvel-kapp-controller/releases/download/v0.31.0/release.yml",
+			KappControllerInstallNamespace: "kapp-controller",
+		},
+		ManagementPackageRepositoryOptions: managementcomponents.ManagementPackageRepositoryOptions{
+			ManagementPackageRepoImage: managementPackageRepoImage,
+			TKGPackageValuesFile:       tkgPackageValuesFile,
+		},
+	}
+
+	return managementcomponents.InstallManagementComponents(&managementcomponentsInstallOptions)
+}
+
+func (c *TkgClient) getTKGPackageConfigValuesFile() (string, error) {
+	path, err := c.tkgConfigPathsClient.GetConfigDefaultsFilePath()
+	if err != nil {
+		return "", err
+	}
+
+	userProviderConfigValues, err := c.GetUserConfigVariableValueMap(path, c.TKGConfigReaderWriter())
+	if err != nil {
+		return "", err
+	}
+
+	tkgPackageConfig, err := managementcomponents.GetTKGPackageConfigValuesFileFromUserConfig(userProviderConfigValues)
+	if err != nil {
+		return "", err
+	}
+
+	configBytes, err := yaml.Marshal(tkgPackageConfig)
+	if err != nil {
+		return "", err
+	}
+
+	valuesFile, err := utils.CreateTempFile("", "")
+	if err != nil {
+		return "", err
+	}
+
+	err = utils.WriteToFile(valuesFile, configBytes)
+	if err != nil {
+		return "", err
+	}
+	return valuesFile, nil
+}
+
+// GetUserConfigVariableValueMap is a specific implementation expecting to use a flat key-value
+// file to provide a source of keys to filter for the valid user provided values.
+// For example, this function uses config_default.yaml filepath to find relevant config variables
+// and returns the config map of user provided variable among all applicable config variables
+func (c *TkgClient) GetUserConfigVariableValueMap(configDefaultFilePath string, rw tkgconfigreaderwriter.TKGConfigReaderWriter) (map[string]string, error) {
+	bytes, err := os.ReadFile(configDefaultFilePath)
+	if err != nil {
+		return nil, err
+	}
+
+	variables, err := GetConfigVariableListFromYamlData(bytes)
+	if err != nil {
+		return nil, err
+	}
+
+	userProvidedConfigValues := map[string]string{}
+	for _, k := range variables {
+		if v, e := rw.Get(k); e == nil {
+			userProvidedConfigValues[k] = v
+		}
+	}
+
+	return userProvidedConfigValues, nil
+}
+
+func GetConfigVariableListFromYamlData(bytes []byte) ([]string, error) {
+	configValues := map[string]interface{}{}
+	err := yaml.Unmarshal(bytes, &configValues)
+	if err != nil {
+		return nil, errors.Wrap(err, "error while unmarshaling")
+	}
+
+	keys := make([]string, 0, len(configValues))
+	for k := range configValues {
+		keys = append(keys, k)
+	}
+
+	return keys, nil
+}
diff --git a/pkg/v1/tkg/constants/cluster_internal.go b/pkg/v1/tkg/constants/cluster_internal.go
index b891751929..e4142365b9 100644
--- a/pkg/v1/tkg/constants/cluster_internal.go
+++ b/pkg/v1/tkg/constants/cluster_internal.go
@@ -118,3 +118,10 @@ const (
 	// ClusterNameLabel is the label on the Secret to indicate the cluster on which addon is to be installed
 	ClusterNameLabel = "tkg.tanzu.vmware.com/cluster-name"
 )
+
+// TKG management package related constants
+const (
+	TKGManagementPackageName           = "tkg.tanzu.vmware.com"
+	TKGManagementPackageInstallName    = "tkg-pkg"
+	TKGManagementPackageRepositoryName = "management"
+)
diff --git a/pkg/v1/tkg/constants/files.go b/pkg/v1/tkg/constants/files.go
index 17082e3f93..3a0b1b3242 100644
--- a/pkg/v1/tkg/constants/files.go
+++ b/pkg/v1/tkg/constants/files.go
@@ -29,6 +29,7 @@ const (
 	TKGConfigFileName               = "config.yaml"
 	TKGDefaultClusterConfigFileName = "cluster-config.yaml"
 	TKGCompatibilityFileName        = "tkg-compatibility.yaml"
+	TKGConfigDefaultFileName        = "config_default.yaml"
 
 	TKGClusterConfigFileDirForUI           = "clusterconfigs"
 	TKGRegistryCertFile                    = "registry_certs"
diff --git a/pkg/v1/tkg/fakes/tkgconfigbomclient.go b/pkg/v1/tkg/fakes/tkgconfigbomclient.go
index 0aa59a122c..da7084c70e 100644
--- a/pkg/v1/tkg/fakes/tkgconfigbomclient.go
+++ b/pkg/v1/tkg/fakes/tkgconfigbomclient.go
@@ -207,6 +207,18 @@ type TKGConfigBomClient struct {
 		result1 string
 		result2 error
 	}
+	GetManagementPackageRepositoryImageStub        func() (string, error)
+	getManagementPackageRepositoryImageMutex       sync.RWMutex
+	getManagementPackageRepositoryImageArgsForCall []struct {
+	}
+	getManagementPackageRepositoryImageReturns struct {
+		result1 string
+		result2 error
+	}
+	getManagementPackageRepositoryImageReturnsOnCall map[int]struct {
+		result1 string
+		result2 error
+	}
 	InitBOMRegistryStub        func() (registry.Registry, error)
 	initBOMRegistryMutex       sync.RWMutex
 	initBOMRegistryArgsForCall []struct {
@@ -1169,6 +1181,62 @@ func (fake *TKGConfigBomClient) GetK8sVersionFromTkrVersionReturnsOnCall(i int,
 	}{result1, result2}
 }
 
+func (fake *TKGConfigBomClient) GetManagementPackageRepositoryImage() (string, error) {
+	fake.getManagementPackageRepositoryImageMutex.Lock()
+	ret, specificReturn := fake.getManagementPackageRepositoryImageReturnsOnCall[len(fake.getManagementPackageRepositoryImageArgsForCall)]
+	fake.getManagementPackageRepositoryImageArgsForCall = append(fake.getManagementPackageRepositoryImageArgsForCall, struct {
+	}{})
+	stub := fake.GetManagementPackageRepositoryImageStub
+	fakeReturns := fake.getManagementPackageRepositoryImageReturns
+	fake.recordInvocation("GetManagementPackageRepositoryImage", []interface{}{})
+	fake.getManagementPackageRepositoryImageMutex.Unlock()
+	if stub != nil {
+		return stub()
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGConfigBomClient) GetManagementPackageRepositoryImageCallCount() int {
+	fake.getManagementPackageRepositoryImageMutex.RLock()
+	defer fake.getManagementPackageRepositoryImageMutex.RUnlock()
+	return len(fake.getManagementPackageRepositoryImageArgsForCall)
+}
+
+func (fake *TKGConfigBomClient) GetManagementPackageRepositoryImageCalls(stub func() (string, error)) {
+	fake.getManagementPackageRepositoryImageMutex.Lock()
+	defer fake.getManagementPackageRepositoryImageMutex.Unlock()
+	fake.GetManagementPackageRepositoryImageStub = stub
+}
+
+func (fake *TKGConfigBomClient) GetManagementPackageRepositoryImageReturns(result1 string, result2 error) {
+	fake.getManagementPackageRepositoryImageMutex.Lock()
+	defer fake.getManagementPackageRepositoryImageMutex.Unlock()
+	fake.GetManagementPackageRepositoryImageStub = nil
+	fake.getManagementPackageRepositoryImageReturns = struct {
+		result1 string
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGConfigBomClient) GetManagementPackageRepositoryImageReturnsOnCall(i int, result1 string, result2 error) {
+	fake.getManagementPackageRepositoryImageMutex.Lock()
+	defer fake.getManagementPackageRepositoryImageMutex.Unlock()
+	fake.GetManagementPackageRepositoryImageStub = nil
+	if fake.getManagementPackageRepositoryImageReturnsOnCall == nil {
+		fake.getManagementPackageRepositoryImageReturnsOnCall = make(map[int]struct {
+			result1 string
+			result2 error
+		})
+	}
+	fake.getManagementPackageRepositoryImageReturnsOnCall[i] = struct {
+		result1 string
+		result2 error
+	}{result1, result2}
+}
+
 func (fake *TKGConfigBomClient) InitBOMRegistry() (registry.Registry, error) {
 	fake.initBOMRegistryMutex.Lock()
 	ret, specificReturn := fake.initBOMRegistryReturnsOnCall[len(fake.initBOMRegistryArgsForCall)]
@@ -1313,6 +1381,8 @@ func (fake *TKGConfigBomClient) Invocations() map[string][][]interface{} {
 	defer fake.getDefaultTkrBOMConfigurationMutex.RUnlock()
 	fake.getK8sVersionFromTkrVersionMutex.RLock()
 	defer fake.getK8sVersionFromTkrVersionMutex.RUnlock()
+	fake.getManagementPackageRepositoryImageMutex.RLock()
+	defer fake.getManagementPackageRepositoryImageMutex.RUnlock()
 	fake.initBOMRegistryMutex.RLock()
 	defer fake.initBOMRegistryMutex.RUnlock()
 	fake.isCustomRepositorySkipTLSVerifyMutex.RLock()
diff --git a/pkg/v1/tkg/fakes/tkgpackageclient.go b/pkg/v1/tkg/fakes/tkgpackageclient.go
new file mode 100644
index 0000000000..51ef79e154
--- /dev/null
+++ b/pkg/v1/tkg/fakes/tkgpackageclient.go
@@ -0,0 +1,1771 @@
+// Code generated by counterfeiter. DO NOT EDIT.
+package fakes
+
+import (
+	"sync"
+
+	v1 "k8s.io/api/core/v1"
+
+	v1alpha1a "github.com/vmware-tanzu/carvel-kapp-controller/pkg/apis/packaging/v1alpha1"
+	"github.com/vmware-tanzu/carvel-kapp-controller/pkg/apiserver/apis/datapackaging/v1alpha1"
+	v1alpha1b "github.com/vmware-tanzu/carvel-secretgen-controller/pkg/apis/secretgen2/v1alpha1"
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
+)
+
+type TKGPackageClient struct {
+	AddRegistrySecretStub        func(*tkgpackagedatamodel.RegistrySecretOptions) error
+	addRegistrySecretMutex       sync.RWMutex
+	addRegistrySecretArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}
+	addRegistrySecretReturns struct {
+		result1 error
+	}
+	addRegistrySecretReturnsOnCall map[int]struct {
+		result1 error
+	}
+	AddRepositoryStub        func(*tkgpackagedatamodel.RepositoryOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType)
+	addRepositoryMutex       sync.RWMutex
+	addRepositoryArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+		arg3 tkgpackagedatamodel.OperationType
+	}
+	AddRepositorySyncStub        func(*tkgpackagedatamodel.RepositoryOptions, tkgpackagedatamodel.OperationType) error
+	addRepositorySyncMutex       sync.RWMutex
+	addRepositorySyncArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+		arg2 tkgpackagedatamodel.OperationType
+	}
+	addRepositorySyncReturns struct {
+		result1 error
+	}
+	addRepositorySyncReturnsOnCall map[int]struct {
+		result1 error
+	}
+	DeleteRegistrySecretStub        func(*tkgpackagedatamodel.RegistrySecretOptions) (bool, error)
+	deleteRegistrySecretMutex       sync.RWMutex
+	deleteRegistrySecretArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}
+	deleteRegistrySecretReturns struct {
+		result1 bool
+		result2 error
+	}
+	deleteRegistrySecretReturnsOnCall map[int]struct {
+		result1 bool
+		result2 error
+	}
+	DeleteRepositoryStub        func(*tkgpackagedatamodel.RepositoryOptions, *tkgpackagedatamodel.PackageProgress)
+	deleteRepositoryMutex       sync.RWMutex
+	deleteRepositoryArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+	}
+	DeleteRepositorySyncStub        func(*tkgpackagedatamodel.RepositoryOptions) error
+	deleteRepositorySyncMutex       sync.RWMutex
+	deleteRepositorySyncArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+	}
+	deleteRepositorySyncReturns struct {
+		result1 error
+	}
+	deleteRepositorySyncReturnsOnCall map[int]struct {
+		result1 error
+	}
+	GetPackageStub        func(*tkgpackagedatamodel.PackageOptions) (*v1alpha1.PackageMetadata, *v1alpha1.Package, error)
+	getPackageMutex       sync.RWMutex
+	getPackageArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+	}
+	getPackageReturns struct {
+		result1 *v1alpha1.PackageMetadata
+		result2 *v1alpha1.Package
+		result3 error
+	}
+	getPackageReturnsOnCall map[int]struct {
+		result1 *v1alpha1.PackageMetadata
+		result2 *v1alpha1.Package
+		result3 error
+	}
+	GetPackageInstallStub        func(*tkgpackagedatamodel.PackageOptions) (*v1alpha1a.PackageInstall, error)
+	getPackageInstallMutex       sync.RWMutex
+	getPackageInstallArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+	}
+	getPackageInstallReturns struct {
+		result1 *v1alpha1a.PackageInstall
+		result2 error
+	}
+	getPackageInstallReturnsOnCall map[int]struct {
+		result1 *v1alpha1a.PackageInstall
+		result2 error
+	}
+	GetRepositoryStub        func(*tkgpackagedatamodel.RepositoryOptions) (*v1alpha1a.PackageRepository, error)
+	getRepositoryMutex       sync.RWMutex
+	getRepositoryArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+	}
+	getRepositoryReturns struct {
+		result1 *v1alpha1a.PackageRepository
+		result2 error
+	}
+	getRepositoryReturnsOnCall map[int]struct {
+		result1 *v1alpha1a.PackageRepository
+		result2 error
+	}
+	GetSecretExportStub        func(*tkgpackagedatamodel.RegistrySecretOptions) (*v1alpha1b.SecretExport, error)
+	getSecretExportMutex       sync.RWMutex
+	getSecretExportArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}
+	getSecretExportReturns struct {
+		result1 *v1alpha1b.SecretExport
+		result2 error
+	}
+	getSecretExportReturnsOnCall map[int]struct {
+		result1 *v1alpha1b.SecretExport
+		result2 error
+	}
+	InstallPackageStub        func(*tkgpackagedatamodel.PackageOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType)
+	installPackageMutex       sync.RWMutex
+	installPackageArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+		arg3 tkgpackagedatamodel.OperationType
+	}
+	InstallPackageSyncStub        func(*tkgpackagedatamodel.PackageOptions, tkgpackagedatamodel.OperationType) error
+	installPackageSyncMutex       sync.RWMutex
+	installPackageSyncArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+		arg2 tkgpackagedatamodel.OperationType
+	}
+	installPackageSyncReturns struct {
+		result1 error
+	}
+	installPackageSyncReturnsOnCall map[int]struct {
+		result1 error
+	}
+	ListPackageInstallsStub        func(*tkgpackagedatamodel.PackageOptions) (*v1alpha1a.PackageInstallList, error)
+	listPackageInstallsMutex       sync.RWMutex
+	listPackageInstallsArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+	}
+	listPackageInstallsReturns struct {
+		result1 *v1alpha1a.PackageInstallList
+		result2 error
+	}
+	listPackageInstallsReturnsOnCall map[int]struct {
+		result1 *v1alpha1a.PackageInstallList
+		result2 error
+	}
+	ListPackageMetadataStub        func(*tkgpackagedatamodel.PackageAvailableOptions) (*v1alpha1.PackageMetadataList, error)
+	listPackageMetadataMutex       sync.RWMutex
+	listPackageMetadataArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageAvailableOptions
+	}
+	listPackageMetadataReturns struct {
+		result1 *v1alpha1.PackageMetadataList
+		result2 error
+	}
+	listPackageMetadataReturnsOnCall map[int]struct {
+		result1 *v1alpha1.PackageMetadataList
+		result2 error
+	}
+	ListPackagesStub        func(*tkgpackagedatamodel.PackageAvailableOptions) (*v1alpha1.PackageList, error)
+	listPackagesMutex       sync.RWMutex
+	listPackagesArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageAvailableOptions
+	}
+	listPackagesReturns struct {
+		result1 *v1alpha1.PackageList
+		result2 error
+	}
+	listPackagesReturnsOnCall map[int]struct {
+		result1 *v1alpha1.PackageList
+		result2 error
+	}
+	ListRegistrySecretsStub        func(*tkgpackagedatamodel.RegistrySecretOptions) (*v1.SecretList, error)
+	listRegistrySecretsMutex       sync.RWMutex
+	listRegistrySecretsArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}
+	listRegistrySecretsReturns struct {
+		result1 *v1.SecretList
+		result2 error
+	}
+	listRegistrySecretsReturnsOnCall map[int]struct {
+		result1 *v1.SecretList
+		result2 error
+	}
+	ListRepositoriesStub        func(*tkgpackagedatamodel.RepositoryOptions) (*v1alpha1a.PackageRepositoryList, error)
+	listRepositoriesMutex       sync.RWMutex
+	listRepositoriesArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+	}
+	listRepositoriesReturns struct {
+		result1 *v1alpha1a.PackageRepositoryList
+		result2 error
+	}
+	listRepositoriesReturnsOnCall map[int]struct {
+		result1 *v1alpha1a.PackageRepositoryList
+		result2 error
+	}
+	ListSecretExportsStub        func(*tkgpackagedatamodel.RegistrySecretOptions) (*v1alpha1b.SecretExportList, error)
+	listSecretExportsMutex       sync.RWMutex
+	listSecretExportsArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}
+	listSecretExportsReturns struct {
+		result1 *v1alpha1b.SecretExportList
+		result2 error
+	}
+	listSecretExportsReturnsOnCall map[int]struct {
+		result1 *v1alpha1b.SecretExportList
+		result2 error
+	}
+	UninstallPackageStub        func(*tkgpackagedatamodel.PackageOptions, *tkgpackagedatamodel.PackageProgress)
+	uninstallPackageMutex       sync.RWMutex
+	uninstallPackageArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+	}
+	UninstallPackageSyncStub        func(*tkgpackagedatamodel.PackageOptions) error
+	uninstallPackageSyncMutex       sync.RWMutex
+	uninstallPackageSyncArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+	}
+	uninstallPackageSyncReturns struct {
+		result1 error
+	}
+	uninstallPackageSyncReturnsOnCall map[int]struct {
+		result1 error
+	}
+	UpdatePackageStub        func(*tkgpackagedatamodel.PackageOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType)
+	updatePackageMutex       sync.RWMutex
+	updatePackageArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+		arg3 tkgpackagedatamodel.OperationType
+	}
+	UpdatePackageSyncStub        func(*tkgpackagedatamodel.PackageOptions, tkgpackagedatamodel.OperationType) error
+	updatePackageSyncMutex       sync.RWMutex
+	updatePackageSyncArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+		arg2 tkgpackagedatamodel.OperationType
+	}
+	updatePackageSyncReturns struct {
+		result1 error
+	}
+	updatePackageSyncReturnsOnCall map[int]struct {
+		result1 error
+	}
+	UpdateRegistrySecretStub        func(*tkgpackagedatamodel.RegistrySecretOptions) error
+	updateRegistrySecretMutex       sync.RWMutex
+	updateRegistrySecretArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}
+	updateRegistrySecretReturns struct {
+		result1 error
+	}
+	updateRegistrySecretReturnsOnCall map[int]struct {
+		result1 error
+	}
+	UpdateRepositoryStub        func(*tkgpackagedatamodel.RepositoryOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType)
+	updateRepositoryMutex       sync.RWMutex
+	updateRepositoryArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+		arg3 tkgpackagedatamodel.OperationType
+	}
+	UpdateRepositorySyncStub        func(*tkgpackagedatamodel.RepositoryOptions, tkgpackagedatamodel.OperationType) error
+	updateRepositorySyncMutex       sync.RWMutex
+	updateRepositorySyncArgsForCall []struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+		arg2 tkgpackagedatamodel.OperationType
+	}
+	updateRepositorySyncReturns struct {
+		result1 error
+	}
+	updateRepositorySyncReturnsOnCall map[int]struct {
+		result1 error
+	}
+	invocations      map[string][][]interface{}
+	invocationsMutex sync.RWMutex
+}
+
+func (fake *TKGPackageClient) AddRegistrySecret(arg1 *tkgpackagedatamodel.RegistrySecretOptions) error {
+	fake.addRegistrySecretMutex.Lock()
+	ret, specificReturn := fake.addRegistrySecretReturnsOnCall[len(fake.addRegistrySecretArgsForCall)]
+	fake.addRegistrySecretArgsForCall = append(fake.addRegistrySecretArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}{arg1})
+	stub := fake.AddRegistrySecretStub
+	fakeReturns := fake.addRegistrySecretReturns
+	fake.recordInvocation("AddRegistrySecret", []interface{}{arg1})
+	fake.addRegistrySecretMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	return fakeReturns.result1
+}
+
+func (fake *TKGPackageClient) AddRegistrySecretCallCount() int {
+	fake.addRegistrySecretMutex.RLock()
+	defer fake.addRegistrySecretMutex.RUnlock()
+	return len(fake.addRegistrySecretArgsForCall)
+}
+
+func (fake *TKGPackageClient) AddRegistrySecretCalls(stub func(*tkgpackagedatamodel.RegistrySecretOptions) error) {
+	fake.addRegistrySecretMutex.Lock()
+	defer fake.addRegistrySecretMutex.Unlock()
+	fake.AddRegistrySecretStub = stub
+}
+
+func (fake *TKGPackageClient) AddRegistrySecretArgsForCall(i int) *tkgpackagedatamodel.RegistrySecretOptions {
+	fake.addRegistrySecretMutex.RLock()
+	defer fake.addRegistrySecretMutex.RUnlock()
+	argsForCall := fake.addRegistrySecretArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) AddRegistrySecretReturns(result1 error) {
+	fake.addRegistrySecretMutex.Lock()
+	defer fake.addRegistrySecretMutex.Unlock()
+	fake.AddRegistrySecretStub = nil
+	fake.addRegistrySecretReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) AddRegistrySecretReturnsOnCall(i int, result1 error) {
+	fake.addRegistrySecretMutex.Lock()
+	defer fake.addRegistrySecretMutex.Unlock()
+	fake.AddRegistrySecretStub = nil
+	if fake.addRegistrySecretReturnsOnCall == nil {
+		fake.addRegistrySecretReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.addRegistrySecretReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) AddRepository(arg1 *tkgpackagedatamodel.RepositoryOptions, arg2 *tkgpackagedatamodel.PackageProgress, arg3 tkgpackagedatamodel.OperationType) {
+	fake.addRepositoryMutex.Lock()
+	fake.addRepositoryArgsForCall = append(fake.addRepositoryArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+		arg3 tkgpackagedatamodel.OperationType
+	}{arg1, arg2, arg3})
+	stub := fake.AddRepositoryStub
+	fake.recordInvocation("AddRepository", []interface{}{arg1, arg2, arg3})
+	fake.addRepositoryMutex.Unlock()
+	if stub != nil {
+		fake.AddRepositoryStub(arg1, arg2, arg3)
+	}
+}
+
+func (fake *TKGPackageClient) AddRepositoryCallCount() int {
+	fake.addRepositoryMutex.RLock()
+	defer fake.addRepositoryMutex.RUnlock()
+	return len(fake.addRepositoryArgsForCall)
+}
+
+func (fake *TKGPackageClient) AddRepositoryCalls(stub func(*tkgpackagedatamodel.RepositoryOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType)) {
+	fake.addRepositoryMutex.Lock()
+	defer fake.addRepositoryMutex.Unlock()
+	fake.AddRepositoryStub = stub
+}
+
+func (fake *TKGPackageClient) AddRepositoryArgsForCall(i int) (*tkgpackagedatamodel.RepositoryOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType) {
+	fake.addRepositoryMutex.RLock()
+	defer fake.addRepositoryMutex.RUnlock()
+	argsForCall := fake.addRepositoryArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3
+}
+
+func (fake *TKGPackageClient) AddRepositorySync(arg1 *tkgpackagedatamodel.RepositoryOptions, arg2 tkgpackagedatamodel.OperationType) error {
+	fake.addRepositorySyncMutex.Lock()
+	ret, specificReturn := fake.addRepositorySyncReturnsOnCall[len(fake.addRepositorySyncArgsForCall)]
+	fake.addRepositorySyncArgsForCall = append(fake.addRepositorySyncArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+		arg2 tkgpackagedatamodel.OperationType
+	}{arg1, arg2})
+	stub := fake.AddRepositorySyncStub
+	fakeReturns := fake.addRepositorySyncReturns
+	fake.recordInvocation("AddRepositorySync", []interface{}{arg1, arg2})
+	fake.addRepositorySyncMutex.Unlock()
+	if stub != nil {
+		return stub(arg1, arg2)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	return fakeReturns.result1
+}
+
+func (fake *TKGPackageClient) AddRepositorySyncCallCount() int {
+	fake.addRepositorySyncMutex.RLock()
+	defer fake.addRepositorySyncMutex.RUnlock()
+	return len(fake.addRepositorySyncArgsForCall)
+}
+
+func (fake *TKGPackageClient) AddRepositorySyncCalls(stub func(*tkgpackagedatamodel.RepositoryOptions, tkgpackagedatamodel.OperationType) error) {
+	fake.addRepositorySyncMutex.Lock()
+	defer fake.addRepositorySyncMutex.Unlock()
+	fake.AddRepositorySyncStub = stub
+}
+
+func (fake *TKGPackageClient) AddRepositorySyncArgsForCall(i int) (*tkgpackagedatamodel.RepositoryOptions, tkgpackagedatamodel.OperationType) {
+	fake.addRepositorySyncMutex.RLock()
+	defer fake.addRepositorySyncMutex.RUnlock()
+	argsForCall := fake.addRepositorySyncArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2
+}
+
+func (fake *TKGPackageClient) AddRepositorySyncReturns(result1 error) {
+	fake.addRepositorySyncMutex.Lock()
+	defer fake.addRepositorySyncMutex.Unlock()
+	fake.AddRepositorySyncStub = nil
+	fake.addRepositorySyncReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) AddRepositorySyncReturnsOnCall(i int, result1 error) {
+	fake.addRepositorySyncMutex.Lock()
+	defer fake.addRepositorySyncMutex.Unlock()
+	fake.AddRepositorySyncStub = nil
+	if fake.addRepositorySyncReturnsOnCall == nil {
+		fake.addRepositorySyncReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.addRepositorySyncReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) DeleteRegistrySecret(arg1 *tkgpackagedatamodel.RegistrySecretOptions) (bool, error) {
+	fake.deleteRegistrySecretMutex.Lock()
+	ret, specificReturn := fake.deleteRegistrySecretReturnsOnCall[len(fake.deleteRegistrySecretArgsForCall)]
+	fake.deleteRegistrySecretArgsForCall = append(fake.deleteRegistrySecretArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}{arg1})
+	stub := fake.DeleteRegistrySecretStub
+	fakeReturns := fake.deleteRegistrySecretReturns
+	fake.recordInvocation("DeleteRegistrySecret", []interface{}{arg1})
+	fake.deleteRegistrySecretMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGPackageClient) DeleteRegistrySecretCallCount() int {
+	fake.deleteRegistrySecretMutex.RLock()
+	defer fake.deleteRegistrySecretMutex.RUnlock()
+	return len(fake.deleteRegistrySecretArgsForCall)
+}
+
+func (fake *TKGPackageClient) DeleteRegistrySecretCalls(stub func(*tkgpackagedatamodel.RegistrySecretOptions) (bool, error)) {
+	fake.deleteRegistrySecretMutex.Lock()
+	defer fake.deleteRegistrySecretMutex.Unlock()
+	fake.DeleteRegistrySecretStub = stub
+}
+
+func (fake *TKGPackageClient) DeleteRegistrySecretArgsForCall(i int) *tkgpackagedatamodel.RegistrySecretOptions {
+	fake.deleteRegistrySecretMutex.RLock()
+	defer fake.deleteRegistrySecretMutex.RUnlock()
+	argsForCall := fake.deleteRegistrySecretArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) DeleteRegistrySecretReturns(result1 bool, result2 error) {
+	fake.deleteRegistrySecretMutex.Lock()
+	defer fake.deleteRegistrySecretMutex.Unlock()
+	fake.DeleteRegistrySecretStub = nil
+	fake.deleteRegistrySecretReturns = struct {
+		result1 bool
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) DeleteRegistrySecretReturnsOnCall(i int, result1 bool, result2 error) {
+	fake.deleteRegistrySecretMutex.Lock()
+	defer fake.deleteRegistrySecretMutex.Unlock()
+	fake.DeleteRegistrySecretStub = nil
+	if fake.deleteRegistrySecretReturnsOnCall == nil {
+		fake.deleteRegistrySecretReturnsOnCall = make(map[int]struct {
+			result1 bool
+			result2 error
+		})
+	}
+	fake.deleteRegistrySecretReturnsOnCall[i] = struct {
+		result1 bool
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) DeleteRepository(arg1 *tkgpackagedatamodel.RepositoryOptions, arg2 *tkgpackagedatamodel.PackageProgress) {
+	fake.deleteRepositoryMutex.Lock()
+	fake.deleteRepositoryArgsForCall = append(fake.deleteRepositoryArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+	}{arg1, arg2})
+	stub := fake.DeleteRepositoryStub
+	fake.recordInvocation("DeleteRepository", []interface{}{arg1, arg2})
+	fake.deleteRepositoryMutex.Unlock()
+	if stub != nil {
+		fake.DeleteRepositoryStub(arg1, arg2)
+	}
+}
+
+func (fake *TKGPackageClient) DeleteRepositoryCallCount() int {
+	fake.deleteRepositoryMutex.RLock()
+	defer fake.deleteRepositoryMutex.RUnlock()
+	return len(fake.deleteRepositoryArgsForCall)
+}
+
+func (fake *TKGPackageClient) DeleteRepositoryCalls(stub func(*tkgpackagedatamodel.RepositoryOptions, *tkgpackagedatamodel.PackageProgress)) {
+	fake.deleteRepositoryMutex.Lock()
+	defer fake.deleteRepositoryMutex.Unlock()
+	fake.DeleteRepositoryStub = stub
+}
+
+func (fake *TKGPackageClient) DeleteRepositoryArgsForCall(i int) (*tkgpackagedatamodel.RepositoryOptions, *tkgpackagedatamodel.PackageProgress) {
+	fake.deleteRepositoryMutex.RLock()
+	defer fake.deleteRepositoryMutex.RUnlock()
+	argsForCall := fake.deleteRepositoryArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2
+}
+
+func (fake *TKGPackageClient) DeleteRepositorySync(arg1 *tkgpackagedatamodel.RepositoryOptions) error {
+	fake.deleteRepositorySyncMutex.Lock()
+	ret, specificReturn := fake.deleteRepositorySyncReturnsOnCall[len(fake.deleteRepositorySyncArgsForCall)]
+	fake.deleteRepositorySyncArgsForCall = append(fake.deleteRepositorySyncArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+	}{arg1})
+	stub := fake.DeleteRepositorySyncStub
+	fakeReturns := fake.deleteRepositorySyncReturns
+	fake.recordInvocation("DeleteRepositorySync", []interface{}{arg1})
+	fake.deleteRepositorySyncMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	return fakeReturns.result1
+}
+
+func (fake *TKGPackageClient) DeleteRepositorySyncCallCount() int {
+	fake.deleteRepositorySyncMutex.RLock()
+	defer fake.deleteRepositorySyncMutex.RUnlock()
+	return len(fake.deleteRepositorySyncArgsForCall)
+}
+
+func (fake *TKGPackageClient) DeleteRepositorySyncCalls(stub func(*tkgpackagedatamodel.RepositoryOptions) error) {
+	fake.deleteRepositorySyncMutex.Lock()
+	defer fake.deleteRepositorySyncMutex.Unlock()
+	fake.DeleteRepositorySyncStub = stub
+}
+
+func (fake *TKGPackageClient) DeleteRepositorySyncArgsForCall(i int) *tkgpackagedatamodel.RepositoryOptions {
+	fake.deleteRepositorySyncMutex.RLock()
+	defer fake.deleteRepositorySyncMutex.RUnlock()
+	argsForCall := fake.deleteRepositorySyncArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) DeleteRepositorySyncReturns(result1 error) {
+	fake.deleteRepositorySyncMutex.Lock()
+	defer fake.deleteRepositorySyncMutex.Unlock()
+	fake.DeleteRepositorySyncStub = nil
+	fake.deleteRepositorySyncReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) DeleteRepositorySyncReturnsOnCall(i int, result1 error) {
+	fake.deleteRepositorySyncMutex.Lock()
+	defer fake.deleteRepositorySyncMutex.Unlock()
+	fake.DeleteRepositorySyncStub = nil
+	if fake.deleteRepositorySyncReturnsOnCall == nil {
+		fake.deleteRepositorySyncReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.deleteRepositorySyncReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) GetPackage(arg1 *tkgpackagedatamodel.PackageOptions) (*v1alpha1.PackageMetadata, *v1alpha1.Package, error) {
+	fake.getPackageMutex.Lock()
+	ret, specificReturn := fake.getPackageReturnsOnCall[len(fake.getPackageArgsForCall)]
+	fake.getPackageArgsForCall = append(fake.getPackageArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+	}{arg1})
+	stub := fake.GetPackageStub
+	fakeReturns := fake.getPackageReturns
+	fake.recordInvocation("GetPackage", []interface{}{arg1})
+	fake.getPackageMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2, ret.result3
+	}
+	return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3
+}
+
+func (fake *TKGPackageClient) GetPackageCallCount() int {
+	fake.getPackageMutex.RLock()
+	defer fake.getPackageMutex.RUnlock()
+	return len(fake.getPackageArgsForCall)
+}
+
+func (fake *TKGPackageClient) GetPackageCalls(stub func(*tkgpackagedatamodel.PackageOptions) (*v1alpha1.PackageMetadata, *v1alpha1.Package, error)) {
+	fake.getPackageMutex.Lock()
+	defer fake.getPackageMutex.Unlock()
+	fake.GetPackageStub = stub
+}
+
+func (fake *TKGPackageClient) GetPackageArgsForCall(i int) *tkgpackagedatamodel.PackageOptions {
+	fake.getPackageMutex.RLock()
+	defer fake.getPackageMutex.RUnlock()
+	argsForCall := fake.getPackageArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) GetPackageReturns(result1 *v1alpha1.PackageMetadata, result2 *v1alpha1.Package, result3 error) {
+	fake.getPackageMutex.Lock()
+	defer fake.getPackageMutex.Unlock()
+	fake.GetPackageStub = nil
+	fake.getPackageReturns = struct {
+		result1 *v1alpha1.PackageMetadata
+		result2 *v1alpha1.Package
+		result3 error
+	}{result1, result2, result3}
+}
+
+func (fake *TKGPackageClient) GetPackageReturnsOnCall(i int, result1 *v1alpha1.PackageMetadata, result2 *v1alpha1.Package, result3 error) {
+	fake.getPackageMutex.Lock()
+	defer fake.getPackageMutex.Unlock()
+	fake.GetPackageStub = nil
+	if fake.getPackageReturnsOnCall == nil {
+		fake.getPackageReturnsOnCall = make(map[int]struct {
+			result1 *v1alpha1.PackageMetadata
+			result2 *v1alpha1.Package
+			result3 error
+		})
+	}
+	fake.getPackageReturnsOnCall[i] = struct {
+		result1 *v1alpha1.PackageMetadata
+		result2 *v1alpha1.Package
+		result3 error
+	}{result1, result2, result3}
+}
+
+func (fake *TKGPackageClient) GetPackageInstall(arg1 *tkgpackagedatamodel.PackageOptions) (*v1alpha1a.PackageInstall, error) {
+	fake.getPackageInstallMutex.Lock()
+	ret, specificReturn := fake.getPackageInstallReturnsOnCall[len(fake.getPackageInstallArgsForCall)]
+	fake.getPackageInstallArgsForCall = append(fake.getPackageInstallArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+	}{arg1})
+	stub := fake.GetPackageInstallStub
+	fakeReturns := fake.getPackageInstallReturns
+	fake.recordInvocation("GetPackageInstall", []interface{}{arg1})
+	fake.getPackageInstallMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGPackageClient) GetPackageInstallCallCount() int {
+	fake.getPackageInstallMutex.RLock()
+	defer fake.getPackageInstallMutex.RUnlock()
+	return len(fake.getPackageInstallArgsForCall)
+}
+
+func (fake *TKGPackageClient) GetPackageInstallCalls(stub func(*tkgpackagedatamodel.PackageOptions) (*v1alpha1a.PackageInstall, error)) {
+	fake.getPackageInstallMutex.Lock()
+	defer fake.getPackageInstallMutex.Unlock()
+	fake.GetPackageInstallStub = stub
+}
+
+func (fake *TKGPackageClient) GetPackageInstallArgsForCall(i int) *tkgpackagedatamodel.PackageOptions {
+	fake.getPackageInstallMutex.RLock()
+	defer fake.getPackageInstallMutex.RUnlock()
+	argsForCall := fake.getPackageInstallArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) GetPackageInstallReturns(result1 *v1alpha1a.PackageInstall, result2 error) {
+	fake.getPackageInstallMutex.Lock()
+	defer fake.getPackageInstallMutex.Unlock()
+	fake.GetPackageInstallStub = nil
+	fake.getPackageInstallReturns = struct {
+		result1 *v1alpha1a.PackageInstall
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) GetPackageInstallReturnsOnCall(i int, result1 *v1alpha1a.PackageInstall, result2 error) {
+	fake.getPackageInstallMutex.Lock()
+	defer fake.getPackageInstallMutex.Unlock()
+	fake.GetPackageInstallStub = nil
+	if fake.getPackageInstallReturnsOnCall == nil {
+		fake.getPackageInstallReturnsOnCall = make(map[int]struct {
+			result1 *v1alpha1a.PackageInstall
+			result2 error
+		})
+	}
+	fake.getPackageInstallReturnsOnCall[i] = struct {
+		result1 *v1alpha1a.PackageInstall
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) GetRepository(arg1 *tkgpackagedatamodel.RepositoryOptions) (*v1alpha1a.PackageRepository, error) {
+	fake.getRepositoryMutex.Lock()
+	ret, specificReturn := fake.getRepositoryReturnsOnCall[len(fake.getRepositoryArgsForCall)]
+	fake.getRepositoryArgsForCall = append(fake.getRepositoryArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+	}{arg1})
+	stub := fake.GetRepositoryStub
+	fakeReturns := fake.getRepositoryReturns
+	fake.recordInvocation("GetRepository", []interface{}{arg1})
+	fake.getRepositoryMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGPackageClient) GetRepositoryCallCount() int {
+	fake.getRepositoryMutex.RLock()
+	defer fake.getRepositoryMutex.RUnlock()
+	return len(fake.getRepositoryArgsForCall)
+}
+
+func (fake *TKGPackageClient) GetRepositoryCalls(stub func(*tkgpackagedatamodel.RepositoryOptions) (*v1alpha1a.PackageRepository, error)) {
+	fake.getRepositoryMutex.Lock()
+	defer fake.getRepositoryMutex.Unlock()
+	fake.GetRepositoryStub = stub
+}
+
+func (fake *TKGPackageClient) GetRepositoryArgsForCall(i int) *tkgpackagedatamodel.RepositoryOptions {
+	fake.getRepositoryMutex.RLock()
+	defer fake.getRepositoryMutex.RUnlock()
+	argsForCall := fake.getRepositoryArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) GetRepositoryReturns(result1 *v1alpha1a.PackageRepository, result2 error) {
+	fake.getRepositoryMutex.Lock()
+	defer fake.getRepositoryMutex.Unlock()
+	fake.GetRepositoryStub = nil
+	fake.getRepositoryReturns = struct {
+		result1 *v1alpha1a.PackageRepository
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) GetRepositoryReturnsOnCall(i int, result1 *v1alpha1a.PackageRepository, result2 error) {
+	fake.getRepositoryMutex.Lock()
+	defer fake.getRepositoryMutex.Unlock()
+	fake.GetRepositoryStub = nil
+	if fake.getRepositoryReturnsOnCall == nil {
+		fake.getRepositoryReturnsOnCall = make(map[int]struct {
+			result1 *v1alpha1a.PackageRepository
+			result2 error
+		})
+	}
+	fake.getRepositoryReturnsOnCall[i] = struct {
+		result1 *v1alpha1a.PackageRepository
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) GetSecretExport(arg1 *tkgpackagedatamodel.RegistrySecretOptions) (*v1alpha1b.SecretExport, error) {
+	fake.getSecretExportMutex.Lock()
+	ret, specificReturn := fake.getSecretExportReturnsOnCall[len(fake.getSecretExportArgsForCall)]
+	fake.getSecretExportArgsForCall = append(fake.getSecretExportArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}{arg1})
+	stub := fake.GetSecretExportStub
+	fakeReturns := fake.getSecretExportReturns
+	fake.recordInvocation("GetSecretExport", []interface{}{arg1})
+	fake.getSecretExportMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGPackageClient) GetSecretExportCallCount() int {
+	fake.getSecretExportMutex.RLock()
+	defer fake.getSecretExportMutex.RUnlock()
+	return len(fake.getSecretExportArgsForCall)
+}
+
+func (fake *TKGPackageClient) GetSecretExportCalls(stub func(*tkgpackagedatamodel.RegistrySecretOptions) (*v1alpha1b.SecretExport, error)) {
+	fake.getSecretExportMutex.Lock()
+	defer fake.getSecretExportMutex.Unlock()
+	fake.GetSecretExportStub = stub
+}
+
+func (fake *TKGPackageClient) GetSecretExportArgsForCall(i int) *tkgpackagedatamodel.RegistrySecretOptions {
+	fake.getSecretExportMutex.RLock()
+	defer fake.getSecretExportMutex.RUnlock()
+	argsForCall := fake.getSecretExportArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) GetSecretExportReturns(result1 *v1alpha1b.SecretExport, result2 error) {
+	fake.getSecretExportMutex.Lock()
+	defer fake.getSecretExportMutex.Unlock()
+	fake.GetSecretExportStub = nil
+	fake.getSecretExportReturns = struct {
+		result1 *v1alpha1b.SecretExport
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) GetSecretExportReturnsOnCall(i int, result1 *v1alpha1b.SecretExport, result2 error) {
+	fake.getSecretExportMutex.Lock()
+	defer fake.getSecretExportMutex.Unlock()
+	fake.GetSecretExportStub = nil
+	if fake.getSecretExportReturnsOnCall == nil {
+		fake.getSecretExportReturnsOnCall = make(map[int]struct {
+			result1 *v1alpha1b.SecretExport
+			result2 error
+		})
+	}
+	fake.getSecretExportReturnsOnCall[i] = struct {
+		result1 *v1alpha1b.SecretExport
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) InstallPackage(arg1 *tkgpackagedatamodel.PackageOptions, arg2 *tkgpackagedatamodel.PackageProgress, arg3 tkgpackagedatamodel.OperationType) {
+	fake.installPackageMutex.Lock()
+	fake.installPackageArgsForCall = append(fake.installPackageArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+		arg3 tkgpackagedatamodel.OperationType
+	}{arg1, arg2, arg3})
+	stub := fake.InstallPackageStub
+	fake.recordInvocation("InstallPackage", []interface{}{arg1, arg2, arg3})
+	fake.installPackageMutex.Unlock()
+	if stub != nil {
+		fake.InstallPackageStub(arg1, arg2, arg3)
+	}
+}
+
+func (fake *TKGPackageClient) InstallPackageCallCount() int {
+	fake.installPackageMutex.RLock()
+	defer fake.installPackageMutex.RUnlock()
+	return len(fake.installPackageArgsForCall)
+}
+
+func (fake *TKGPackageClient) InstallPackageCalls(stub func(*tkgpackagedatamodel.PackageOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType)) {
+	fake.installPackageMutex.Lock()
+	defer fake.installPackageMutex.Unlock()
+	fake.InstallPackageStub = stub
+}
+
+func (fake *TKGPackageClient) InstallPackageArgsForCall(i int) (*tkgpackagedatamodel.PackageOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType) {
+	fake.installPackageMutex.RLock()
+	defer fake.installPackageMutex.RUnlock()
+	argsForCall := fake.installPackageArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3
+}
+
+func (fake *TKGPackageClient) InstallPackageSync(arg1 *tkgpackagedatamodel.PackageOptions, arg2 tkgpackagedatamodel.OperationType) error {
+	fake.installPackageSyncMutex.Lock()
+	ret, specificReturn := fake.installPackageSyncReturnsOnCall[len(fake.installPackageSyncArgsForCall)]
+	fake.installPackageSyncArgsForCall = append(fake.installPackageSyncArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+		arg2 tkgpackagedatamodel.OperationType
+	}{arg1, arg2})
+	stub := fake.InstallPackageSyncStub
+	fakeReturns := fake.installPackageSyncReturns
+	fake.recordInvocation("InstallPackageSync", []interface{}{arg1, arg2})
+	fake.installPackageSyncMutex.Unlock()
+	if stub != nil {
+		return stub(arg1, arg2)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	return fakeReturns.result1
+}
+
+func (fake *TKGPackageClient) InstallPackageSyncCallCount() int {
+	fake.installPackageSyncMutex.RLock()
+	defer fake.installPackageSyncMutex.RUnlock()
+	return len(fake.installPackageSyncArgsForCall)
+}
+
+func (fake *TKGPackageClient) InstallPackageSyncCalls(stub func(*tkgpackagedatamodel.PackageOptions, tkgpackagedatamodel.OperationType) error) {
+	fake.installPackageSyncMutex.Lock()
+	defer fake.installPackageSyncMutex.Unlock()
+	fake.InstallPackageSyncStub = stub
+}
+
+func (fake *TKGPackageClient) InstallPackageSyncArgsForCall(i int) (*tkgpackagedatamodel.PackageOptions, tkgpackagedatamodel.OperationType) {
+	fake.installPackageSyncMutex.RLock()
+	defer fake.installPackageSyncMutex.RUnlock()
+	argsForCall := fake.installPackageSyncArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2
+}
+
+func (fake *TKGPackageClient) InstallPackageSyncReturns(result1 error) {
+	fake.installPackageSyncMutex.Lock()
+	defer fake.installPackageSyncMutex.Unlock()
+	fake.InstallPackageSyncStub = nil
+	fake.installPackageSyncReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) InstallPackageSyncReturnsOnCall(i int, result1 error) {
+	fake.installPackageSyncMutex.Lock()
+	defer fake.installPackageSyncMutex.Unlock()
+	fake.InstallPackageSyncStub = nil
+	if fake.installPackageSyncReturnsOnCall == nil {
+		fake.installPackageSyncReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.installPackageSyncReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) ListPackageInstalls(arg1 *tkgpackagedatamodel.PackageOptions) (*v1alpha1a.PackageInstallList, error) {
+	fake.listPackageInstallsMutex.Lock()
+	ret, specificReturn := fake.listPackageInstallsReturnsOnCall[len(fake.listPackageInstallsArgsForCall)]
+	fake.listPackageInstallsArgsForCall = append(fake.listPackageInstallsArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+	}{arg1})
+	stub := fake.ListPackageInstallsStub
+	fakeReturns := fake.listPackageInstallsReturns
+	fake.recordInvocation("ListPackageInstalls", []interface{}{arg1})
+	fake.listPackageInstallsMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGPackageClient) ListPackageInstallsCallCount() int {
+	fake.listPackageInstallsMutex.RLock()
+	defer fake.listPackageInstallsMutex.RUnlock()
+	return len(fake.listPackageInstallsArgsForCall)
+}
+
+func (fake *TKGPackageClient) ListPackageInstallsCalls(stub func(*tkgpackagedatamodel.PackageOptions) (*v1alpha1a.PackageInstallList, error)) {
+	fake.listPackageInstallsMutex.Lock()
+	defer fake.listPackageInstallsMutex.Unlock()
+	fake.ListPackageInstallsStub = stub
+}
+
+func (fake *TKGPackageClient) ListPackageInstallsArgsForCall(i int) *tkgpackagedatamodel.PackageOptions {
+	fake.listPackageInstallsMutex.RLock()
+	defer fake.listPackageInstallsMutex.RUnlock()
+	argsForCall := fake.listPackageInstallsArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) ListPackageInstallsReturns(result1 *v1alpha1a.PackageInstallList, result2 error) {
+	fake.listPackageInstallsMutex.Lock()
+	defer fake.listPackageInstallsMutex.Unlock()
+	fake.ListPackageInstallsStub = nil
+	fake.listPackageInstallsReturns = struct {
+		result1 *v1alpha1a.PackageInstallList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListPackageInstallsReturnsOnCall(i int, result1 *v1alpha1a.PackageInstallList, result2 error) {
+	fake.listPackageInstallsMutex.Lock()
+	defer fake.listPackageInstallsMutex.Unlock()
+	fake.ListPackageInstallsStub = nil
+	if fake.listPackageInstallsReturnsOnCall == nil {
+		fake.listPackageInstallsReturnsOnCall = make(map[int]struct {
+			result1 *v1alpha1a.PackageInstallList
+			result2 error
+		})
+	}
+	fake.listPackageInstallsReturnsOnCall[i] = struct {
+		result1 *v1alpha1a.PackageInstallList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListPackageMetadata(arg1 *tkgpackagedatamodel.PackageAvailableOptions) (*v1alpha1.PackageMetadataList, error) {
+	fake.listPackageMetadataMutex.Lock()
+	ret, specificReturn := fake.listPackageMetadataReturnsOnCall[len(fake.listPackageMetadataArgsForCall)]
+	fake.listPackageMetadataArgsForCall = append(fake.listPackageMetadataArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageAvailableOptions
+	}{arg1})
+	stub := fake.ListPackageMetadataStub
+	fakeReturns := fake.listPackageMetadataReturns
+	fake.recordInvocation("ListPackageMetadata", []interface{}{arg1})
+	fake.listPackageMetadataMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGPackageClient) ListPackageMetadataCallCount() int {
+	fake.listPackageMetadataMutex.RLock()
+	defer fake.listPackageMetadataMutex.RUnlock()
+	return len(fake.listPackageMetadataArgsForCall)
+}
+
+func (fake *TKGPackageClient) ListPackageMetadataCalls(stub func(*tkgpackagedatamodel.PackageAvailableOptions) (*v1alpha1.PackageMetadataList, error)) {
+	fake.listPackageMetadataMutex.Lock()
+	defer fake.listPackageMetadataMutex.Unlock()
+	fake.ListPackageMetadataStub = stub
+}
+
+func (fake *TKGPackageClient) ListPackageMetadataArgsForCall(i int) *tkgpackagedatamodel.PackageAvailableOptions {
+	fake.listPackageMetadataMutex.RLock()
+	defer fake.listPackageMetadataMutex.RUnlock()
+	argsForCall := fake.listPackageMetadataArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) ListPackageMetadataReturns(result1 *v1alpha1.PackageMetadataList, result2 error) {
+	fake.listPackageMetadataMutex.Lock()
+	defer fake.listPackageMetadataMutex.Unlock()
+	fake.ListPackageMetadataStub = nil
+	fake.listPackageMetadataReturns = struct {
+		result1 *v1alpha1.PackageMetadataList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListPackageMetadataReturnsOnCall(i int, result1 *v1alpha1.PackageMetadataList, result2 error) {
+	fake.listPackageMetadataMutex.Lock()
+	defer fake.listPackageMetadataMutex.Unlock()
+	fake.ListPackageMetadataStub = nil
+	if fake.listPackageMetadataReturnsOnCall == nil {
+		fake.listPackageMetadataReturnsOnCall = make(map[int]struct {
+			result1 *v1alpha1.PackageMetadataList
+			result2 error
+		})
+	}
+	fake.listPackageMetadataReturnsOnCall[i] = struct {
+		result1 *v1alpha1.PackageMetadataList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListPackages(arg1 *tkgpackagedatamodel.PackageAvailableOptions) (*v1alpha1.PackageList, error) {
+	fake.listPackagesMutex.Lock()
+	ret, specificReturn := fake.listPackagesReturnsOnCall[len(fake.listPackagesArgsForCall)]
+	fake.listPackagesArgsForCall = append(fake.listPackagesArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageAvailableOptions
+	}{arg1})
+	stub := fake.ListPackagesStub
+	fakeReturns := fake.listPackagesReturns
+	fake.recordInvocation("ListPackages", []interface{}{arg1})
+	fake.listPackagesMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGPackageClient) ListPackagesCallCount() int {
+	fake.listPackagesMutex.RLock()
+	defer fake.listPackagesMutex.RUnlock()
+	return len(fake.listPackagesArgsForCall)
+}
+
+func (fake *TKGPackageClient) ListPackagesCalls(stub func(*tkgpackagedatamodel.PackageAvailableOptions) (*v1alpha1.PackageList, error)) {
+	fake.listPackagesMutex.Lock()
+	defer fake.listPackagesMutex.Unlock()
+	fake.ListPackagesStub = stub
+}
+
+func (fake *TKGPackageClient) ListPackagesArgsForCall(i int) *tkgpackagedatamodel.PackageAvailableOptions {
+	fake.listPackagesMutex.RLock()
+	defer fake.listPackagesMutex.RUnlock()
+	argsForCall := fake.listPackagesArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) ListPackagesReturns(result1 *v1alpha1.PackageList, result2 error) {
+	fake.listPackagesMutex.Lock()
+	defer fake.listPackagesMutex.Unlock()
+	fake.ListPackagesStub = nil
+	fake.listPackagesReturns = struct {
+		result1 *v1alpha1.PackageList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListPackagesReturnsOnCall(i int, result1 *v1alpha1.PackageList, result2 error) {
+	fake.listPackagesMutex.Lock()
+	defer fake.listPackagesMutex.Unlock()
+	fake.ListPackagesStub = nil
+	if fake.listPackagesReturnsOnCall == nil {
+		fake.listPackagesReturnsOnCall = make(map[int]struct {
+			result1 *v1alpha1.PackageList
+			result2 error
+		})
+	}
+	fake.listPackagesReturnsOnCall[i] = struct {
+		result1 *v1alpha1.PackageList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListRegistrySecrets(arg1 *tkgpackagedatamodel.RegistrySecretOptions) (*v1.SecretList, error) {
+	fake.listRegistrySecretsMutex.Lock()
+	ret, specificReturn := fake.listRegistrySecretsReturnsOnCall[len(fake.listRegistrySecretsArgsForCall)]
+	fake.listRegistrySecretsArgsForCall = append(fake.listRegistrySecretsArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}{arg1})
+	stub := fake.ListRegistrySecretsStub
+	fakeReturns := fake.listRegistrySecretsReturns
+	fake.recordInvocation("ListRegistrySecrets", []interface{}{arg1})
+	fake.listRegistrySecretsMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGPackageClient) ListRegistrySecretsCallCount() int {
+	fake.listRegistrySecretsMutex.RLock()
+	defer fake.listRegistrySecretsMutex.RUnlock()
+	return len(fake.listRegistrySecretsArgsForCall)
+}
+
+func (fake *TKGPackageClient) ListRegistrySecretsCalls(stub func(*tkgpackagedatamodel.RegistrySecretOptions) (*v1.SecretList, error)) {
+	fake.listRegistrySecretsMutex.Lock()
+	defer fake.listRegistrySecretsMutex.Unlock()
+	fake.ListRegistrySecretsStub = stub
+}
+
+func (fake *TKGPackageClient) ListRegistrySecretsArgsForCall(i int) *tkgpackagedatamodel.RegistrySecretOptions {
+	fake.listRegistrySecretsMutex.RLock()
+	defer fake.listRegistrySecretsMutex.RUnlock()
+	argsForCall := fake.listRegistrySecretsArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) ListRegistrySecretsReturns(result1 *v1.SecretList, result2 error) {
+	fake.listRegistrySecretsMutex.Lock()
+	defer fake.listRegistrySecretsMutex.Unlock()
+	fake.ListRegistrySecretsStub = nil
+	fake.listRegistrySecretsReturns = struct {
+		result1 *v1.SecretList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListRegistrySecretsReturnsOnCall(i int, result1 *v1.SecretList, result2 error) {
+	fake.listRegistrySecretsMutex.Lock()
+	defer fake.listRegistrySecretsMutex.Unlock()
+	fake.ListRegistrySecretsStub = nil
+	if fake.listRegistrySecretsReturnsOnCall == nil {
+		fake.listRegistrySecretsReturnsOnCall = make(map[int]struct {
+			result1 *v1.SecretList
+			result2 error
+		})
+	}
+	fake.listRegistrySecretsReturnsOnCall[i] = struct {
+		result1 *v1.SecretList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListRepositories(arg1 *tkgpackagedatamodel.RepositoryOptions) (*v1alpha1a.PackageRepositoryList, error) {
+	fake.listRepositoriesMutex.Lock()
+	ret, specificReturn := fake.listRepositoriesReturnsOnCall[len(fake.listRepositoriesArgsForCall)]
+	fake.listRepositoriesArgsForCall = append(fake.listRepositoriesArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+	}{arg1})
+	stub := fake.ListRepositoriesStub
+	fakeReturns := fake.listRepositoriesReturns
+	fake.recordInvocation("ListRepositories", []interface{}{arg1})
+	fake.listRepositoriesMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGPackageClient) ListRepositoriesCallCount() int {
+	fake.listRepositoriesMutex.RLock()
+	defer fake.listRepositoriesMutex.RUnlock()
+	return len(fake.listRepositoriesArgsForCall)
+}
+
+func (fake *TKGPackageClient) ListRepositoriesCalls(stub func(*tkgpackagedatamodel.RepositoryOptions) (*v1alpha1a.PackageRepositoryList, error)) {
+	fake.listRepositoriesMutex.Lock()
+	defer fake.listRepositoriesMutex.Unlock()
+	fake.ListRepositoriesStub = stub
+}
+
+func (fake *TKGPackageClient) ListRepositoriesArgsForCall(i int) *tkgpackagedatamodel.RepositoryOptions {
+	fake.listRepositoriesMutex.RLock()
+	defer fake.listRepositoriesMutex.RUnlock()
+	argsForCall := fake.listRepositoriesArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) ListRepositoriesReturns(result1 *v1alpha1a.PackageRepositoryList, result2 error) {
+	fake.listRepositoriesMutex.Lock()
+	defer fake.listRepositoriesMutex.Unlock()
+	fake.ListRepositoriesStub = nil
+	fake.listRepositoriesReturns = struct {
+		result1 *v1alpha1a.PackageRepositoryList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListRepositoriesReturnsOnCall(i int, result1 *v1alpha1a.PackageRepositoryList, result2 error) {
+	fake.listRepositoriesMutex.Lock()
+	defer fake.listRepositoriesMutex.Unlock()
+	fake.ListRepositoriesStub = nil
+	if fake.listRepositoriesReturnsOnCall == nil {
+		fake.listRepositoriesReturnsOnCall = make(map[int]struct {
+			result1 *v1alpha1a.PackageRepositoryList
+			result2 error
+		})
+	}
+	fake.listRepositoriesReturnsOnCall[i] = struct {
+		result1 *v1alpha1a.PackageRepositoryList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListSecretExports(arg1 *tkgpackagedatamodel.RegistrySecretOptions) (*v1alpha1b.SecretExportList, error) {
+	fake.listSecretExportsMutex.Lock()
+	ret, specificReturn := fake.listSecretExportsReturnsOnCall[len(fake.listSecretExportsArgsForCall)]
+	fake.listSecretExportsArgsForCall = append(fake.listSecretExportsArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}{arg1})
+	stub := fake.ListSecretExportsStub
+	fakeReturns := fake.listSecretExportsReturns
+	fake.recordInvocation("ListSecretExports", []interface{}{arg1})
+	fake.listSecretExportsMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *TKGPackageClient) ListSecretExportsCallCount() int {
+	fake.listSecretExportsMutex.RLock()
+	defer fake.listSecretExportsMutex.RUnlock()
+	return len(fake.listSecretExportsArgsForCall)
+}
+
+func (fake *TKGPackageClient) ListSecretExportsCalls(stub func(*tkgpackagedatamodel.RegistrySecretOptions) (*v1alpha1b.SecretExportList, error)) {
+	fake.listSecretExportsMutex.Lock()
+	defer fake.listSecretExportsMutex.Unlock()
+	fake.ListSecretExportsStub = stub
+}
+
+func (fake *TKGPackageClient) ListSecretExportsArgsForCall(i int) *tkgpackagedatamodel.RegistrySecretOptions {
+	fake.listSecretExportsMutex.RLock()
+	defer fake.listSecretExportsMutex.RUnlock()
+	argsForCall := fake.listSecretExportsArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) ListSecretExportsReturns(result1 *v1alpha1b.SecretExportList, result2 error) {
+	fake.listSecretExportsMutex.Lock()
+	defer fake.listSecretExportsMutex.Unlock()
+	fake.ListSecretExportsStub = nil
+	fake.listSecretExportsReturns = struct {
+		result1 *v1alpha1b.SecretExportList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) ListSecretExportsReturnsOnCall(i int, result1 *v1alpha1b.SecretExportList, result2 error) {
+	fake.listSecretExportsMutex.Lock()
+	defer fake.listSecretExportsMutex.Unlock()
+	fake.ListSecretExportsStub = nil
+	if fake.listSecretExportsReturnsOnCall == nil {
+		fake.listSecretExportsReturnsOnCall = make(map[int]struct {
+			result1 *v1alpha1b.SecretExportList
+			result2 error
+		})
+	}
+	fake.listSecretExportsReturnsOnCall[i] = struct {
+		result1 *v1alpha1b.SecretExportList
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *TKGPackageClient) UninstallPackage(arg1 *tkgpackagedatamodel.PackageOptions, arg2 *tkgpackagedatamodel.PackageProgress) {
+	fake.uninstallPackageMutex.Lock()
+	fake.uninstallPackageArgsForCall = append(fake.uninstallPackageArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+	}{arg1, arg2})
+	stub := fake.UninstallPackageStub
+	fake.recordInvocation("UninstallPackage", []interface{}{arg1, arg2})
+	fake.uninstallPackageMutex.Unlock()
+	if stub != nil {
+		fake.UninstallPackageStub(arg1, arg2)
+	}
+}
+
+func (fake *TKGPackageClient) UninstallPackageCallCount() int {
+	fake.uninstallPackageMutex.RLock()
+	defer fake.uninstallPackageMutex.RUnlock()
+	return len(fake.uninstallPackageArgsForCall)
+}
+
+func (fake *TKGPackageClient) UninstallPackageCalls(stub func(*tkgpackagedatamodel.PackageOptions, *tkgpackagedatamodel.PackageProgress)) {
+	fake.uninstallPackageMutex.Lock()
+	defer fake.uninstallPackageMutex.Unlock()
+	fake.UninstallPackageStub = stub
+}
+
+func (fake *TKGPackageClient) UninstallPackageArgsForCall(i int) (*tkgpackagedatamodel.PackageOptions, *tkgpackagedatamodel.PackageProgress) {
+	fake.uninstallPackageMutex.RLock()
+	defer fake.uninstallPackageMutex.RUnlock()
+	argsForCall := fake.uninstallPackageArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2
+}
+
+func (fake *TKGPackageClient) UninstallPackageSync(arg1 *tkgpackagedatamodel.PackageOptions) error {
+	fake.uninstallPackageSyncMutex.Lock()
+	ret, specificReturn := fake.uninstallPackageSyncReturnsOnCall[len(fake.uninstallPackageSyncArgsForCall)]
+	fake.uninstallPackageSyncArgsForCall = append(fake.uninstallPackageSyncArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+	}{arg1})
+	stub := fake.UninstallPackageSyncStub
+	fakeReturns := fake.uninstallPackageSyncReturns
+	fake.recordInvocation("UninstallPackageSync", []interface{}{arg1})
+	fake.uninstallPackageSyncMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	return fakeReturns.result1
+}
+
+func (fake *TKGPackageClient) UninstallPackageSyncCallCount() int {
+	fake.uninstallPackageSyncMutex.RLock()
+	defer fake.uninstallPackageSyncMutex.RUnlock()
+	return len(fake.uninstallPackageSyncArgsForCall)
+}
+
+func (fake *TKGPackageClient) UninstallPackageSyncCalls(stub func(*tkgpackagedatamodel.PackageOptions) error) {
+	fake.uninstallPackageSyncMutex.Lock()
+	defer fake.uninstallPackageSyncMutex.Unlock()
+	fake.UninstallPackageSyncStub = stub
+}
+
+func (fake *TKGPackageClient) UninstallPackageSyncArgsForCall(i int) *tkgpackagedatamodel.PackageOptions {
+	fake.uninstallPackageSyncMutex.RLock()
+	defer fake.uninstallPackageSyncMutex.RUnlock()
+	argsForCall := fake.uninstallPackageSyncArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) UninstallPackageSyncReturns(result1 error) {
+	fake.uninstallPackageSyncMutex.Lock()
+	defer fake.uninstallPackageSyncMutex.Unlock()
+	fake.UninstallPackageSyncStub = nil
+	fake.uninstallPackageSyncReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) UninstallPackageSyncReturnsOnCall(i int, result1 error) {
+	fake.uninstallPackageSyncMutex.Lock()
+	defer fake.uninstallPackageSyncMutex.Unlock()
+	fake.UninstallPackageSyncStub = nil
+	if fake.uninstallPackageSyncReturnsOnCall == nil {
+		fake.uninstallPackageSyncReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.uninstallPackageSyncReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) UpdatePackage(arg1 *tkgpackagedatamodel.PackageOptions, arg2 *tkgpackagedatamodel.PackageProgress, arg3 tkgpackagedatamodel.OperationType) {
+	fake.updatePackageMutex.Lock()
+	fake.updatePackageArgsForCall = append(fake.updatePackageArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+		arg3 tkgpackagedatamodel.OperationType
+	}{arg1, arg2, arg3})
+	stub := fake.UpdatePackageStub
+	fake.recordInvocation("UpdatePackage", []interface{}{arg1, arg2, arg3})
+	fake.updatePackageMutex.Unlock()
+	if stub != nil {
+		fake.UpdatePackageStub(arg1, arg2, arg3)
+	}
+}
+
+func (fake *TKGPackageClient) UpdatePackageCallCount() int {
+	fake.updatePackageMutex.RLock()
+	defer fake.updatePackageMutex.RUnlock()
+	return len(fake.updatePackageArgsForCall)
+}
+
+func (fake *TKGPackageClient) UpdatePackageCalls(stub func(*tkgpackagedatamodel.PackageOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType)) {
+	fake.updatePackageMutex.Lock()
+	defer fake.updatePackageMutex.Unlock()
+	fake.UpdatePackageStub = stub
+}
+
+func (fake *TKGPackageClient) UpdatePackageArgsForCall(i int) (*tkgpackagedatamodel.PackageOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType) {
+	fake.updatePackageMutex.RLock()
+	defer fake.updatePackageMutex.RUnlock()
+	argsForCall := fake.updatePackageArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3
+}
+
+func (fake *TKGPackageClient) UpdatePackageSync(arg1 *tkgpackagedatamodel.PackageOptions, arg2 tkgpackagedatamodel.OperationType) error {
+	fake.updatePackageSyncMutex.Lock()
+	ret, specificReturn := fake.updatePackageSyncReturnsOnCall[len(fake.updatePackageSyncArgsForCall)]
+	fake.updatePackageSyncArgsForCall = append(fake.updatePackageSyncArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.PackageOptions
+		arg2 tkgpackagedatamodel.OperationType
+	}{arg1, arg2})
+	stub := fake.UpdatePackageSyncStub
+	fakeReturns := fake.updatePackageSyncReturns
+	fake.recordInvocation("UpdatePackageSync", []interface{}{arg1, arg2})
+	fake.updatePackageSyncMutex.Unlock()
+	if stub != nil {
+		return stub(arg1, arg2)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	return fakeReturns.result1
+}
+
+func (fake *TKGPackageClient) UpdatePackageSyncCallCount() int {
+	fake.updatePackageSyncMutex.RLock()
+	defer fake.updatePackageSyncMutex.RUnlock()
+	return len(fake.updatePackageSyncArgsForCall)
+}
+
+func (fake *TKGPackageClient) UpdatePackageSyncCalls(stub func(*tkgpackagedatamodel.PackageOptions, tkgpackagedatamodel.OperationType) error) {
+	fake.updatePackageSyncMutex.Lock()
+	defer fake.updatePackageSyncMutex.Unlock()
+	fake.UpdatePackageSyncStub = stub
+}
+
+func (fake *TKGPackageClient) UpdatePackageSyncArgsForCall(i int) (*tkgpackagedatamodel.PackageOptions, tkgpackagedatamodel.OperationType) {
+	fake.updatePackageSyncMutex.RLock()
+	defer fake.updatePackageSyncMutex.RUnlock()
+	argsForCall := fake.updatePackageSyncArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2
+}
+
+func (fake *TKGPackageClient) UpdatePackageSyncReturns(result1 error) {
+	fake.updatePackageSyncMutex.Lock()
+	defer fake.updatePackageSyncMutex.Unlock()
+	fake.UpdatePackageSyncStub = nil
+	fake.updatePackageSyncReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) UpdatePackageSyncReturnsOnCall(i int, result1 error) {
+	fake.updatePackageSyncMutex.Lock()
+	defer fake.updatePackageSyncMutex.Unlock()
+	fake.UpdatePackageSyncStub = nil
+	if fake.updatePackageSyncReturnsOnCall == nil {
+		fake.updatePackageSyncReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.updatePackageSyncReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) UpdateRegistrySecret(arg1 *tkgpackagedatamodel.RegistrySecretOptions) error {
+	fake.updateRegistrySecretMutex.Lock()
+	ret, specificReturn := fake.updateRegistrySecretReturnsOnCall[len(fake.updateRegistrySecretArgsForCall)]
+	fake.updateRegistrySecretArgsForCall = append(fake.updateRegistrySecretArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RegistrySecretOptions
+	}{arg1})
+	stub := fake.UpdateRegistrySecretStub
+	fakeReturns := fake.updateRegistrySecretReturns
+	fake.recordInvocation("UpdateRegistrySecret", []interface{}{arg1})
+	fake.updateRegistrySecretMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	return fakeReturns.result1
+}
+
+func (fake *TKGPackageClient) UpdateRegistrySecretCallCount() int {
+	fake.updateRegistrySecretMutex.RLock()
+	defer fake.updateRegistrySecretMutex.RUnlock()
+	return len(fake.updateRegistrySecretArgsForCall)
+}
+
+func (fake *TKGPackageClient) UpdateRegistrySecretCalls(stub func(*tkgpackagedatamodel.RegistrySecretOptions) error) {
+	fake.updateRegistrySecretMutex.Lock()
+	defer fake.updateRegistrySecretMutex.Unlock()
+	fake.UpdateRegistrySecretStub = stub
+}
+
+func (fake *TKGPackageClient) UpdateRegistrySecretArgsForCall(i int) *tkgpackagedatamodel.RegistrySecretOptions {
+	fake.updateRegistrySecretMutex.RLock()
+	defer fake.updateRegistrySecretMutex.RUnlock()
+	argsForCall := fake.updateRegistrySecretArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *TKGPackageClient) UpdateRegistrySecretReturns(result1 error) {
+	fake.updateRegistrySecretMutex.Lock()
+	defer fake.updateRegistrySecretMutex.Unlock()
+	fake.UpdateRegistrySecretStub = nil
+	fake.updateRegistrySecretReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) UpdateRegistrySecretReturnsOnCall(i int, result1 error) {
+	fake.updateRegistrySecretMutex.Lock()
+	defer fake.updateRegistrySecretMutex.Unlock()
+	fake.UpdateRegistrySecretStub = nil
+	if fake.updateRegistrySecretReturnsOnCall == nil {
+		fake.updateRegistrySecretReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.updateRegistrySecretReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) UpdateRepository(arg1 *tkgpackagedatamodel.RepositoryOptions, arg2 *tkgpackagedatamodel.PackageProgress, arg3 tkgpackagedatamodel.OperationType) {
+	fake.updateRepositoryMutex.Lock()
+	fake.updateRepositoryArgsForCall = append(fake.updateRepositoryArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+		arg2 *tkgpackagedatamodel.PackageProgress
+		arg3 tkgpackagedatamodel.OperationType
+	}{arg1, arg2, arg3})
+	stub := fake.UpdateRepositoryStub
+	fake.recordInvocation("UpdateRepository", []interface{}{arg1, arg2, arg3})
+	fake.updateRepositoryMutex.Unlock()
+	if stub != nil {
+		fake.UpdateRepositoryStub(arg1, arg2, arg3)
+	}
+}
+
+func (fake *TKGPackageClient) UpdateRepositoryCallCount() int {
+	fake.updateRepositoryMutex.RLock()
+	defer fake.updateRepositoryMutex.RUnlock()
+	return len(fake.updateRepositoryArgsForCall)
+}
+
+func (fake *TKGPackageClient) UpdateRepositoryCalls(stub func(*tkgpackagedatamodel.RepositoryOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType)) {
+	fake.updateRepositoryMutex.Lock()
+	defer fake.updateRepositoryMutex.Unlock()
+	fake.UpdateRepositoryStub = stub
+}
+
+func (fake *TKGPackageClient) UpdateRepositoryArgsForCall(i int) (*tkgpackagedatamodel.RepositoryOptions, *tkgpackagedatamodel.PackageProgress, tkgpackagedatamodel.OperationType) {
+	fake.updateRepositoryMutex.RLock()
+	defer fake.updateRepositoryMutex.RUnlock()
+	argsForCall := fake.updateRepositoryArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3
+}
+
+func (fake *TKGPackageClient) UpdateRepositorySync(arg1 *tkgpackagedatamodel.RepositoryOptions, arg2 tkgpackagedatamodel.OperationType) error {
+	fake.updateRepositorySyncMutex.Lock()
+	ret, specificReturn := fake.updateRepositorySyncReturnsOnCall[len(fake.updateRepositorySyncArgsForCall)]
+	fake.updateRepositorySyncArgsForCall = append(fake.updateRepositorySyncArgsForCall, struct {
+		arg1 *tkgpackagedatamodel.RepositoryOptions
+		arg2 tkgpackagedatamodel.OperationType
+	}{arg1, arg2})
+	stub := fake.UpdateRepositorySyncStub
+	fakeReturns := fake.updateRepositorySyncReturns
+	fake.recordInvocation("UpdateRepositorySync", []interface{}{arg1, arg2})
+	fake.updateRepositorySyncMutex.Unlock()
+	if stub != nil {
+		return stub(arg1, arg2)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	return fakeReturns.result1
+}
+
+func (fake *TKGPackageClient) UpdateRepositorySyncCallCount() int {
+	fake.updateRepositorySyncMutex.RLock()
+	defer fake.updateRepositorySyncMutex.RUnlock()
+	return len(fake.updateRepositorySyncArgsForCall)
+}
+
+func (fake *TKGPackageClient) UpdateRepositorySyncCalls(stub func(*tkgpackagedatamodel.RepositoryOptions, tkgpackagedatamodel.OperationType) error) {
+	fake.updateRepositorySyncMutex.Lock()
+	defer fake.updateRepositorySyncMutex.Unlock()
+	fake.UpdateRepositorySyncStub = stub
+}
+
+func (fake *TKGPackageClient) UpdateRepositorySyncArgsForCall(i int) (*tkgpackagedatamodel.RepositoryOptions, tkgpackagedatamodel.OperationType) {
+	fake.updateRepositorySyncMutex.RLock()
+	defer fake.updateRepositorySyncMutex.RUnlock()
+	argsForCall := fake.updateRepositorySyncArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2
+}
+
+func (fake *TKGPackageClient) UpdateRepositorySyncReturns(result1 error) {
+	fake.updateRepositorySyncMutex.Lock()
+	defer fake.updateRepositorySyncMutex.Unlock()
+	fake.UpdateRepositorySyncStub = nil
+	fake.updateRepositorySyncReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) UpdateRepositorySyncReturnsOnCall(i int, result1 error) {
+	fake.updateRepositorySyncMutex.Lock()
+	defer fake.updateRepositorySyncMutex.Unlock()
+	fake.UpdateRepositorySyncStub = nil
+	if fake.updateRepositorySyncReturnsOnCall == nil {
+		fake.updateRepositorySyncReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.updateRepositorySyncReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *TKGPackageClient) Invocations() map[string][][]interface{} {
+	fake.invocationsMutex.RLock()
+	defer fake.invocationsMutex.RUnlock()
+	fake.addRegistrySecretMutex.RLock()
+	defer fake.addRegistrySecretMutex.RUnlock()
+	fake.addRepositoryMutex.RLock()
+	defer fake.addRepositoryMutex.RUnlock()
+	fake.addRepositorySyncMutex.RLock()
+	defer fake.addRepositorySyncMutex.RUnlock()
+	fake.deleteRegistrySecretMutex.RLock()
+	defer fake.deleteRegistrySecretMutex.RUnlock()
+	fake.deleteRepositoryMutex.RLock()
+	defer fake.deleteRepositoryMutex.RUnlock()
+	fake.deleteRepositorySyncMutex.RLock()
+	defer fake.deleteRepositorySyncMutex.RUnlock()
+	fake.getPackageMutex.RLock()
+	defer fake.getPackageMutex.RUnlock()
+	fake.getPackageInstallMutex.RLock()
+	defer fake.getPackageInstallMutex.RUnlock()
+	fake.getRepositoryMutex.RLock()
+	defer fake.getRepositoryMutex.RUnlock()
+	fake.getSecretExportMutex.RLock()
+	defer fake.getSecretExportMutex.RUnlock()
+	fake.installPackageMutex.RLock()
+	defer fake.installPackageMutex.RUnlock()
+	fake.installPackageSyncMutex.RLock()
+	defer fake.installPackageSyncMutex.RUnlock()
+	fake.listPackageInstallsMutex.RLock()
+	defer fake.listPackageInstallsMutex.RUnlock()
+	fake.listPackageMetadataMutex.RLock()
+	defer fake.listPackageMetadataMutex.RUnlock()
+	fake.listPackagesMutex.RLock()
+	defer fake.listPackagesMutex.RUnlock()
+	fake.listRegistrySecretsMutex.RLock()
+	defer fake.listRegistrySecretsMutex.RUnlock()
+	fake.listRepositoriesMutex.RLock()
+	defer fake.listRepositoriesMutex.RUnlock()
+	fake.listSecretExportsMutex.RLock()
+	defer fake.listSecretExportsMutex.RUnlock()
+	fake.uninstallPackageMutex.RLock()
+	defer fake.uninstallPackageMutex.RUnlock()
+	fake.uninstallPackageSyncMutex.RLock()
+	defer fake.uninstallPackageSyncMutex.RUnlock()
+	fake.updatePackageMutex.RLock()
+	defer fake.updatePackageMutex.RUnlock()
+	fake.updatePackageSyncMutex.RLock()
+	defer fake.updatePackageSyncMutex.RUnlock()
+	fake.updateRegistrySecretMutex.RLock()
+	defer fake.updateRegistrySecretMutex.RUnlock()
+	fake.updateRepositoryMutex.RLock()
+	defer fake.updateRepositoryMutex.RUnlock()
+	fake.updateRepositorySyncMutex.RLock()
+	defer fake.updateRepositorySyncMutex.RUnlock()
+	copiedInvocations := map[string][][]interface{}{}
+	for key, value := range fake.invocations {
+		copiedInvocations[key] = value
+	}
+	return copiedInvocations
+}
+
+func (fake *TKGPackageClient) recordInvocation(key string, args []interface{}) {
+	fake.invocationsMutex.Lock()
+	defer fake.invocationsMutex.Unlock()
+	if fake.invocations == nil {
+		fake.invocations = map[string][][]interface{}{}
+	}
+	if fake.invocations[key] == nil {
+		fake.invocations[key] = [][]interface{}{}
+	}
+	fake.invocations[key] = append(fake.invocations[key], args)
+}
+
+var _ tkgpackageclient.TKGPackageClient = new(TKGPackageClient)
diff --git a/pkg/v1/tkg/managementcomponents/helper.go b/pkg/v1/tkg/managementcomponents/helper.go
new file mode 100644
index 0000000000..e7aeab1b56
--- /dev/null
+++ b/pkg/v1/tkg/managementcomponents/helper.go
@@ -0,0 +1,45 @@
+// Copyright 2021 VMware, Inc. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+// Package managementcomponents implements management component installation helpers
+package managementcomponents
+
+import (
+	"time"
+
+	"gopkg.in/yaml.v3"
+
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/constants"
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/utils"
+)
+
+const (
+	packagePollInterval = 5 * time.Second
+	packagePollTimeout  = 10 * time.Minute
+)
+
+// GetTKGPackageConfigValuesFileFromUserConfig returns values file from user configuration
+func GetTKGPackageConfigValuesFileFromUserConfig(userProviderConfigValues map[string]string) (string, error) {
+	tkgPackageConfig := TKGPackageConfig{
+		Metadata: Metadata{
+			InfraProvider: userProviderConfigValues[constants.ConfigVariableProviderType],
+		},
+		ConfigValues: userProviderConfigValues,
+	}
+
+	configBytes, err := yaml.Marshal(tkgPackageConfig)
+	if err != nil {
+		return "", err
+	}
+
+	valuesFile, err := utils.CreateTempFile("", "")
+	if err != nil {
+		return "", err
+	}
+
+	err = utils.WriteToFile(valuesFile, configBytes)
+	if err != nil {
+		return "", err
+	}
+	return valuesFile, nil
+}
diff --git a/pkg/v1/tkg/managementcomponents/management_component_install.go b/pkg/v1/tkg/managementcomponents/management_component_install.go
new file mode 100644
index 0000000000..d53fb3f113
--- /dev/null
+++ b/pkg/v1/tkg/managementcomponents/management_component_install.go
@@ -0,0 +1,117 @@
+// Copyright 2021 VMware, Inc. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package managementcomponents
+
+import (
+	"github.com/pkg/errors"
+
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/clusterclient"
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/constants"
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
+)
+
+// ClusterOptions specifies cluster configuration
+type ClusterOptions struct {
+	Kubeconfig  string
+	Kubecontext string
+}
+
+// ManagementPackageRepositoryOptions specifies management package repository deployment options
+type ManagementPackageRepositoryOptions struct {
+	ManagementPackageRepoImage string
+	TKGPackageValuesFile       string
+}
+
+// KappControllerOptions specifies kapp-controller deployment options
+type KappControllerOptions struct {
+	KappControllerConfigFile       string
+	KappControllerInstallNamespace string
+}
+
+// ManagementComponentsInstallOptions specifies install options for management components
+type ManagementComponentsInstallOptions struct {
+	ClusterOptions                     ClusterOptions
+	ManagementPackageRepositoryOptions ManagementPackageRepositoryOptions
+	KappControllerOptions              KappControllerOptions
+}
+
+// InstallManagementComponents installs the management component to cluster
+func InstallManagementComponents(mcip *ManagementComponentsInstallOptions) error {
+	clusterClient, err := clusterclient.NewClient(mcip.ClusterOptions.Kubeconfig, mcip.ClusterOptions.Kubecontext, clusterclient.Options{})
+	if err != nil {
+		return errors.Wrap(err, "unable to get cluster client")
+	}
+	if err := InstallKappController(clusterClient, mcip.KappControllerOptions); err != nil {
+		return errors.Wrap(err, "unable to install kapp-controller")
+	}
+
+	// create package client
+	pkgClient, err := tkgpackageclient.NewTKGPackageClientForContext(mcip.ClusterOptions.Kubeconfig, mcip.ClusterOptions.Kubecontext)
+	if err != nil {
+		return err
+	}
+	if err = InstallManagementPackages(pkgClient, mcip.ManagementPackageRepositoryOptions); err != nil {
+		return errors.Wrap(err, "unable to install management packages")
+	}
+	return nil
+}
+
+// InstallKappController installs kapp-controller to the cluster
+func InstallKappController(clusterClient clusterclient.Client, kappControllerOptions KappControllerOptions) error {
+	// Apply kapp-controller configuration
+	err := clusterClient.ApplyFile(kappControllerOptions.KappControllerConfigFile)
+	if err != nil {
+		return errors.Wrapf(err, "error installing %s", constants.KappControllerDeploymentName)
+	}
+	// Wait for kapp-controller to be deployed and running
+	err = clusterClient.WaitForDeployment(constants.KappControllerDeploymentName, kappControllerOptions.KappControllerInstallNamespace)
+	if err != nil {
+		return errors.Wrapf(err, "error while waiting for deployment %s", constants.KappControllerDeploymentName)
+	}
+	return nil
+}
+
+// InstallManagementPackages installs TKG management packages to the cluster
+func InstallManagementPackages(pkgClient tkgpackageclient.TKGPackageClient, mpro ManagementPackageRepositoryOptions) error {
+	// install management package repository
+	err := installManagementPackageRepository(pkgClient, mpro)
+	if err != nil {
+		return err
+	}
+
+	// install tkg composite management package
+	err = installTKGManagementPackage(pkgClient, mpro)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func installManagementPackageRepository(pkgClient tkgpackageclient.TKGPackageClient, mpro ManagementPackageRepositoryOptions) error {
+	repositoryOptions := tkgpackagedatamodel.NewRepositoryOptions()
+	repositoryOptions.RepositoryName = constants.TKGManagementPackageRepositoryName
+	repositoryOptions.RepositoryURL = mpro.ManagementPackageRepoImage
+	repositoryOptions.Namespace = constants.TkgNamespace
+	repositoryOptions.CreateRepository = true
+	repositoryOptions.Wait = true
+	repositoryOptions.PollInterval = packagePollInterval
+	repositoryOptions.PollTimeout = packagePollTimeout
+
+	return pkgClient.UpdateRepositorySync(repositoryOptions, tkgpackagedatamodel.OperationTypeInstall)
+}
+
+func installTKGManagementPackage(pkgClient tkgpackageclient.TKGPackageClient, mpro ManagementPackageRepositoryOptions) error {
+	packageOptions := tkgpackagedatamodel.NewPackageOptions()
+	packageOptions.PackageName = constants.TKGManagementPackageName
+	packageOptions.PkgInstallName = constants.TKGManagementPackageInstallName
+	packageOptions.Namespace = constants.TkgNamespace
+	packageOptions.Install = true
+	packageOptions.Wait = true
+	packageOptions.PollInterval = packagePollInterval
+	packageOptions.PollTimeout = packagePollTimeout
+	packageOptions.ValuesFile = mpro.TKGPackageValuesFile
+	return pkgClient.InstallPackageSync(packageOptions, tkgpackagedatamodel.OperationTypeInstall)
+}
diff --git a/pkg/v1/tkg/managementcomponents/types.go b/pkg/v1/tkg/managementcomponents/types.go
new file mode 100644
index 0000000000..098026b17b
--- /dev/null
+++ b/pkg/v1/tkg/managementcomponents/types.go
@@ -0,0 +1,15 @@
+// Copyright 2021 VMware, Inc. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package managementcomponents
+
+// TKGPackageConfig defines TKG package configuration
+type TKGPackageConfig struct {
+	Metadata     Metadata          `yaml:"metadata"`
+	ConfigValues map[string]string `yaml:"configvalues"`
+}
+
+// Metadata specifies metadata as part of TKG package config
+type Metadata struct {
+	InfraProvider string `yaml:"infraProvider"`
+}
diff --git a/pkg/v1/tkg/tkgconfigbom/bom.go b/pkg/v1/tkg/tkgconfigbom/bom.go
index cc0fcbe3c8..46b55d61b6 100644
--- a/pkg/v1/tkg/tkgconfigbom/bom.go
+++ b/pkg/v1/tkg/tkgconfigbom/bom.go
@@ -652,3 +652,24 @@ func (c *client) getDefaultBOMFileImagePathAndTagFromCompatabilityFile() (string
 	}
 	return "", "", errors.Errorf("unable to find the supported TKG BOM version for the management plugin version %q in the TKG Compatibility file %q", tkgconfigpaths.TKGManagementClusterPluginVersion, compatibilityFile)
 }
+
+// GetManagementPackageRepositoryImage returns management package repository image
+func (c *client) GetManagementPackageRepositoryImage() (string, error) {
+	bomConfiguration, err := c.GetDefaultTkgBOMConfiguration()
+	if err != nil {
+		return "", err
+	}
+
+	tfmpComponent, ok := bomConfiguration.Components["tanzu-framework-management-packages"]
+	if !ok || len(tfmpComponent) == 0 {
+		return "", errors.New("unable to find 'tanzu-framework-management-packages' component in BoM file")
+	}
+
+	tfmprImage, ok := tfmpComponent[0].Images["tanzuFrameworkManagementPackageRepositoryImage"]
+	if !ok || tfmprImage == nil {
+		return "", errors.New("unable to find 'tanzuFrameworkManagementPackageRepositoryImage' image in BoM file")
+	}
+
+	managementPackageRepositoryImage := fmt.Sprintf("%s/%s:%s", bomConfiguration.ImageConfig.ImageRepository, tfmprImage.ImagePath, tfmprImage.Tag)
+	return managementPackageRepositoryImage, nil
+}
diff --git a/pkg/v1/tkg/tkgconfigbom/client.go b/pkg/v1/tkg/tkgconfigbom/client.go
index 10595d6d85..34d651e257 100644
--- a/pkg/v1/tkg/tkgconfigbom/client.go
+++ b/pkg/v1/tkg/tkgconfigbom/client.go
@@ -64,6 +64,8 @@ type Client interface {
 	GetDefaultBoMFilePath() (string, error)
 	// GetDefaultBoMFileName returns name of default BoM file
 	GetDefaultBoMFileName() (string, error)
+	// GetManagementPackageRepositoryImage returns management package repository image
+	GetManagementPackageRepositoryImage() (string, error)
 }
 
 func (c *client) TKGConfigReaderWriter() tkgconfigreaderwriter.TKGConfigReaderWriter {
diff --git a/pkg/v1/tkg/tkgconfigpaths/client.go b/pkg/v1/tkg/tkgconfigpaths/client.go
index f494b50977..d7d50f221b 100644
--- a/pkg/v1/tkg/tkgconfigpaths/client.go
+++ b/pkg/v1/tkg/tkgconfigpaths/client.go
@@ -46,4 +46,7 @@ type Client interface {
 
 	// GetTKGCompatibilityConfigPath returns TKG compatibility file path
 	GetTKGCompatibilityConfigPath() (string, error)
+
+	// GetConfigDefaultsFilePath returns config_default.yaml file path under TKG directory
+	GetConfigDefaultsFilePath() (string, error)
 }
diff --git a/pkg/v1/tkg/tkgconfigpaths/filepaths.go b/pkg/v1/tkg/tkgconfigpaths/filepaths.go
index f846acca77..7bfa230bc2 100644
--- a/pkg/v1/tkg/tkgconfigpaths/filepaths.go
+++ b/pkg/v1/tkg/tkgconfigpaths/filepaths.go
@@ -124,3 +124,12 @@ func GetRegistryTrustedCACertFileForWindows() (string, error) {
 	}
 	return path.Join(home, constants.TKGRegistryTrustedRootCAFileForWindows), nil
 }
+
+// GetConfigDefaultsFilePath returns config_default.yaml file path under TKG directory
+func (c *client) GetConfigDefaultsFilePath() (string, error) {
+	tkgDir, err := c.GetTKGProvidersDirectory()
+	if err != nil {
+		return "", err
+	}
+	return filepath.Join(tkgDir, constants.TKGConfigDefaultFileName), nil
+}
diff --git a/pkg/v1/tkg/tkgpackageclient/client.go b/pkg/v1/tkg/tkgpackageclient/client.go
index 7a2842f32c..1ef8967c67 100644
--- a/pkg/v1/tkg/tkgpackageclient/client.go
+++ b/pkg/v1/tkg/tkgpackageclient/client.go
@@ -27,3 +27,9 @@ func NewTKGPackageClientForContext(kubeconfigPath, kubeContext string) (TKGPacka
 
 	return client, nil
 }
+
+func NewTKGPackageClientWithKappClient(kappClient kappclient.Client) (TKGPackageClient, error) {
+	return &pkgClient{
+		kappClient: kappClient,
+	}, nil
+}
diff --git a/pkg/v1/tkg/tkgpackageclient/image_utils.go b/pkg/v1/tkg/tkgpackageclient/image_utils.go
index 86885ec447..689d7d150b 100644
--- a/pkg/v1/tkg/tkgpackageclient/image_utils.go
+++ b/pkg/v1/tkg/tkgpackageclient/image_utils.go
@@ -15,8 +15,8 @@ import (
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
-// parseRegistryImageURL parses the registry image URL to get repository and tag, tag is empty if not specified
-func parseRegistryImageURL(imgURL string) (repository, tag string, err error) {
+// ParseRegistryImageURL parses the registry image URL to get repository and tag, tag is empty if not specified
+func ParseRegistryImageURL(imgURL string) (repository, tag string, err error) {
 	ref, err := name.ParseReference(imgURL, name.WeakValidation)
 	if err != nil {
 		return "", "", err
@@ -37,7 +37,7 @@ func GetCurrentRepositoryAndTagInUse(pkgr *kappipkg.PackageRepository) (reposito
 		return "", "", errors.New("failed to find OCI registry URL")
 	}
 
-	repository, tag, err = parseRegistryImageURL(pkgr.Spec.Fetch.ImgpkgBundle.Image)
+	repository, tag, err = ParseRegistryImageURL(pkgr.Spec.Fetch.ImgpkgBundle.Image)
 	if err != nil {
 		return "", "", errors.Wrap(err, "failed to parse OCI registry URL")
 	}
diff --git a/pkg/v1/tkg/tkgpackageclient/interface.go b/pkg/v1/tkg/tkgpackageclient/interface.go
index bf75c3cc96..83691ef684 100644
--- a/pkg/v1/tkg/tkgpackageclient/interface.go
+++ b/pkg/v1/tkg/tkgpackageclient/interface.go
@@ -14,6 +14,8 @@ import (
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
+//go:generate counterfeiter -o ../fakes/tkgpackageclient.go --fake-name TKGPackageClient . TKGPackageClient
+
 // TKGPackageClient is the TKG package client interface
 type TKGPackageClient interface {
 	AddRegistrySecret(o *tkgpackagedatamodel.RegistrySecretOptions) error
diff --git a/pkg/v1/tkg/tkgpackageclient/package_install.go b/pkg/v1/tkg/tkgpackageclient/package_install.go
index 6f18251234..de17fe40a2 100644
--- a/pkg/v1/tkg/tkgpackageclient/package_install.go
+++ b/pkg/v1/tkg/tkgpackageclient/package_install.go
@@ -233,7 +233,7 @@ func (p *pkgClient) createOrUpdateDataValuesSecret(o *tkgpackagedatamodel.Packag
 	if dataValues[filepath.Base(o.ValuesFile)], err = os.ReadFile(o.ValuesFile); err != nil {
 		return false, errors.Wrap(err, fmt.Sprintf("failed to read from data values file '%s'", o.ValuesFile))
 	}
-	secret = &corev1.Secret{
+	Secret = &corev1.Secret{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:        o.SecretName,
 			Namespace:   o.Namespace,
@@ -242,9 +242,9 @@ func (p *pkgClient) createOrUpdateDataValuesSecret(o *tkgpackagedatamodel.Packag
 		Data: dataValues,
 	}
 
-	if err := p.kappClient.GetClient().Create(context.Background(), secret); err != nil {
+	if err := p.kappClient.GetClient().Create(context.Background(), Secret); err != nil {
 		if k8serror.IsAlreadyExists(err) {
-			if err := p.kappClient.GetClient().Update(context.Background(), secret); err != nil {
+			if err := p.kappClient.GetClient().Update(context.Background(), Secret); err != nil {
 				return false, err
 			}
 		} else {
diff --git a/pkg/v1/tkg/tkgpackageclient/package_update.go b/pkg/v1/tkg/tkgpackageclient/package_update.go
index 581b26314c..c114820805 100644
--- a/pkg/v1/tkg/tkgpackageclient/package_update.go
+++ b/pkg/v1/tkg/tkgpackageclient/package_update.go
@@ -187,11 +187,11 @@ func (p *pkgClient) updateDataValuesSecret(o *tkgpackagedatamodel.PackageOptions
 	if dataValues[filepath.Base(o.ValuesFile)], err = os.ReadFile(o.ValuesFile); err != nil {
 		return errors.Wrap(err, fmt.Sprintf("failed to read from data values file '%s'", o.ValuesFile))
 	}
-	secret = &corev1.Secret{
+	Secret = &corev1.Secret{
 		ObjectMeta: metav1.ObjectMeta{Name: o.SecretName, Namespace: o.Namespace}, Data: dataValues,
 	}
 
-	if err := p.kappClient.GetClient().Update(context.Background(), secret); err != nil {
+	if err := p.kappClient.GetClient().Update(context.Background(), Secret); err != nil {
 		return errors.Wrap(err, "failed to update Secret resource")
 	}
 
diff --git a/pkg/v1/tkg/tkgpackageclient/registry_secret_add.go b/pkg/v1/tkg/tkgpackageclient/registry_secret_add.go
index 0c9171b19e..976b771715 100644
--- a/pkg/v1/tkg/tkgpackageclient/registry_secret_add.go
+++ b/pkg/v1/tkg/tkgpackageclient/registry_secret_add.go
@@ -20,31 +20,31 @@ import (
 // Note: datapolicy is seemingly used for log sanitization: https://github.com/kubernetes/enhancements/blob/master/keps/sig-security/1933-secret-logging-static-analysis/README.md
 // TODO: change to use k8s types after upgrading the K8s version
 type DockerConfigJSON struct {
-	Auths map[string]dockerConfigEntry `json:"auths" datapolicy:"token"`
+	Auths map[string]DockerConfigEntry `json:"auths" datapolicy:"token"`
 }
 
-type dockerConfigEntry struct {
+type DockerConfigEntry struct {
 	Username string `json:"username,omitempty"`
 	Password string `json:"password,omitempty" datapolicy:"password"`
 }
 
 // AddRegistrySecret adds a registry secret to the cluster
 func (p *pkgClient) AddRegistrySecret(o *tkgpackagedatamodel.RegistrySecretOptions) error {
-	dockerCfg := DockerConfigJSON{Auths: map[string]dockerConfigEntry{o.Server: {Username: o.Username, Password: o.Password}}}
+	dockerCfg := DockerConfigJSON{Auths: map[string]DockerConfigEntry{o.Server: {Username: o.Username, Password: o.Password}}}
 	dockerCfgContent, err := json.Marshal(dockerCfg)
 	if err != nil {
 		return err
 	}
 
-	secret = p.newSecret(o.SecretName, o.Namespace, corev1.SecretTypeDockerConfigJson)
-	secret.Data[corev1.DockerConfigJsonKey] = dockerCfgContent
-	if err := p.kappClient.GetClient().Create(context.Background(), secret); err != nil {
+	Secret = p.newSecret(o.SecretName, o.Namespace, corev1.SecretTypeDockerConfigJson)
+	Secret.Data[corev1.DockerConfigJsonKey] = dockerCfgContent
+	if err := p.kappClient.GetClient().Create(context.Background(), Secret); err != nil {
 		return errors.Wrap(err, "failed to create Secret resource")
 	}
 
 	if o.ExportToAllNamespaces {
-		secretExport = p.newSecretExport(o.SecretName, o.Namespace)
-		if err := p.kappClient.GetClient().Create(context.Background(), secretExport); err != nil {
+		SecretExport = p.newSecretExport(o.SecretName, o.Namespace)
+		if err := p.kappClient.GetClient().Create(context.Background(), SecretExport); err != nil {
 			return errors.Wrap(err, "failed to create SecretExport resource")
 		}
 	}
diff --git a/pkg/v1/tkg/tkgpackageclient/registry_secret_delete.go b/pkg/v1/tkg/tkgpackageclient/registry_secret_delete.go
index 53d000f3ff..28a40ffb9e 100644
--- a/pkg/v1/tkg/tkgpackageclient/registry_secret_delete.go
+++ b/pkg/v1/tkg/tkgpackageclient/registry_secret_delete.go
@@ -18,21 +18,21 @@ import (
 
 // DeleteRegistrySecret deletes a registry secret from the cluster
 func (p *pkgClient) DeleteRegistrySecret(o *tkgpackagedatamodel.RegistrySecretOptions) (bool, error) {
-	secretExport = &secretgenctrl.SecretExport{
+	SecretExport = &secretgenctrl.SecretExport{
 		TypeMeta:   metav1.TypeMeta{Kind: tkgpackagedatamodel.KindSecretExport, APIVersion: secretgenctrl.SchemeGroupVersion.String()},
 		ObjectMeta: metav1.ObjectMeta{Name: o.SecretName, Namespace: o.Namespace},
 	}
-	if err := p.kappClient.GetClient().Delete(context.Background(), secretExport); err != nil {
+	if err := p.kappClient.GetClient().Delete(context.Background(), SecretExport); err != nil {
 		if !apierrors.IsNotFound(err) {
 			return true, errors.Wrap(err, "failed to delete SecretExport resource")
 		}
 	}
 
-	secret = &corev1.Secret{
+	Secret = &corev1.Secret{
 		TypeMeta:   metav1.TypeMeta{Kind: tkgpackagedatamodel.KindSecret, APIVersion: corev1.SchemeGroupVersion.String()},
 		ObjectMeta: metav1.ObjectMeta{Name: o.SecretName, Namespace: o.Namespace},
 	}
-	if err := p.kappClient.GetClient().Delete(context.Background(), secret); err != nil {
+	if err := p.kappClient.GetClient().Delete(context.Background(), Secret); err != nil {
 		if !apierrors.IsNotFound(err) {
 			return true, errors.Wrap(err, "failed to delete Secret resource")
 		}
diff --git a/pkg/v1/tkg/tkgpackageclient/registry_secret_list.go b/pkg/v1/tkg/tkgpackageclient/registry_secret_list.go
index eab2d18709..04f465854b 100644
--- a/pkg/v1/tkg/tkgpackageclient/registry_secret_list.go
+++ b/pkg/v1/tkg/tkgpackageclient/registry_secret_list.go
@@ -35,10 +35,10 @@ func (p *pkgClient) ListSecretExports(o *tkgpackagedatamodel.RegistrySecretOptio
 // GetSecretExport gets the SecretExport having the same name and namespace as specified secret.
 func (p *pkgClient) GetSecretExport(o *tkgpackagedatamodel.RegistrySecretOptions) (*secretgenctrl.SecretExport, error) {
 	var err error
-	secretExport, err = p.kappClient.GetSecretExport(o.SecretName, o.Namespace)
+	SecretExport, err = p.kappClient.GetSecretExport(o.SecretName, o.Namespace)
 	if err != nil {
 		return nil, errors.Wrap(err, "failed to get existing secret export in the cluster")
 	}
 
-	return secretExport, nil
+	return SecretExport, nil
 }
diff --git a/pkg/v1/tkg/tkgpackageclient/registry_secret_update.go b/pkg/v1/tkg/tkgpackageclient/registry_secret_update.go
index 2af253133f..641e3c2bf3 100644
--- a/pkg/v1/tkg/tkgpackageclient/registry_secret_update.go
+++ b/pkg/v1/tkg/tkgpackageclient/registry_secret_update.go
@@ -19,20 +19,20 @@ import (
 )
 
 var (
-	secret       = &corev1.Secret{}
-	secretExport = &secretgenctrl.SecretExport{}
+	Secret       = &corev1.Secret{}
+	SecretExport = &secretgenctrl.SecretExport{}
 )
 
 // UpdateRegistrySecret updates a registry Secret in the cluster
 func (p *pkgClient) UpdateRegistrySecret(o *tkgpackagedatamodel.RegistrySecretOptions) error {
-	if err := p.kappClient.GetClient().Get(context.Background(), crtclient.ObjectKey{Name: o.SecretName, Namespace: o.Namespace}, secret); err != nil {
+	if err := p.kappClient.GetClient().Get(context.Background(), crtclient.ObjectKey{Name: o.SecretName, Namespace: o.Namespace}, Secret); err != nil {
 		if apierrors.IsNotFound(err) {
 			return fmt.Errorf("secret '%s' does not exist in namespace '%s'", o.SecretName, o.Namespace)
 		}
 		return err
 	}
 
-	registry, username, password, err := extractExistingSecretCredentials(secret, o)
+	registry, username, password, err := extractExistingSecretCredentials(Secret, o)
 	if err != nil {
 		return err
 	}
@@ -51,12 +51,12 @@ func (p *pkgClient) UpdateRegistrySecret(o *tkgpackagedatamodel.RegistrySecretOp
 		password = o.Password
 	}
 
-	dockerCfg := DockerConfigJSON{Auths: map[string]dockerConfigEntry{registry: {Username: username, Password: password}}}
+	dockerCfg := DockerConfigJSON{Auths: map[string]DockerConfigEntry{registry: {Username: username, Password: password}}}
 	dockerCfgContent, err := json.Marshal(dockerCfg)
 	if err != nil {
 		return err
 	}
-	secretToUpdate := secret.DeepCopy()
+	secretToUpdate := Secret.DeepCopy()
 	secretToUpdate.Data[corev1.DockerConfigJsonKey] = dockerCfgContent
 
 	if err := p.kappClient.GetClient().Update(context.Background(), secretToUpdate); err != nil {
@@ -121,28 +121,28 @@ func (p *pkgClient) UpdateSecretExport(o *tkgpackagedatamodel.RegistrySecretOpti
 	}
 
 	if *o.Export.ExportToAllNamespaces {
-		err := p.kappClient.GetClient().Get(context.Background(), crtclient.ObjectKey{Name: o.SecretName, Namespace: o.Namespace}, secretExport)
+		err := p.kappClient.GetClient().Get(context.Background(), crtclient.ObjectKey{Name: o.SecretName, Namespace: o.Namespace}, SecretExport)
 		if err != nil {
 			if !apierrors.IsNotFound(err) {
 				return err
 			}
-			secretExport = p.newSecretExport(o.SecretName, o.Namespace)
-			if err := p.kappClient.GetClient().Create(context.Background(), secretExport); err != nil {
+			SecretExport = p.newSecretExport(o.SecretName, o.Namespace)
+			if err := p.kappClient.GetClient().Create(context.Background(), SecretExport); err != nil {
 				return errors.Wrap(err, "failed to create SecretExport resource")
 			}
 			return nil
 		}
-		secretExportToUpdate := secretExport.DeepCopy()
+		secretExportToUpdate := SecretExport.DeepCopy()
 		secretExportToUpdate.Spec = secretgenctrl.SecretExportSpec{ToNamespaces: []string{"*"}}
 		if err := p.kappClient.GetClient().Update(context.Background(), secretExportToUpdate); err != nil {
 			return errors.Wrap(err, "failed to update SecretExport resource")
 		}
 	} else { // un-export already exported secrets
-		secretExport = &secretgenctrl.SecretExport{
+		SecretExport = &secretgenctrl.SecretExport{
 			TypeMeta:   metav1.TypeMeta{Kind: tkgpackagedatamodel.KindSecretExport, APIVersion: secretgenctrl.SchemeGroupVersion.String()},
 			ObjectMeta: metav1.ObjectMeta{Name: o.SecretName, Namespace: o.Namespace},
 		}
-		if err := p.kappClient.GetClient().Delete(context.Background(), secretExport); err != nil {
+		if err := p.kappClient.GetClient().Delete(context.Background(), SecretExport); err != nil {
 			if !apierrors.IsNotFound(err) {
 				return errors.Wrap(err, "failed to delete SecretExport resource")
 			}
diff --git a/pkg/v1/tkg/tkgpackageclient/repository_add.go b/pkg/v1/tkg/tkgpackageclient/repository_add.go
index 8c2ac5f281..4b5ba853c9 100644
--- a/pkg/v1/tkg/tkgpackageclient/repository_add.go
+++ b/pkg/v1/tkg/tkgpackageclient/repository_add.go
@@ -118,7 +118,7 @@ func (p *pkgClient) newPackageRepository(repositoryName, repositoryImg, namespac
 		}},
 	}
 
-	_, tag, err := parseRegistryImageURL(repositoryImg)
+	_, tag, err := ParseRegistryImageURL(repositoryImg)
 	if err != nil {
 		return nil, errors.Wrap(err, "failed to parse OCI registry URL")
 	}
diff --git a/pkg/v1/tkg/tkgpackageclient/repository_update.go b/pkg/v1/tkg/tkgpackageclient/repository_update.go
index 072b0f4054..374b33aa9a 100644
--- a/pkg/v1/tkg/tkgpackageclient/repository_update.go
+++ b/pkg/v1/tkg/tkgpackageclient/repository_update.go
@@ -73,7 +73,7 @@ func (p *pkgClient) updateRepository(o *tkgpackagedatamodel.RepositoryOptions, p
 			return
 		}
 
-		_, tag, err = parseRegistryImageURL(o.RepositoryURL)
+		_, tag, err = ParseRegistryImageURL(o.RepositoryURL)
 		if err != nil {
 			err = errors.Wrap(err, "failed to parse OCI registry URL")
 			return


Test patch:
diff --git a/pkg/v1/tkg/client/management_components_test.go b/pkg/v1/tkg/client/management_components_test.go
new file mode 100644
index 0000000000..383802c65c
--- /dev/null
+++ b/pkg/v1/tkg/client/management_components_test.go
@@ -0,0 +1,87 @@
+// Copyright 2021 VMware, Inc. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package client_test
+
+import (
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/client"
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgconfigreaderwriter"
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/utils"
+)
+
+var _ = Describe("Unit tests for GetUserConfigVariableValueMap", func() {
+	var (
+		err                      error
+		tkgClient                *TkgClient
+		configFilePath           string
+		configFileData           string
+		userProviderConfigValues map[string]string
+		rw                       tkgconfigreaderwriter.TKGConfigReaderWriter
+	)
+
+	sampleConfigFileData1 := `
+#@data/values
+#@overlay/match-child-defaults missing_ok=True
+---
+ABC:
+PQR: ""
+`
+	sampleConfigFileData2 := ``
+
+	BeforeEach(func() {
+		rw, err = tkgconfigreaderwriter.NewReaderWriterFromConfigFile("", "../fakes/config/config.yaml")
+		Expect(err).NotTo(HaveOccurred())
+	})
+
+	JustBeforeEach(func() {
+		configFilePath = writeConfigFileData(configFileData)
+		userProviderConfigValues, err = tkgClient.GetUserConfigVariableValueMap(configFilePath, rw)
+	})
+
+	Context("When only one data value is provided by user", func() {
+		BeforeEach(func() {
+			configFileData = sampleConfigFileData1
+			rw.Set("ABC", "abc-value")
+		})
+		It("returns userProviderConfigValues with ABC", func() {
+			Expect(err).NotTo(HaveOccurred())
+			Expect(len(userProviderConfigValues)).To(Equal(1))
+			Expect(userProviderConfigValues["ABC"]).To(Equal("abc-value"))
+		})
+	})
+
+	Context("When all data value is provided by user", func() {
+		BeforeEach(func() {
+			configFileData = sampleConfigFileData1
+			rw.Set("ABC", "abc-value")
+			rw.Set("PQR", "pqr-value")
+			rw.Set("TEST", "test-value")
+		})
+		It("returns userProviderConfigValues with ABC and PQR", func() {
+			Expect(err).NotTo(HaveOccurred())
+			Expect(len(userProviderConfigValues)).To(Equal(2))
+			Expect(userProviderConfigValues["ABC"]).To(Equal("abc-value"))
+			Expect(userProviderConfigValues["PQR"]).To(Equal("pqr-value"))
+		})
+	})
+
+	Context("When no config variables are defined in config default", func() {
+		BeforeEach(func() {
+			configFileData = sampleConfigFileData2
+			rw.Set("TEST", "test-value")
+		})
+		It("returns empty map", func() {
+			Expect(err).NotTo(HaveOccurred())
+			Expect(len(userProviderConfigValues)).To(Equal(0))
+		})
+	})
+})
+
+func writeConfigFileData(configconfigFileData string) string {
+	tmpFile, _ := utils.CreateTempFile("", "")
+	_ = utils.WriteToFile(tmpFile, []byte(configconfigFileData))
+	return tmpFile
+}
diff --git a/pkg/v1/tkg/managementcomponents/management_component_install_test.go b/pkg/v1/tkg/managementcomponents/management_component_install_test.go
new file mode 100644
index 0000000000..e2e17e93d3
--- /dev/null
+++ b/pkg/v1/tkg/managementcomponents/management_component_install_test.go
@@ -0,0 +1,120 @@
+// Copyright 2021 VMware, Inc. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package managementcomponents_test
+
+import (
+	"errors"
+	"testing"
+
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/managementcomponents"
+
+	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+)
+
+func Test(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "ManagementComponent Suite")
+}
+
+var _ = Describe("Test InstallManagementPackages", func() {
+	var (
+		fakePkgClient *fakes.TKGPackageClient
+		mprOptions    ManagementPackageRepositoryOptions
+		err           error
+	)
+
+	BeforeEach(func() {
+		fakePkgClient = &fakes.TKGPackageClient{}
+		mprOptions = ManagementPackageRepositoryOptions{ManagementPackageRepoImage: "", TKGPackageValuesFile: ""}
+	})
+
+	JustBeforeEach(func() {
+		err = InstallManagementPackages(fakePkgClient, mprOptions)
+	})
+
+	Context("when update repository throws error", func() {
+		BeforeEach(func() {
+			fakePkgClient.UpdateRepositorySyncReturns(errors.New("fake error update repository"))
+			fakePkgClient.InstallPackageSyncReturns(nil)
+		})
+		It("should return error", func() {
+			Expect(err).To(HaveOccurred())
+			Expect(err.Error()).To(ContainSubstring("fake error update repository"))
+		})
+	})
+
+	Context("when install package throws error", func() {
+		BeforeEach(func() {
+			fakePkgClient.UpdateRepositorySyncReturns(nil)
+			fakePkgClient.InstallPackageSyncReturns(errors.New("fake error install package"))
+		})
+		It("should return error", func() {
+			Expect(err).To(HaveOccurred())
+			Expect(err.Error()).To(ContainSubstring("fake error install package"))
+		})
+	})
+
+	Context("when update repository and install package are successful", func() {
+		BeforeEach(func() {
+			fakePkgClient.UpdateRepositorySyncReturns(nil)
+			fakePkgClient.InstallPackageSyncReturns(nil)
+		})
+		It("should not return error", func() {
+			Expect(err).NotTo(HaveOccurred())
+		})
+	})
+})
+
+var _ = Describe("Test InstallKappController", func() {
+	var (
+		clusterClient *fakes.ClusterClient
+		kcOptions     KappControllerOptions
+		err           error
+	)
+
+	BeforeEach(func() {
+		clusterClient = &fakes.ClusterClient{}
+		kcOptions = KappControllerOptions{KappControllerConfigFile: "", KappControllerInstallNamespace: ""}
+	})
+
+	JustBeforeEach(func() {
+		err = InstallKappController(clusterClient, kcOptions)
+	})
+
+	Context("when applying kapp-controller config throws error", func() {
+		BeforeEach(func() {
+			clusterClient.ApplyFileReturns(errors.New("fake error applyfile"))
+			clusterClient.WaitForDeploymentReturns(nil)
+		})
+		It("should return error", func() {
+			Expect(err).To(HaveOccurred())
+			Expect(err.Error()).To(ContainSubstring("fake error applyfile"))
+		})
+	})
+
+	Context("when WaitForDeployment config throws error", func() {
+		BeforeEach(func() {
+			clusterClient.ApplyFileReturns(nil)
+			clusterClient.WaitForDeploymentReturns(errors.New("fake error waitfordeployment"))
+		})
+		It("should return error", func() {
+			Expect(err).To(HaveOccurred())
+			Expect(err.Error()).To(ContainSubstring("fake error waitfordeployment"))
+		})
+	})
+
+	Context("when kapp-controller is deployed successfully", func() {
+		BeforeEach(func() {
+			clusterClient.ApplyFileReturns(nil)
+			clusterClient.WaitForDeploymentReturns(nil)
+		})
+		It("should return error", func() {
+			Expect(err).NotTo(HaveOccurred())
+		})
+	})
+
+})
diff --git a/pkg/v1/tkg/tkgpackageclient/image_utils_test.go b/pkg/v1/tkg/tkgpackageclient/image_utils_test.go
index fe1075563f..a045ef466a 100644
--- a/pkg/v1/tkg/tkgpackageclient/image_utils_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/image_utils_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	. "github.com/onsi/ginkgo"
@@ -12,6 +12,8 @@ import (
 	kappctrl "github.com/vmware-tanzu/carvel-kapp-controller/pkg/apis/kappctrl/v1alpha1"
 	kappipkg "github.com/vmware-tanzu/carvel-kapp-controller/pkg/apis/packaging/v1alpha1"
 	versions "github.com/vmware-tanzu/carvel-vendir/pkg/vendir/versions/v1alpha1"
+
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
@@ -20,7 +22,7 @@ var _ = Describe("Test image utils", func() {
 
 		It("should have error if image url isn't valid", func() {
 			// case 1
-			repository, tag, err := parseRegistryImageURL("sftp://user:passwd@example.com/foo/bar:latest")
+			repository, tag, err := ParseRegistryImageURL("sftp://user:passwd@example.com/foo/bar:latest")
 			Expect(err).To(HaveOccurred())
 			Expect(repository).To(Equal(""))
 			Expect(tag).To(Equal(""))
@@ -28,13 +30,13 @@ var _ = Describe("Test image utils", func() {
 
 		It("should give the correct tag when tag is specified", func() {
 			// case 1
-			repository, tag, err := parseRegistryImageURL("foo/bar:1.1")
+			repository, tag, err := ParseRegistryImageURL("foo/bar:1.1")
 			Expect(err).NotTo(HaveOccurred())
 			Expect(repository).To(Equal("index.docker.io/foo/bar"))
 			Expect(tag).To(Equal("1.1"))
 
 			// case 2
-			repository, tag, err = parseRegistryImageURL("localhost.localdomain:5000/foo/bar:latest")
+			repository, tag, err = ParseRegistryImageURL("localhost.localdomain:5000/foo/bar:latest")
 			Expect(err).NotTo(HaveOccurred())
 			Expect(repository).To(Equal("localhost.localdomain:5000/foo/bar"))
 			Expect(tag).To(Equal("latest"))
@@ -42,13 +44,13 @@ var _ = Describe("Test image utils", func() {
 
 		It("should give the empty tag when tag is not specified", func() {
 			// case 1
-			repository, tag, err := parseRegistryImageURL("foo/bar")
+			repository, tag, err := ParseRegistryImageURL("foo/bar")
 			Expect(err).NotTo(HaveOccurred())
 			Expect(repository).To(Equal("index.docker.io/foo/bar"))
 			Expect(tag).To(Equal(""))
 
 			// case 2
-			repository, tag, err = parseRegistryImageURL("localhost.localdomain:5000/foo/bar")
+			repository, tag, err = ParseRegistryImageURL("localhost.localdomain:5000/foo/bar")
 			Expect(err).NotTo(HaveOccurred())
 			Expect(repository).To(Equal("localhost.localdomain:5000/foo/bar"))
 			Expect(tag).To(Equal(""))
@@ -56,13 +58,13 @@ var _ = Describe("Test image utils", func() {
 
 		It("should give the digest when sha256 is specified", func() {
 			// case 1
-			repository, tag, err := parseRegistryImageURL("us-east4-docker.pkg.dev/cf-sandbox-dkalinin/test-areg-private/example-pkg-repo@sha256:a80e9b512b9eff76ab638cce50a3c4541a12673d9b698103314f32c93f1deb61")
+			repository, tag, err := ParseRegistryImageURL("us-east4-docker.pkg.dev/cf-sandbox-dkalinin/test-areg-private/example-pkg-repo@sha256:a80e9b512b9eff76ab638cce50a3c4541a12673d9b698103314f32c93f1deb61")
 			Expect(err).NotTo(HaveOccurred())
 			Expect(repository).To(Equal("us-east4-docker.pkg.dev/cf-sandbox-dkalinin/test-areg-private/example-pkg-repo"))
 			Expect(tag).To(Equal("sha256:a80e9b512b9eff76ab638cce50a3c4541a12673d9b698103314f32c93f1deb61"))
 
 			// case 2
-			repository, tag, err = parseRegistryImageURL("projects-stg.registry.vmware.com/tkg/packages/standard/repo@sha256:dce0b8e03a2a2f8b7ddb732def271f50435b490875c9e90ce3df51cae8af68e5")
+			repository, tag, err = ParseRegistryImageURL("projects-stg.registry.vmware.com/tkg/packages/standard/repo@sha256:dce0b8e03a2a2f8b7ddb732def271f50435b490875c9e90ce3df51cae8af68e5")
 			Expect(err).NotTo(HaveOccurred())
 			Expect(repository).To(Equal("projects-stg.registry.vmware.com/tkg/packages/standard/repo"))
 			Expect(tag).To(Equal("sha256:dce0b8e03a2a2f8b7ddb732def271f50435b490875c9e90ce3df51cae8af68e5"))
diff --git a/pkg/v1/tkg/tkgpackageclient/package_get_test.go b/pkg/v1/tkg/tkgpackageclient/package_get_test.go
index e5701f924f..6bae1cfff5 100644
--- a/pkg/v1/tkg/tkgpackageclient/package_get_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/package_get_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	. "github.com/onsi/ginkgo"
@@ -11,12 +11,13 @@ import (
 	kappipkg "github.com/vmware-tanzu/carvel-kapp-controller/pkg/apis/packaging/v1alpha1"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 var _ = Describe("Get Installed Package", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		kappCtl *fakes.KappClient
 		err     error
 		opts    = tkgpackagedatamodel.PackageOptions{
@@ -28,7 +29,9 @@ var _ = Describe("Get Installed Package", func() {
 	)
 
 	JustBeforeEach(func() {
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
+
 		pkgInstall, err = ctl.GetPackageInstall(&options)
 	})
 
diff --git a/pkg/v1/tkg/tkgpackageclient/package_install_test.go b/pkg/v1/tkg/tkgpackageclient/package_install_test.go
index 4e6638d218..1e496c92de 100644
--- a/pkg/v1/tkg/tkgpackageclient/package_install_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/package_install_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	"fmt"
@@ -12,6 +12,8 @@ import (
 	. "github.com/onsi/gomega"
 	"github.com/pkg/errors"
 
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
+
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/api/meta"
@@ -80,7 +82,7 @@ var (
 
 var _ = Describe("Install Package", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		crtCtl  *fakes.CRTClusterClient
 		kappCtl *fakes.KappClient
 		err     error
@@ -103,7 +105,8 @@ var _ = Describe("Install Package", func() {
 			Err:         make(chan error),
 			Done:        make(chan struct{}),
 		}
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		go ctl.InstallPackage(&options, progress, tkgpackagedatamodel.OperationTypeInstall)
 		err = testReceive(progress)
 	})
diff --git a/pkg/v1/tkg/tkgpackageclient/package_list_test.go b/pkg/v1/tkg/tkgpackageclient/package_list_test.go
index 05b4f2ea2e..6156f976b0 100644
--- a/pkg/v1/tkg/tkgpackageclient/package_list_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/package_list_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	. "github.com/onsi/ginkgo"
@@ -14,12 +14,13 @@ import (
 	kapppkg "github.com/vmware-tanzu/carvel-kapp-controller/pkg/apiserver/apis/datapackaging/v1alpha1"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 var _ = Describe("List Packages", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		kappCtl *fakes.KappClient
 		err     error
 		opts    = tkgpackagedatamodel.PackageOptions{
@@ -53,7 +54,8 @@ var _ = Describe("List Packages", func() {
 		BeforeEach(func() {
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListPackageMetadataReturns(nil, errors.New("failure in ListPackageMetadata"))
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 			pkgMetadataList, err = ctl.ListPackageMetadata(&optionsAvailable)
 		})
 		It(testFailureMsg, func() {
@@ -68,7 +70,8 @@ var _ = Describe("List Packages", func() {
 		BeforeEach(func() {
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListPackageMetadataReturns(packageMetadataList, nil)
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 			pkgMetadataList, err = ctl.ListPackageMetadata(&optionsAvailable)
 		})
 		It(testSuccessMsg, func() {
@@ -83,7 +86,8 @@ var _ = Describe("List Packages", func() {
 		BeforeEach(func() {
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListPackageInstallsReturns(nil, errors.New("failure in ListPackageInstalls"))
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 			packageInstalls, err = ctl.ListPackageInstalls(&options)
 		})
 		It(testFailureMsg, func() {
@@ -98,7 +102,8 @@ var _ = Describe("List Packages", func() {
 		BeforeEach(func() {
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListPackageInstallsReturns(pkgInstallList, nil)
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 			packageInstalls, err = ctl.ListPackageInstalls(&options)
 		})
 		It(testSuccessMsg, func() {
@@ -114,7 +119,8 @@ var _ = Describe("List Packages", func() {
 			optionsAvailable.PackageName = testPkgInstallName
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListPackagesReturns(nil, errors.New("failure in ListPackages"))
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 			packageVersions, err = ctl.ListPackages(&optionsAvailable)
 		})
 		It(testFailureMsg, func() {
@@ -130,7 +136,8 @@ var _ = Describe("List Packages", func() {
 			optionsAvailable.PackageName = testPkgInstallName
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListPackagesReturns(testPkgVersionList, nil)
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 			packageVersions, err = ctl.ListPackages(&optionsAvailable)
 		})
 		It(testSuccessMsg, func() {
diff --git a/pkg/v1/tkg/tkgpackageclient/package_uninstall_test.go b/pkg/v1/tkg/tkgpackageclient/package_uninstall_test.go
index c63097bc66..e2024e05d8 100644
--- a/pkg/v1/tkg/tkgpackageclient/package_uninstall_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/package_uninstall_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	. "github.com/onsi/ginkgo"
@@ -15,12 +15,13 @@ import (
 	kappipkg "github.com/vmware-tanzu/carvel-kapp-controller/pkg/apis/packaging/v1alpha1"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 var _ = Describe("Uninstall Package", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		crtCtl  *fakes.CRTClusterClient
 		kappCtl *fakes.KappClient
 		err     error
@@ -53,7 +54,8 @@ var _ = Describe("Uninstall Package", func() {
 			Err:         make(chan error),
 			Done:        make(chan struct{}),
 		}
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		go ctl.UninstallPackage(&options, progress)
 		err = testReceive(progress)
 	})
diff --git a/pkg/v1/tkg/tkgpackageclient/package_update_test.go b/pkg/v1/tkg/tkgpackageclient/package_update_test.go
index a2c08dc365..89f24806f1 100644
--- a/pkg/v1/tkg/tkgpackageclient/package_update_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/package_update_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	"fmt"
@@ -20,12 +20,13 @@ import (
 	versions "github.com/vmware-tanzu/carvel-vendir/pkg/vendir/versions/v1alpha1"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 var _ = Describe("Update Package", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		crtCtl  *fakes.CRTClusterClient
 		kappCtl *fakes.KappClient
 		err     error
@@ -48,7 +49,8 @@ var _ = Describe("Update Package", func() {
 			Err:         make(chan error),
 			Done:        make(chan struct{}),
 		}
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		go ctl.UpdatePackage(&options, progress, tkgpackagedatamodel.OperationTypeUpdate)
 		err = testReceive(progress)
 	})
@@ -191,7 +193,7 @@ var _ = Describe("Update Package", func() {
 			kappCtl.ListPackagesReturns(testPkgVersionList, nil)
 			err = os.WriteFile(testValuesFile, []byte("test"), 0644)
 			Expect(err).ToNot(HaveOccurred())
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.CreateReturns(errors.New("error on creating the secret resource"))
 		})
 		It(testFailureMsg, func() {
@@ -200,7 +202,7 @@ var _ = Describe("Update Package", func() {
 		})
 		AfterEach(func() {
 			options = opts
-			secret = &corev1.Secret{}
+			Secret = &corev1.Secret{}
 			testPkgInstall.Spec.PackageRef.VersionSelection = testVersionSelection
 			err = os.Remove(testValuesFile)
 			Expect(err).ToNot(HaveOccurred())
@@ -220,7 +222,7 @@ var _ = Describe("Update Package", func() {
 			kappCtl.ListPackagesReturns(testPkgVersionList, nil)
 			err = os.WriteFile(testValuesFile, []byte("test"), 0644)
 			Expect(err).ToNot(HaveOccurred())
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.UpdateReturns(errors.New("error on updating the secret resource"))
 		})
 		It(testFailureMsg, func() {
@@ -229,7 +231,7 @@ var _ = Describe("Update Package", func() {
 		})
 		AfterEach(func() {
 			options = opts
-			secret = &corev1.Secret{}
+			Secret = &corev1.Secret{}
 			testPkgInstall.Spec.PackageRef.VersionSelection = testVersionSelection
 			err = os.Remove(testValuesFile)
 			Expect(err).ToNot(HaveOccurred())
diff --git a/pkg/v1/tkg/tkgpackageclient/registry_secret_add_test.go b/pkg/v1/tkg/tkgpackageclient/registry_secret_add_test.go
index a5499ab143..f5f06f2707 100644
--- a/pkg/v1/tkg/tkgpackageclient/registry_secret_add_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/registry_secret_add_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	. "github.com/onsi/ginkgo"
@@ -9,6 +9,7 @@ import (
 	"github.com/pkg/errors"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
@@ -22,7 +23,7 @@ const (
 
 var _ = Describe("Add Secret", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		crtCtl  *fakes.CRTClusterClient
 		kappCtl *fakes.KappClient
 		err     error
@@ -38,7 +39,8 @@ var _ = Describe("Add Secret", func() {
 	)
 
 	JustBeforeEach(func() {
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		err = ctl.AddRegistrySecret(&options)
 	})
 
diff --git a/pkg/v1/tkg/tkgpackageclient/registry_secret_delete_test.go b/pkg/v1/tkg/tkgpackageclient/registry_secret_delete_test.go
index cceb815c50..e4acfd1308 100644
--- a/pkg/v1/tkg/tkgpackageclient/registry_secret_delete_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/registry_secret_delete_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	. "github.com/onsi/ginkgo"
@@ -12,12 +12,13 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 var _ = Describe("Delete Secret", func() {
 	var (
-		ctl           *pkgClient
+		ctl           TKGPackageClient
 		crtCtl        *fakes.CRTClusterClient
 		kappCtl       *fakes.KappClient
 		err           error
@@ -35,7 +36,8 @@ var _ = Describe("Delete Secret", func() {
 	)
 
 	JustBeforeEach(func() {
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		isSecretFound, err = ctl.DeleteRegistrySecret(&options)
 	})
 
diff --git a/pkg/v1/tkg/tkgpackageclient/registry_secret_list_test.go b/pkg/v1/tkg/tkgpackageclient/registry_secret_list_test.go
index 65f0cc8fb7..f15f7e32f0 100644
--- a/pkg/v1/tkg/tkgpackageclient/registry_secret_list_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/registry_secret_list_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	"encoding/json"
@@ -16,12 +16,13 @@ import (
 	secretgenctrl "github.com/vmware-tanzu/carvel-secretgen-controller/pkg/apis/secretgen2/v1alpha1"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 const testSecretExportName = "test-secret"
 
-var testDockerConfig = DockerConfigJSON{Auths: map[string]dockerConfigEntry{"us-east4-docker.pkg.dev": {Username: "test_user", Password: "test_password"}}}
+var testDockerConfig = DockerConfigJSON{Auths: map[string]DockerConfigEntry{"us-east4-docker.pkg.dev": {Username: "test_user", Password: "test_password"}}}
 
 var testSecret = &corev1.Secret{
 	TypeMeta:   metav1.TypeMeta{Kind: tkgpackagedatamodel.KindSecret, APIVersion: corev1.SchemeGroupVersion.String()},
@@ -38,7 +39,7 @@ var testSecretExport = &secretgenctrl.SecretExport{
 
 var _ = Describe("List Secrets", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		kappCtl *fakes.KappClient
 		err     error
 		opts    = tkgpackagedatamodel.RegistrySecretOptions{
@@ -54,7 +55,8 @@ var _ = Describe("List Secrets", func() {
 	)
 
 	JustBeforeEach(func() {
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		dockerCfgContent, _ := json.Marshal(testDockerConfig)
 		testSecret.Data[corev1.DockerConfigJsonKey] = dockerCfgContent
 		secrets, err = ctl.ListRegistrySecrets(&options)
@@ -64,7 +66,8 @@ var _ = Describe("List Secrets", func() {
 		BeforeEach(func() {
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListRegistrySecretsReturns(nil, errors.New("failure in ListRegistrySecrets"))
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 		})
 		It(testFailureMsg, func() {
 			Expect(err).To(HaveOccurred())
@@ -77,7 +80,8 @@ var _ = Describe("List Secrets", func() {
 		BeforeEach(func() {
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListRegistrySecretsReturns(secretList, nil)
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 		})
 		It(testSuccessMsg, func() {
 			Expect(err).NotTo(HaveOccurred())
@@ -89,7 +93,7 @@ var _ = Describe("List Secrets", func() {
 
 var _ = Describe("List Secret Exports", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		kappCtl *fakes.KappClient
 		err     error
 		opts    = tkgpackagedatamodel.RegistrySecretOptions{
@@ -105,7 +109,8 @@ var _ = Describe("List Secret Exports", func() {
 	)
 
 	JustBeforeEach(func() {
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		secretExports, err = ctl.ListSecretExports(&options)
 	})
 
@@ -113,7 +118,8 @@ var _ = Describe("List Secret Exports", func() {
 		BeforeEach(func() {
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListSecretExportsReturns(nil, errors.New("failure in ListSecretExports"))
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 		})
 		It(testFailureMsg, func() {
 			Expect(err).To(HaveOccurred())
@@ -126,7 +132,8 @@ var _ = Describe("List Secret Exports", func() {
 		BeforeEach(func() {
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListSecretExportsReturns(secretExportList, nil)
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 		})
 		It(testSuccessMsg, func() {
 			Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/v1/tkg/tkgpackageclient/registry_secret_update_test.go b/pkg/v1/tkg/tkgpackageclient/registry_secret_update_test.go
index ea98c6636e..f9dc2e93da 100644
--- a/pkg/v1/tkg/tkgpackageclient/registry_secret_update_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/registry_secret_update_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	"encoding/json"
@@ -16,15 +16,16 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 var _ = Describe("Update Secret", func() {
 	type invalidDockerCfgJSON struct {
-		Auths map[string]dockerConfigEntry `json:"invalid-key" datapolicy:"token"`
+		Auths map[string]DockerConfigEntry `json:"invalid-key" datapolicy:"token"`
 	}
 	var (
-		ctl              *pkgClient
+		ctl              TKGPackageClient
 		crtCtl           *fakes.CRTClusterClient
 		kappCtl          *fakes.KappClient
 		err              error
@@ -40,14 +41,15 @@ var _ = Describe("Update Secret", func() {
 			Server:     testServer,
 		}
 		options                         = opts
-		testDockerCfgInvalid            = invalidDockerCfgJSON{Auths: map[string]dockerConfigEntry{testServer: {Username: "test_user", Password: "test_password"}}}
-		testDockerCfgMultipleRegistries = DockerConfigJSON{Auths: map[string]dockerConfigEntry{testServer: {Username: "test_user", Password: "test_password"}, "us-west-docker.pkg.dev": {Username: "test_user", Password: "test_password"}}}
-		testDockerCfgNoUsername         = DockerConfigJSON{Auths: map[string]dockerConfigEntry{testServer: {Password: "test_password"}}}
-		testDockerCfgNoPassword         = DockerConfigJSON{Auths: map[string]dockerConfigEntry{testServer: {Username: "test_user"}}}
+		testDockerCfgInvalid            = invalidDockerCfgJSON{Auths: map[string]DockerConfigEntry{testServer: {Username: "test_user", Password: "test_password"}}}
+		testDockerCfgMultipleRegistries = DockerConfigJSON{Auths: map[string]DockerConfigEntry{testServer: {Username: "test_user", Password: "test_password"}, "us-west-docker.pkg.dev": {Username: "test_user", Password: "test_password"}}}
+		testDockerCfgNoUsername         = DockerConfigJSON{Auths: map[string]DockerConfigEntry{testServer: {Password: "test_password"}}}
+		testDockerCfgNoPassword         = DockerConfigJSON{Auths: map[string]DockerConfigEntry{testServer: {Username: "test_user"}}}
 	)
 
 	JustBeforeEach(func() {
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		err = ctl.UpdateRegistrySecret(&options)
 	})
 
@@ -84,7 +86,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerCfgInvalid)
 			Expect(err).NotTo(HaveOccurred())
@@ -102,7 +104,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerCfgMultipleRegistries)
 			Expect(err).NotTo(HaveOccurred())
@@ -121,7 +123,7 @@ var _ = Describe("Update Secret", func() {
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
 			options.Server = "new-server"
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerCfgNoUsername)
 			Expect(err).NotTo(HaveOccurred())
@@ -140,7 +142,7 @@ var _ = Describe("Update Secret", func() {
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
 			options.Username = ""
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerCfgNoUsername)
 			Expect(err).NotTo(HaveOccurred())
@@ -158,7 +160,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerCfgNoPassword)
 			Expect(err).NotTo(HaveOccurred())
@@ -176,7 +178,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerConfig)
 			Expect(err).NotTo(HaveOccurred())
@@ -195,7 +197,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerConfig)
 			Expect(err).NotTo(HaveOccurred())
@@ -215,7 +217,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerConfig)
 			Expect(err).NotTo(HaveOccurred())
@@ -236,7 +238,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerConfig)
 			Expect(err).NotTo(HaveOccurred())
@@ -256,7 +258,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerConfig)
 			Expect(err).NotTo(HaveOccurred())
@@ -277,7 +279,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerConfig)
 			Expect(err).NotTo(HaveOccurred())
@@ -298,7 +300,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerConfig)
 			Expect(err).NotTo(HaveOccurred())
@@ -319,7 +321,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerConfig)
 			Expect(err).NotTo(HaveOccurred())
@@ -339,7 +341,7 @@ var _ = Describe("Update Secret", func() {
 			kappCtl = &fakes.KappClient{}
 			crtCtl = &fakes.CRTClusterClient{}
 			kappCtl.GetClientReturns(crtCtl)
-			secret = testSecret
+			Secret = testSecret
 			crtCtl.GetReturnsOnCall(0, nil)
 			dockerCfgContent, err = json.Marshal(testDockerConfig)
 			Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/v1/tkg/tkgpackageclient/repository_add_test.go b/pkg/v1/tkg/tkgpackageclient/repository_add_test.go
index d44281349c..9e4d254cc4 100644
--- a/pkg/v1/tkg/tkgpackageclient/repository_add_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/repository_add_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	"fmt"
@@ -18,6 +18,7 @@ import (
 	kappipkg "github.com/vmware-tanzu/carvel-kapp-controller/pkg/apis/packaging/v1alpha1"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
@@ -41,7 +42,7 @@ var testRepository = &kappipkg.PackageRepository{
 
 var _ = Describe("Add Repository", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		crtCtl  *fakes.CRTClusterClient
 		kappCtl *fakes.KappClient
 		err     error
@@ -65,7 +66,8 @@ var _ = Describe("Add Repository", func() {
 			Err:         make(chan error),
 			Done:        make(chan struct{}),
 		}
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		go ctl.AddRepository(&options, progress, tkgpackagedatamodel.OperationTypeInstall)
 		err = testReceive(progress)
 	})
diff --git a/pkg/v1/tkg/tkgpackageclient/repository_delete_test.go b/pkg/v1/tkg/tkgpackageclient/repository_delete_test.go
index 8d341cec2c..d1dc050743 100644
--- a/pkg/v1/tkg/tkgpackageclient/repository_delete_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/repository_delete_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	. "github.com/onsi/ginkgo"
@@ -12,12 +12,13 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 var _ = Describe("Delete Repository", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		kappCtl *fakes.KappClient
 		err     error
 		opts    = tkgpackagedatamodel.RepositoryOptions{
@@ -34,7 +35,8 @@ var _ = Describe("Delete Repository", func() {
 			Err:         make(chan error),
 			Done:        make(chan struct{}),
 		}
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		go ctl.DeleteRepository(&options, progress)
 		err = testReceive(progress)
 	})
diff --git a/pkg/v1/tkg/tkgpackageclient/repository_get_test.go b/pkg/v1/tkg/tkgpackageclient/repository_get_test.go
index fc4ddfaa0a..f834947e1d 100644
--- a/pkg/v1/tkg/tkgpackageclient/repository_get_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/repository_get_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	. "github.com/onsi/ginkgo"
@@ -11,12 +11,13 @@ import (
 	kappipkg "github.com/vmware-tanzu/carvel-kapp-controller/pkg/apis/packaging/v1alpha1"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 var _ = Describe("Get Repository", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		kappCtl *fakes.KappClient
 		err     error
 		opts    = tkgpackagedatamodel.RepositoryOptions{
@@ -28,7 +29,8 @@ var _ = Describe("Get Repository", func() {
 	)
 
 	JustBeforeEach(func() {
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		repository, err = ctl.GetRepository(&options)
 	})
 
diff --git a/pkg/v1/tkg/tkgpackageclient/repository_list_test.go b/pkg/v1/tkg/tkgpackageclient/repository_list_test.go
index 79d6020c43..75edce80fd 100644
--- a/pkg/v1/tkg/tkgpackageclient/repository_list_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/repository_list_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	. "github.com/onsi/ginkgo"
@@ -13,12 +13,13 @@ import (
 	kappipkg "github.com/vmware-tanzu/carvel-kapp-controller/pkg/apis/packaging/v1alpha1"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 var _ = Describe("List Repositories", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		kappCtl *fakes.KappClient
 		err     error
 		opts    = tkgpackagedatamodel.RepositoryOptions{
@@ -34,7 +35,8 @@ var _ = Describe("List Repositories", func() {
 	)
 
 	JustBeforeEach(func() {
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		repositories, err = ctl.ListRepositories(&options)
 	})
 
@@ -42,7 +44,8 @@ var _ = Describe("List Repositories", func() {
 		BeforeEach(func() {
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListPackageRepositoriesReturns(nil, errors.New("failure in ListPackageRepositories"))
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 		})
 		It(testFailureMsg, func() {
 			Expect(err).To(HaveOccurred())
@@ -55,7 +58,8 @@ var _ = Describe("List Repositories", func() {
 		BeforeEach(func() {
 			kappCtl = &fakes.KappClient{}
 			kappCtl.ListPackageRepositoriesReturns(repositoryList, nil)
-			ctl = &pkgClient{kappClient: kappCtl}
+			ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+			Expect(err).NotTo(HaveOccurred())
 		})
 		It(testSuccessMsg, func() {
 			Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/v1/tkg/tkgpackageclient/repository_update_test.go b/pkg/v1/tkg/tkgpackageclient/repository_update_test.go
index 15d7e58036..5329e0ec7c 100644
--- a/pkg/v1/tkg/tkgpackageclient/repository_update_test.go
+++ b/pkg/v1/tkg/tkgpackageclient/repository_update_test.go
@@ -1,7 +1,7 @@
 // Copyright 2021 VMware, Inc. All Rights Reserved.
 // SPDX-License-Identifier: Apache-2.0
 
-package tkgpackageclient
+package tkgpackageclient_test
 
 import (
 	"fmt"
@@ -16,12 +16,13 @@ import (
 	kappipkg "github.com/vmware-tanzu/carvel-kapp-controller/pkg/apis/packaging/v1alpha1"
 
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/fakes"
+	. "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackageclient"
 	"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/tkgpackagedatamodel"
 )
 
 var _ = Describe("Update Repository", func() {
 	var (
-		ctl     *pkgClient
+		ctl     TKGPackageClient
 		kappCtl *fakes.KappClient
 		err     error
 		opts    = tkgpackagedatamodel.RepositoryOptions{
@@ -42,7 +43,8 @@ var _ = Describe("Update Repository", func() {
 			Err:         make(chan error),
 			Done:        make(chan struct{}),
 		}
-		ctl = &pkgClient{kappClient: kappCtl}
+		ctl, err = NewTKGPackageClientWithKappClient(kappCtl)
+		Expect(err).NotTo(HaveOccurred())
 		go ctl.UpdateRepository(&options, progress, tkgpackagedatamodel.OperationTypeUpdate)
 		err = testReceive(progress)
 	})