Skip to content

Commit

Permalink
Issue argoproj#1167 - Document orphaned resources, update proj CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Matyushentsev authored and Alexander Matyushentsev committed Aug 22, 2019
1 parent 7ac9e6f commit 88453cf
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 10 deletions.
44 changes: 36 additions & 8 deletions cmd/argocd/commands/project.go
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"

"github.com/argoproj/argo-cd/errors"
argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
Expand All @@ -27,9 +28,11 @@ import (
)

type projectOpts struct {
description string
destinations []string
sources []string
description string
destinations []string
sources []string
orphanedResourcesEnabled bool
orphanedResourcesWarn bool
}

type policyOpts struct {
Expand Down Expand Up @@ -87,6 +90,20 @@ func addProjFlags(command *cobra.Command, opts *projectOpts) {
command.Flags().StringArrayVarP(&opts.destinations, "dest", "d", []string{},
"Permitted destination server and namespace (e.g. https://192.168.99.100:8443,default)")
command.Flags().StringArrayVarP(&opts.sources, "src", "s", []string{}, "Permitted git source repository URL")
command.Flags().BoolVar(&opts.orphanedResourcesEnabled, "orphaned-resources", false, "Enables orphaned resources monitoring")
command.Flags().BoolVar(&opts.orphanedResourcesWarn, "orphaned-resources-warn", false, "Specifies if applications should be a warning condition when orphaned resources detected")
}

func getOrphanedResourcesSettings(c *cobra.Command, opts projectOpts) *v1alpha1.OrphanedResourcesMonitorSettings {
warnChanged := c.Flag("orphaned-resources-warn").Changed
if opts.orphanedResourcesEnabled || warnChanged {
settings := v1alpha1.OrphanedResourcesMonitorSettings{}
if warnChanged {
settings.Warn = pointer.BoolPtr(opts.orphanedResourcesWarn)
}
return &settings
}
return nil
}

func addPolicyFlags(command *cobra.Command, opts *policyOpts) {
Expand Down Expand Up @@ -117,9 +134,10 @@ func NewProjectCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm
proj := v1alpha1.AppProject{
ObjectMeta: v1.ObjectMeta{Name: projName},
Spec: v1alpha1.AppProjectSpec{
Description: opts.description,
Destinations: opts.GetDestinations(),
SourceRepos: opts.sources,
Description: opts.description,
Destinations: opts.GetDestinations(),
SourceRepos: opts.sources,
OrphanedResources: getOrphanedResourcesSettings(c, opts),
},
}
conn, projIf := argocdclient.NewClientOrDie(clientOpts).NewProjectClientOrDie()
Expand Down Expand Up @@ -163,6 +181,8 @@ func NewProjectSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
proj.Spec.Destinations = opts.GetDestinations()
case "src":
proj.Spec.SourceRepos = opts.sources
case "orphaned-resources", "orphaned-resources-warn":
proj.Spec.OrphanedResources = getOrphanedResourcesSettings(c, opts)
}
})
if visited == 0 {
Expand Down Expand Up @@ -453,7 +473,7 @@ func printProjectNames(projects []v1alpha1.AppProject) {
// Print table of project info
func printProjectTable(projects []v1alpha1.AppProject) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(w, "NAME\tDESCRIPTION\tDESTINATIONS\tSOURCES\tCLUSTER-RESOURCE-WHITELIST\tNAMESPACE-RESOURCE-BLACKLIST\n")
fmt.Fprintf(w, "NAME\tDESCRIPTION\tDESTINATIONS\tSOURCES\tCLUSTER-RESOURCE-WHITELIST\tNAMESPACE-RESOURCE-BLACKLIST\tORPHANED-RESOURCES\n")
for _, p := range projects {
printProjectLine(w, &p)
}
Expand Down Expand Up @@ -484,6 +504,13 @@ func NewProjectListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman
return command
}

func formatOrphanedResources(p *v1alpha1.AppProject) string {
if p.Spec.OrphanedResources == nil {
return "disabled"
}
return fmt.Sprintf("enabled (warn=%v)", p.Spec.OrphanedResources.IsWarn())
}

func printProjectLine(w io.Writer, p *v1alpha1.AppProject) {
var destinations, sourceRepos, clusterWhitelist, namespaceBlacklist string
switch len(p.Spec.Destinations) {
Expand Down Expand Up @@ -516,7 +543,7 @@ func printProjectLine(w io.Writer, p *v1alpha1.AppProject) {
default:
namespaceBlacklist = fmt.Sprintf("%d resources", len(p.Spec.NamespaceResourceBlacklist))
}
fmt.Fprintf(w, "%s\t%s\t%v\t%v\t%v\t%v\n", p.Name, p.Spec.Description, destinations, sourceRepos, clusterWhitelist, namespaceBlacklist)
fmt.Fprintf(w, "%s\t%s\t%v\t%v\t%v\t%v\t%v\n", p.Name, p.Spec.Description, destinations, sourceRepos, clusterWhitelist, namespaceBlacklist, formatOrphanedResources(p))
}

// NewProjectGetCommand returns a new instance of an `argocd proj get` command
Expand Down Expand Up @@ -577,6 +604,7 @@ func NewProjectGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
for i := 1; i < len(p.Spec.NamespaceResourceBlacklist); i++ {
fmt.Printf(printProjFmtStr, "", fmt.Sprintf("%s/%s", p.Spec.NamespaceResourceBlacklist[i].Group, p.Spec.NamespaceResourceBlacklist[i].Kind))
}
fmt.Printf(printProjFmtStr, "Orphaned Resources:", formatOrphanedResources(p))
},
}
return command
Expand Down
Binary file added docs/assets/orphaned-resources.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions docs/user-guide/orphaned-resources.md
@@ -0,0 +1,19 @@
# Orphaned Resources Monitoring

