Skip to content

Commit

Permalink
provide utility helpers for preserving internal annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
natasha41575 committed Oct 28, 2021
1 parent 5765ab4 commit 89f36d8
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 7 deletions.
1 change: 1 addition & 0 deletions api/resource/resource.go
Expand Up @@ -26,6 +26,7 @@ type Resource struct {
refVarNames []string
}

// nolint
var BuildAnnotations = []string{
utils.BuildAnnotationPreviousKinds,
utils.BuildAnnotationPreviousNames,
Expand Down
1 change: 1 addition & 0 deletions cmd/config/internal/commands/cat.go
Expand Up @@ -166,6 +166,7 @@ func (r *CatRunner) catFilters() []kio.Filter {
return fltrs
}

// nolint
func (r *CatRunner) out(w io.Writer) ([]kio.Writer, error) {
var outputs []kio.Writer
var functionConfig *yaml.RNode
Expand Down
1 change: 1 addition & 0 deletions cmd/config/internal/commands/sink.go
Expand Up @@ -46,6 +46,7 @@ See discussion in https://github.com/kubernetes-sigs/kustomize/issues/3953.`)
return err
}

// nolint
func (r *SinkRunner) runE(c *cobra.Command, args []string) error {
var outputs []kio.Writer
if len(args) == 1 {
Expand Down
102 changes: 95 additions & 7 deletions kyaml/kio/kioutil/kioutil.go
Expand Up @@ -17,25 +17,29 @@ import (
type AnnotationKey = string

const (
// internalPrefix is the prefix given to internal annotations that are used
// internally by the orchestrator
internalPrefix string = "internal.config.kubernetes.io/"

// IndexAnnotation records the index of a specific resource in a file or input stream.
IndexAnnotation AnnotationKey = "internal.config.kubernetes.io/index"
IndexAnnotation AnnotationKey = internalPrefix + "index"

// PathAnnotation records the path to the file the Resource was read from
PathAnnotation AnnotationKey = "internal.config.kubernetes.io/path"
PathAnnotation AnnotationKey = internalPrefix + "path"

// SeqIndentAnnotation records the sequence nodes indentation of the input resource
SeqIndentAnnotation AnnotationKey = "internal.config.kubernetes.io/seqindent"
SeqIndentAnnotation AnnotationKey = internalPrefix + "seqindent"

// IdAnnotation records the id of the resource to map inputs to outputs
IdAnnotation = "internal.config.kubernetes.io/id"
IdAnnotation AnnotationKey = internalPrefix + "id"

// LegacyIndexAnnotation is the deprecated annotation key for resource index
// Deprecated: LegacyIndexAnnotation is deprecated.
LegacyIndexAnnotation AnnotationKey = "config.kubernetes.io/index"

// LegacyPathAnnotation is the deprecated annotation key for resource path
// Deprecated: LegacyPathAnnotation is deprecated.
LegacyPathAnnotation AnnotationKey = "config.kubernetes.io/path"

// LegacyIdAnnotation is the deprecated annotation key for resource ids
// Deprecated: LegacyIdAnnotation is deprecated.
LegacyIdAnnotation = "config.k8s.io/id"
)

Expand Down Expand Up @@ -311,3 +315,87 @@ func SortNodes(nodes []*yaml.RNode) error {
})
return errors.Wrap(err)
}

// CopyInternalAnnotations copies the annotations that begin with the prefix
// `internal.config.kubernetes.io` from the source RNode to the destination RNode.
// It takes a parameter exclusions, which is a list of annotation keys to ignore.
func CopyInternalAnnotations(src *yaml.RNode, dst *yaml.RNode, exclusions ...AnnotationKey) error {
srcAnnotations := GetInternalAnnotations(src)
for k, v := range srcAnnotations {
if stringSliceContains(exclusions, k) {
continue
}
if err := dst.PipeE(yaml.SetAnnotation(k, v)); err != nil {
return err
}
}
return nil
}

// ConfirmInternalAnnotationUnchanged compares the annotations of the RNodes that begin with the prefix
// `internal.config.kubernetes.io`, throwing an error if they differ. // It takes a parameter exclusions,
// which is a list of annotation keys to ignore.
func ConfirmInternalAnnotationUnchanged(r1 *yaml.RNode, r2 *yaml.RNode, exclusions ...AnnotationKey) error {
r1Annotations := GetInternalAnnotations(r1)
r2Annotations := GetInternalAnnotations(r2)

// this is a map to prevent duplicates
diffAnnos := make(map[string]bool)

for k, v1 := range r1Annotations {
if stringSliceContains(exclusions, k) {
continue
}
if v2, ok := r2Annotations[k]; !ok || v1 != v2 {
diffAnnos[k] = true
}
}

for k, v2 := range r2Annotations {
if stringSliceContains(exclusions, k) {
continue
}
if v1, ok := r1Annotations[k]; !ok || v2 != v1 {
diffAnnos[k] = true
}
}

if len(diffAnnos) > 0 {
keys := make([]string, 0, len(diffAnnos))
for k := range diffAnnos {
keys = append(keys, k)
}
sort.Strings(keys)

errorString := "internal annotations differ: "
for _, key := range keys {
errorString = errorString + key + ", "
}
return errors.Errorf(errorString[0 : len(errorString)-2])
}

return nil
}

// GetInternalAnnotations returns a map of all the annotations of the provided RNode that begin
// with the prefix `internal.config.kubernetes.io`
func GetInternalAnnotations(rn *yaml.RNode) map[string]string {
annotations := rn.GetAnnotations()
result := make(map[string]string)
for k, v := range annotations {
if strings.HasPrefix(k, internalPrefix) {
result[k] = v
}
}
return result
}

// stringSliceContains returns true if the slice has the string.
func stringSliceContains(slice []string, str string) bool {
for _, s := range slice {
if s == str {
return true
}
}
return false
}

0 comments on commit 89f36d8

Please sign in to comment.