Skip to content

Commit

Permalink
Add defaultNamespace in pkgi/app crs (#1317)
Browse files Browse the repository at this point in the history
Signed-off-by: Praveen Rewar <[email protected]>
  • Loading branch information
praveenrewar authored Sep 21, 2023
1 parent 96bbb58 commit 5aac6ae
Show file tree
Hide file tree
Showing 18 changed files with 581 additions and 178 deletions.
9 changes: 9 additions & 0 deletions config/config/crds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ spec:
description: Specifies namespace in destination cluster (optional)
type: string
type: object
defaultNamespace:
description: Specifies the default namespace to install the App resources, by default this is same as the App's namespace (optional; v0.48.0+)
type: string
deploy:
items:
properties:
Expand Down Expand Up @@ -773,6 +776,9 @@ spec:
description: Specifies namespace in destination cluster (optional)
type: string
type: object
defaultNamespace:
description: Specifies the default namespace to install the App resources, by default this is same as the App's namespace (optional; v0.48.0+)
type: string
deploy:
items:
properties:
Expand Down Expand Up @@ -1502,6 +1508,9 @@ spec:
description: Specifies namespace in destination cluster (optional)
type: string
type: object
defaultNamespace:
description: Specifies the default namespace to install the Package resources, by default this is same as the PackageInstall namespace (optional; v0.48.0+)
type: string
noopDelete:
description: When NoopDelete set to true, PackageInstall deletion should delete PackageInstall/App CR but preserve App's associated resources.
type: boolean
Expand Down
11 changes: 6 additions & 5 deletions hack/dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,19 @@
repo: vmware-tanzu/carvel-kbld
urlTemplate: https://github.com/vmware-tanzu/carvel-{{.Name}}/releases/download/{{.Version}}/{{.Name}}-{{.OS}}-{{.Arch}}
version: v0.37.4
# To be updated after official kapp release
- checksums:
darwin:
amd64: e71048d2b11a2c10258079cc134d7d2c2b6584429202a6212306380d3a8c0a30
arm64: 3660dd8efe83c1356e05255307fa6f65825ba694d96b93bc38c6a43d7e6d7a8c
amd64: ac1f2bd9f43f0d77465f8f4e4b2540a498c6fd3228d7e8452e360d66e04344c7
arm64: 0954a8343d1ef7dac131e2212efd6ff1e2f39c898a242f280c4889e6acfc38e3
linux:
amd64: b253ea9cf6add07f9497955147dc12e8612c24c36dc9929c9a4fecdc76752bd3
arm64: 25491298f6783a8b337d2ebdecf749f7750cf10260fe37086315a9c7da0b558f
amd64: cc1cca783173badd5e74edc1f10decfcae85525cfece73b3d43acfda1eaccbe5
arm64: 59a8ddcacf82cec055f0ca9e66b1ea90ade138792db1b1ddaa72d653cc6d93ba
dev: true
name: kapp
repo: vmware-tanzu/carvel-kapp
urlTemplate: https://github.com/vmware-tanzu/carvel-{{.Name}}/releases/download/{{.Version}}/{{.Name}}-{{.OS}}-{{.Arch}}
version: v0.58.0
version: v0.59.0
- checksums:
darwin:
amd64: 6a5290066d8fbe26aa0603902825bbca55b97f011e97949677eb937ace2d2e3e
Expand Down
361 changes: 201 additions & 160 deletions pkg/apis/kappctrl/v1alpha1/generated.pb.go

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions pkg/apis/kappctrl/v1alpha1/generated.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions pkg/apis/kappctrl/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ type AppSpec struct {
// (optional; default=false; v0.18.0+)
// +optional
NoopDelete bool `json:"noopDelete,omitempty" protobuf:"varint,9,opt,name=noopDelete"`
// Specifies the default namespace to install the App resources, by default this is
// same as the App's namespace (optional; v0.48.0+)
// +optional
DefaultNamespace string `json:"defaultNamespace,omitempty" protobuf:"bytes,10,opt,name=defaultNamespace"`
}

// +k8s:openapi-gen=true
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/packaging/v1alpha1/package_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ type PackageInstallSpec struct {
// associated resources.
// +optional
NoopDelete bool `json:"noopDelete,omitempty"`
// Specifies the default namespace to install the Package resources, by default this is
// same as the PackageInstall namespace (optional; v0.48.0+)
// +optional
DefaultNamespace string `json:"defaultNamespace,omitempty"`
}

type PackageRef struct {
Expand Down
7 changes: 7 additions & 0 deletions pkg/apiserver/openapi/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion pkg/app/app_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ func (a *App) trySaveMetadata(kapp *ctldep.Kapp) {
func (a *App) newKapp(kapp v1alpha1.AppDeployKapp, cancelCh chan struct{}) (*ctldep.Kapp, error) {

return a.deployFactory.NewKapp(kapp, a.app.Spec.ServiceAccountName,
a.app.Spec.Cluster, cancelCh, kubeconfig.AccessLocation{Name: a.app.Name, Namespace: a.app.Namespace})
a.app.Spec.Cluster, cancelCh, kubeconfig.AccessLocation{Name: a.app.Name, Namespace: a.app.Namespace},
a.app.Spec.DefaultNamespace, a.app.Namespace,
)
}

type cancelCondition func(v1alpha1.App) bool
Expand Down
2 changes: 1 addition & 1 deletion pkg/componentinfo/component_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (ci *ComponentInfo) KubernetesVersion(serviceAccountName string, specCluste
return ci.parseAndScrubVersion(v.String())

case specCluster != nil:
accessInfo, err := ci.clusterAccess.ClusterAccess(serviceAccountName, specCluster, kubeconfig.AccessLocation{Name: objMeta.Name, Namespace: objMeta.Namespace})
accessInfo, err := ci.clusterAccess.ClusterAccess(serviceAccountName, specCluster, kubeconfig.AccessLocation{Name: objMeta.Name, Namespace: objMeta.Namespace}, "")
if err != nil {
return semver.Version{}, err
}
Expand Down
11 changes: 6 additions & 5 deletions pkg/deploy/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,22 @@ func NewFactory(coreClient kubernetes.Interface, kubeconfig *kubeconfig.Kubeconf

// NewKapp configures and returns a deployer of type Kapp
func (f Factory) NewKapp(opts v1alpha1.AppDeployKapp, saName string,
clusterOpts *v1alpha1.AppCluster, cancelCh chan struct{}, location kubeconfig.AccessLocation) (*Kapp, error) {
clusterOpts *v1alpha1.AppCluster, cancelCh chan struct{}, location kubeconfig.AccessLocation,
defaultNamespace string, appNamespace string) (*Kapp, error) {

clusterAccess, err := f.kubeconfig.ClusterAccess(saName, clusterOpts, location)
clusterAccess, err := f.kubeconfig.ClusterAccess(saName, clusterOpts, location, defaultNamespace)
if err != nil {
return nil, err
}

const suffix string = ".app"
return NewKapp(suffix, opts, clusterAccess,
f.globalKappDeployRawOpts(), cancelCh, f.cmdRunner), nil
f.globalKappDeployRawOpts(), cancelCh, f.cmdRunner, appNamespace), nil
}

// NewKappPrivileged is used for package repositories where users aren't required to provide
// a service account, so it will install resources using its own privileges.
func (f Factory) NewKappPrivilegedForPackageRepository(opts v1alpha1.AppDeployKapp, clusterAccess kubeconfig.AccessInfo, cancelCh chan struct{}) (*Kapp, error) {
func (f Factory) NewKappPrivilegedForPackageRepository(opts v1alpha1.AppDeployKapp, clusterAccess kubeconfig.AccessInfo, cancelCh chan struct{}, appNamespace string) (*Kapp, error) {

const suffix string = ".pkgr"

Expand All @@ -61,7 +62,7 @@ func (f Factory) NewKappPrivilegedForPackageRepository(opts v1alpha1.AppDeployKa
DangerousUsePodServiceAccount: true,
}

return NewKapp(suffix, opts, kconfAccess, f.globalKappDeployRawOpts(), cancelCh, f.cmdRunner), nil
return NewKapp(suffix, opts, kconfAccess, f.globalKappDeployRawOpts(), cancelCh, f.cmdRunner, appNamespace), nil
}

func (f Factory) globalKappDeployRawOpts() []string {
Expand Down
10 changes: 6 additions & 4 deletions pkg/deploy/kapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Kapp struct {
cancelCh chan struct{}
cmdRunner exec.CmdRunner
appMeta *Meta
appNamespace string
}

var _ Deploy = &Kapp{}
Expand All @@ -42,9 +43,9 @@ var _ Deploy = &Kapp{}
// additional info from the larger app resource (e.g. service account, name, namespace) as genericOpts,
// and a cancel channel that gets passed through to the exec call that runs kapp.
func NewKapp(appSuffix string, opts v1alpha1.AppDeployKapp, clusterAccess kubeconfig.AccessInfo,
globalDeployRawOpts []string, cancelCh chan struct{}, cmdRunner exec.CmdRunner) *Kapp {
globalDeployRawOpts []string, cancelCh chan struct{}, cmdRunner exec.CmdRunner, appNamespace string) *Kapp {

return &Kapp{appSuffix, opts, clusterAccess, globalDeployRawOpts, cancelCh, cmdRunner, nil}
return &Kapp{appSuffix, opts, clusterAccess, globalDeployRawOpts, cancelCh, cmdRunner, nil, appNamespace}
}

// Deploy takes the output from templating, and the app name,
Expand All @@ -62,7 +63,7 @@ func (a *Kapp) Deploy(tplOutput string, startedApplyingFunc func(),

metadataFile := filepath.Join(tmpMetadataDir.Path(), "app-metadata.yml")

args, err := a.addDeployArgs([]string{"deploy", "--app-metadata-file-output", metadataFile, "--prev-app", a.oldManagedName(), "-f", "-"})
args, err := a.addDeployArgs([]string{"deploy", "--app-metadata-file-output", metadataFile, "--prev-app", a.oldManagedName(), "-f", "-", "--app-namespace", a.appNamespace})
if err != nil {
return exec.NewCmdRunResultWithErr(err)
}
Expand All @@ -89,7 +90,7 @@ func (a *Kapp) Deploy(tplOutput string, startedApplyingFunc func(),

// Delete takes the app name, it shells out, running kapp delete ...
func (a *Kapp) Delete(startedApplyingFunc func(), changedFunc func(exec.CmdRunResult)) exec.CmdRunResult {
args, err := a.addDeleteArgs([]string{"delete", "--prev-app", a.oldManagedName()})
args, err := a.addDeleteArgs([]string{"delete", "--prev-app", a.oldManagedName(), "--app-namespace", a.appNamespace})
if err != nil {
return exec.NewCmdRunResultWithErr(err)
}
Expand Down Expand Up @@ -119,6 +120,7 @@ func (a *Kapp) Inspect() exec.CmdRunResult {
// TODO is there a better way to deal with this?
"--filter", `{"not":{"resource":{"kinds":["PodMetrics"]}}}`,
"--tty",
"--app-namespace", a.appNamespace,
})
if err != nil {
return exec.NewCmdRunResultWithErr(err)
Expand Down
6 changes: 5 additions & 1 deletion pkg/kubeconfig/kubeconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func NewKubeconfig(coreClient kubernetes.Interface, log logr.Logger) *Kubeconfig

// ClusterAccess takes cluster info and a ServiceAccount Name, and returns a populated kubeconfig that can connect to a cluster.
// if the saName is empty then you'll connect to a cluster via the clusterOpts inside the genericOpts, otherwise you'll use the specified SA.
func (k Kubeconfig) ClusterAccess(saName string, clusterOpts *v1alpha1.AppCluster, accessLocation AccessLocation) (AccessInfo, error) {
func (k Kubeconfig) ClusterAccess(saName string, clusterOpts *v1alpha1.AppCluster, accessLocation AccessLocation, preferredNamespace string) (AccessInfo, error) {
var err error
var clusterAccessInfo AccessInfo

Expand All @@ -67,5 +67,9 @@ func (k Kubeconfig) ClusterAccess(saName string, clusterOpts *v1alpha1.AppCluste
default:
return AccessInfo{}, fmt.Errorf("Expected service account or cluster specified")
}

// If preferredNamespace is "", then kubeconfig preferred namespace will be used
clusterAccessInfo.Namespace = preferredNamespace

return clusterAccessInfo, nil
}
1 change: 1 addition & 0 deletions pkg/packageinstall/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func NewApp(existingApp *v1alpha1.App, pkgInstall *pkgingv1alpha1.PackageInstall
desiredApp.Spec.Paused = pkgInstall.Spec.Paused
desiredApp.Spec.Canceled = pkgInstall.Spec.Canceled
desiredApp.Spec.Cluster = pkgInstall.Spec.Cluster
desiredApp.Spec.DefaultNamespace = pkgInstall.Spec.DefaultNamespace

err := controllerutil.SetControllerReference(pkgInstall, desiredApp, scheme.Scheme)
if err != nil {
Expand Down
39 changes: 39 additions & 0 deletions pkg/packageinstall/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -677,3 +677,42 @@ func TestAppPackageDetailsAnnotations(t *testing.T) {

require.Equal(t, expectedObjectMeta, app.ObjectMeta)
}

// TestAppPackageIntallDefaultNamespace tests the creation of an App when using PackageInstall with a defaultNamespace defined.
func TestAppPackageIntallDefaultNamespace(t *testing.T) {
ipkg := &pkgingv1alpha1.PackageInstall{
ObjectMeta: metav1.ObjectMeta{
Name: "app",
Namespace: "default",
},
Spec: pkgingv1alpha1.PackageInstallSpec{
DefaultNamespace: "default-namespace",
SyncPeriod: &metav1.Duration{100 * time.Second},
},
}

pkgVersion := datapkgingv1alpha1.Package{
Spec: datapkgingv1alpha1.PackageSpec{
RefName: "expec-pkg",
Version: "1.5.0",
Template: datapkgingv1alpha1.AppTemplateSpec{
Spec: &kcv1alpha1.AppSpec{},
},
},
}

app, err := packageinstall.NewApp(&kcv1alpha1.App{}, ipkg, pkgVersion, packageinstall.Opts{})
require.NoError(t, err)

expectedApp := &kcv1alpha1.App{
Spec: kcv1alpha1.AppSpec{
DefaultNamespace: "default-namespace",
SyncPeriod: &metav1.Duration{100 * time.Second},
},
}

// Not interested in metadata in this test
app.ObjectMeta = metav1.ObjectMeta{}

require.Equal(t, expectedApp, app, "App does not match expected app")
}
1 change: 1 addition & 0 deletions pkg/packageinstall/packageinstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ func (pi *PackageInstallCR) reconcileDelete(modelStatus *reconciler.Status) (rec
if existingApp.Spec.Canceled != pi.model.Spec.Canceled {
existingApp.Spec.Canceled = pi.model.Spec.Canceled
}
existingApp.Spec.DefaultNamespace = pi.model.Spec.DefaultNamespace

if !equality.Semantic.DeepEqual(existingApp, unchangeExistingApp) {
existingApp, err = pi.kcclient.KappctrlV1alpha1().Apps(existingApp.Namespace).Update(
Expand Down
2 changes: 1 addition & 1 deletion pkg/pkgrepository/app_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,5 @@ func (a *App) delete() exec.CmdRunResult {

func (a *App) newKapp(kapp v1alpha1.AppDeployKapp, cancelCh chan struct{}) (*ctldep.Kapp, error) {
genericOpts := kubeconfig.AccessInfo{Name: a.app.Name, Namespace: a.app.Namespace}
return a.deployFactory.NewKappPrivilegedForPackageRepository(kapp, genericOpts, cancelCh)
return a.deployFactory.NewKappPrivilegedForPackageRepository(kapp, genericOpts, cancelCh, a.app.Namespace)
}
Loading

0 comments on commit 5aac6ae

Please sign in to comment.