Orphaned Kubernetes resource is a top-level namespaced resource which does not belong to any Argo CD Application. The Orphaned Resources Monitoring feature allows detecting
orphaned resources, generate a warning and inspect/remove resources using Argo CD UI.

The Orphaned Resources monitoring is enabled in [Project](projects.md) settings. Once the feature is enabled each project application which target namespace has orphaned resource
will get a warning condition. The orphaned resources can be located using the application details page:

![orphaned resources](../assets/orphaned-resources.png)

Before enabling feature you might consider disabling warning. In this case application users are going to see orphaned resources in the UI but application is won't get a warning condition.

## Exceptions

Not every resource in the Kuberenetes cluster is controlled by the end user. Following resources are never considered as orphaned:

* Namespaced resources blacklisted in the project. Usually, such resources are managed by cluster administrators and not supposed to be modified by namespace user.
* `ServiceAccount` with name `default` ( and corresponding auto-generated `ServiceAccountToken` ).
* `Service` with name `kubernetes` in the `default` namespace.
1 change: 1 addition & 0 deletions mkdocs.yml
Expand Up @@ -48,6 +48,7 @@ nav:
- user-guide/private-repositories.md
- user-guide/auto_sync.md
- user-guide/diffing.md
- user-guide/orphaned-resources.md
- user-guide/compare-options.md
- user-guide/sync-options.md
- user-guide/parameters.md
Expand Down
13 changes: 11 additions & 2 deletions test/e2e/project_management_test.go
Expand Up @@ -44,7 +44,8 @@ func TestProjectCreation(t *testing.T) {
"--description", "Test description",
"-d", "https://192.168.99.100:8443,default",
"-d", "https://192.168.99.100:8443,service",
"-s", "https://github.com/argoproj/argo-cd.git")
"-s", "https://github.com/argoproj/argo-cd.git",
"--orphaned-resources")
assert.Nil(t, err)

proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(projectName, metav1.GetOptions{})
Expand All @@ -61,6 +62,9 @@ func TestProjectCreation(t *testing.T) {
assert.Equal(t, 1, len(proj.Spec.SourceRepos))
assert.Equal(t, "https://github.com/argoproj/argo-cd.git", proj.Spec.SourceRepos[0])

assert.NotNil(t, proj.Spec.OrphanedResources)
assert.True(t, proj.Spec.OrphanedResources.IsWarn())

assertProjHasEvent(t, proj, "create", argo.EventReasonResourceCreated)
}

Expand Down Expand Up @@ -89,7 +93,8 @@ func TestSetProject(t *testing.T) {
_, err = fixture.RunCli("proj", "set", projectName,
"--description", "updated description",
"-d", "https://192.168.99.100:8443,default",
"-d", "https://192.168.99.100:8443,service")
"-d", "https://192.168.99.100:8443,service",
"--orphaned-resources-warn=false")
assert.NoError(t, err)

proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(projectName, metav1.GetOptions{})
Expand All @@ -102,6 +107,10 @@ func TestSetProject(t *testing.T) {

assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[1].Server)
assert.Equal(t, "service", proj.Spec.Destinations[1].Namespace)

assert.NotNil(t, proj.Spec.OrphanedResources)
assert.False(t, proj.Spec.OrphanedResources.IsWarn())

assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated)
}

Expand Down

0 comments on commit 88453cf

Please sign in to comment.