Skip to content

Commit

Permalink
docs: document 'top level' packages (#44)
Browse files Browse the repository at this point in the history
* docs: document cache package

* docs: document diff package

* docs: document health package

* docs: document sync package

* docs: document engine package

* docs: document sync options
  • Loading branch information
Alexander Matyushentsev authored Jun 1, 2020
1 parent 99bd42d commit df17961
Show file tree
Hide file tree
Showing 13 changed files with 301 additions and 29 deletions.
9 changes: 0 additions & 9 deletions pkg/cache/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ type ClusterCache interface {
GetManagedLiveObjs(targetObjs []*unstructured.Unstructured, isManaged func(r *Resource) bool) (map[kube.ResourceKey]*unstructured.Unstructured, error)
// GetClusterInfo returns cluster cache statistics
GetClusterInfo() ClusterInfo
// SetPopulateResourceInfoHandler sets callback that populates resource information in the cache
SetPopulateResourceInfoHandler(handler OnPopulateResourceInfoHandler)
// OnResourceUpdated register event handler that is executed every time when resource get's updated in the cache
OnResourceUpdated(handler OnResourceUpdatedHandler) Unsubscribe
// OnEvent register event handler that is executed every time when new K8S event received
Expand Down Expand Up @@ -140,13 +138,6 @@ type clusterCache struct {
eventHandlers map[uint64]OnEventHandler
}

// SetPopulateResourceInfoHandler sets callback that populates resource information in the cache
func (c *clusterCache) SetPopulateResourceInfoHandler(handler OnPopulateResourceInfoHandler) {
c.handlersLock.Lock()
defer c.handlersLock.Unlock()
c.populateResourceInfoHandler = handler
}

// OnResourceUpdated register event handler that is executed every time when resource get's updated in the cache
func (c *clusterCache) OnResourceUpdated(handler OnResourceUpdatedHandler) Unsubscribe {
c.handlersLock.Lock()
Expand Down
60 changes: 58 additions & 2 deletions pkg/cache/cluster_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package cache

import (
"fmt"
"sort"
"strings"
"testing"
"time"

"github.com/ghodss/yaml"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -241,9 +243,9 @@ func TestGetChildren(t *testing.T) {

func TestGetManagedLiveObjs(t *testing.T) {
cluster := newCluster(testPod, testRS, testDeploy)
cluster.SetPopulateResourceInfoHandler(func(un *unstructured.Unstructured, isRoot bool) (info interface{}, cacheManifest bool) {
cluster.Invalidate(SetPopulateResourceInfoHandler(func(un *unstructured.Unstructured, isRoot bool) (info interface{}, cacheManifest bool) {
return nil, true
})
}))

err := cluster.EnsureSynced()
assert.Nil(t, err)
Expand Down Expand Up @@ -398,3 +400,57 @@ func TestGetDuplicatedChildren(t *testing.T) {
assert.Equal(t, testRS.GetName(), children[0].Ref.Name)
}
}

func ExampleNewClusterCache_inspectNamespaceResources() {
// kubernetes cluster config here
config := &rest.Config{}

clusterCache := NewClusterCache(config,
// cache default namespace only
SetNamespaces([]string{"default", "kube-system"}),
// configure custom logic to cache resources manifest and additional metadata
SetPopulateResourceInfoHandler(func(un *unstructured.Unstructured, isRoot bool) (info interface{}, cacheManifest bool) {
// if resource belongs to 'extensions' group then mark if with 'deprecated' label
if un.GroupVersionKind().Group == "extensions" {
info = []string{"deprecated"}
}
_, ok := un.GetLabels()["acme.io/my-label"]
// cache whole manifest if resource has label
cacheManifest = ok
return
}),
)
// Ensure cluster is synced before using it
if err := clusterCache.EnsureSynced(); err != nil {
panic(err)
}
// Iterate default namespace resources tree
for _, root := range clusterCache.GetNamespaceTopLevelResources("default") {
clusterCache.IterateHierarchy(root.ResourceKey(), func(resource *Resource, _ map[kube.ResourceKey]*Resource) {
println(fmt.Sprintf("resource: %s, info: %v", resource.Ref.String(), resource.Info))
})
}
}

func ExampleNewClusterCache_resourceUpdatedEvents() {
// kubernetes cluster config here
config := &rest.Config{}

clusterCache := NewClusterCache(config)
// Ensure cluster is synced before using it
if err := clusterCache.EnsureSynced(); err != nil {
panic(err)
}
unsubscribe := clusterCache.OnResourceUpdated(func(newRes *Resource, oldRes *Resource, _ map[kube.ResourceKey]*Resource) {
if newRes == nil {
println(fmt.Sprintf("%s deleted", oldRes.Ref.String()))
} else if oldRes == nil {
println(fmt.Sprintf("%s created", newRes.Ref.String()))
} else {
println(fmt.Sprintf("%s updated", newRes.Ref.String()))
}
})
defer unsubscribe()
// observe resource modifications for 1 minute
time.Sleep(time.Minute)
}
9 changes: 9 additions & 0 deletions pkg/cache/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
Package cache implements lightweight Kubernetes cluster caching that stores only resource references and ownership
references. In addition to references cache might be configured to store custom metadata and whole body of selected
resources.
The library uses Kubernetes watch API to maintain cache up to date. This approach reduces number of Kubernetes
API requests and provides instant access to the required Kubernetes resources.
*/
package cache
14 changes: 9 additions & 5 deletions pkg/cache/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ import (
"github.com/argoproj/gitops-engine/pkg/utils/kube"
)

// Resource holds the information about Kubernetes resource, ownership references and optional information
type Resource struct {
// ResourceVersion holds most recent observed resource version
ResourceVersion string
Ref v1.ObjectReference
OwnerRefs []metav1.OwnerReference
Info interface{}

// available only for root application nodes
// Resource reference
Ref v1.ObjectReference
// References to resource owners
OwnerRefs []metav1.OwnerReference
// Optional additional information about the resource
Info interface{}
// Optional whole resource manifest
Resource *unstructured.Unstructured
}

Expand Down
7 changes: 7 additions & 0 deletions pkg/cache/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ func SetKubectl(kubectl kube.Kubectl) func(cache *clusterCache) {

type UpdateSettingsFunc func(cache *clusterCache)

// SetPopulateResourceInfoHandler updates handler that populates resource info
func SetPopulateResourceInfoHandler(handler OnPopulateResourceInfoHandler) UpdateSettingsFunc {
return func(cache *clusterCache) {
cache.populateResourceInfoHandler = handler
}
}

// SetSettings updates caching settings
func SetSettings(settings Settings) UpdateSettingsFunc {
return func(cache *clusterCache) {
Expand Down
19 changes: 15 additions & 4 deletions pkg/diff/diff.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
The package provide functions that allows to compare set of Kubernetes resources using the logic equivalent to
`kubectl diff`.
*/
package diff

import (
Expand Down Expand Up @@ -27,18 +31,25 @@ import (
jsonutil "github.com/argoproj/gitops-engine/pkg/utils/json"
)

// Holds diffing settings
type DiffOptions struct {
// If set to true then differences caused by aggregated roles in RBAC resources are ignored.
IgnoreAggregatedRoles bool `json:"ignoreAggregatedRoles,omitempty"`
}

// Holds diffing result of two resources
type DiffResult struct {
// Deprecated: Use PredictedLive and NormalizedLive instead
Diff gojsondiff.Diff
Modified bool
PredictedLive []byte
// Modified is set to true if resources are not matching
Modified bool
// Contains YAML representation of a live resource with applied normalizations
NormalizedLive []byte
// Contains "expected" YAML representation of a live resource
PredictedLive []byte
// Deprecated: Use PredictedLive and NormalizedLive instead
Diff gojsondiff.Diff
}

// Holds result of two resources sets comparison
type DiffResultList struct {
Diffs []DiffResult
Modified bool
Expand Down
49 changes: 49 additions & 0 deletions pkg/diff/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,3 +723,52 @@ spec:
assert.Equal(t, float64(0.2), requestsBefore["cpu"])
assert.Equal(t, "200m", requestsAfter["cpu"])
}

func ExampleDiff() {
expectedResource := unstructured.Unstructured{}
if err := yaml.Unmarshal([]byte(`
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- image: nginx:1.7.9
name: nginx
resources:
requests:
cpu: 0.2
`), &expectedResource); err != nil {
panic(err)
}

liveResource := unstructured.Unstructured{}
if err := yaml.Unmarshal([]byte(`
apiVersion: v1
kind: Pod
metadata:
name: my-pod-123
creationTimestamp: "2020-03-30T21:34:59Z"
labels:
pod-template-hash: 84bf9649fd
name: argo-cd-cli-84bf9649fd-tm59q
resourceVersion: "233081332"
uid: 9a5ae31a-eed2-4f82-81fe-833799c54f99
spec:
containers:
- image: nginx:1.7.9
name: nginx
resources:
requests:
cpu: 0.1
`), &liveResource); err != nil {
panic(err)
}
diff, err := Diff(&expectedResource, &liveResource, GetNoopNormalizer(), GetDefaultDiffOptions())
if err != nil {
panic(err)
}
if diff.Modified {
println("Resources are different")
}
}
12 changes: 12 additions & 0 deletions pkg/engine/engine.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
/*
The package provides high-level interface that leverages "pkg/cache", "pkg/sync", "pkg/health" and "pkg/diff" packages
and "implements" GitOps.
Example
The https://github.com/argoproj/gitops-engine/tree/master/agent demonstrates how to use the engine.
*/

package engine

import (
Expand All @@ -24,7 +33,9 @@ const (
)

type GitOpsEngine interface {
// Run initializes engine
Run() (io.Closer, error)
// Synchronizes resources in the cluster
Sync(ctx context.Context, resources []*unstructured.Unstructured, isManaged func(r *cache.Resource) bool, revision string, namespace string, opts ...sync.SyncOpt) ([]common.ResourceSyncResult, error)
}

Expand All @@ -34,6 +45,7 @@ type gitOpsEngine struct {
kubectl kube.Kubectl
}

// NewEngine creates new instances of the GitOps engine
func NewEngine(config *rest.Config, clusterCache cache.ClusterCache) GitOpsEngine {
return &gitOpsEngine{
config: config,
Expand Down
21 changes: 16 additions & 5 deletions pkg/health/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,32 @@ import (
"github.com/argoproj/gitops-engine/pkg/utils/kube"
)

// Represents resource health status
type HealthStatusCode string

const (
HealthStatusUnknown HealthStatusCode = "Unknown"
// Indicates that health assessment failed and actual health status is unknown
HealthStatusUnknown HealthStatusCode = "Unknown"
// Progressing health status means that resource is not healthy but still have a chance to reach healthy state
HealthStatusProgressing HealthStatusCode = "Progressing"
HealthStatusHealthy HealthStatusCode = "Healthy"
HealthStatusSuspended HealthStatusCode = "Suspended"
HealthStatusDegraded HealthStatusCode = "Degraded"
HealthStatusMissing HealthStatusCode = "Missing"
// Resource is 100% healthy
HealthStatusHealthy HealthStatusCode = "Healthy"
// Assigned to resources that are suspended or paused. The typical example is a
// [suspended](https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/#suspend) CronJob.
HealthStatusSuspended HealthStatusCode = "Suspended"
// Degrade status is used if resource status indicates failure or resource could not reach healthy state
// within some timeout.
HealthStatusDegraded HealthStatusCode = "Degraded"
// Indicates that resource is missing in the cluster.
HealthStatusMissing HealthStatusCode = "Missing"
)

// Implements custom health assessment that overrides built-in assessment
type HealthOverride interface {
GetResourceHealth(obj *unstructured.Unstructured) (*HealthStatus, error)
}

// Holds health assessment results
type HealthStatus struct {
Status HealthStatusCode `json:"status,omitempty"`
Message string `json:"message,omitempty"`
Expand Down
4 changes: 4 additions & 0 deletions pkg/health/health_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
Package provides functionality that allows assessing the health state of a Kubernetes resource.
*/

package health

import (
Expand Down
7 changes: 7 additions & 0 deletions pkg/sync/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ const (
AnnotationKeyHook = "argocd.argoproj.io/hook"
// AnnotationKeyHookDeletePolicy is the policy of deleting a hook
AnnotationKeyHookDeletePolicy = "argocd.argoproj.io/hook-delete-policy"

// Sync option that disables dry run in resource is missing in the cluster
SyncOptionSkipDryRunOnMissingResource = "SkipDryRunOnMissingResource=true"
// Sync option that disables resource pruning
SyncOptionDisablePrune = "Prune=false"
// Sync option that disables resource validation
SyncOptionsDisableValidation = "Validate=false"
)

type PermissionValidator func(un *unstructured.Unstructured, res *metav1.APIResource) error
Expand Down
Loading

0 comments on commit df17961

Please sign in to comment.