Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add defaultNamespace in pkgi/app crs #1317

Merged
merged 1 commit into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
praveenrewar marked this conversation as resolved.
Show resolved Hide resolved
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
Loading