mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-12 01:14:22 +00:00
kyaml setters: support full and partial field replacement
This commit is contained in:
@@ -34,6 +34,8 @@ func NewCreateSetterRunner(parent string) *CreateSetterRunner {
|
|||||||
"kind of the Resource on which to create the setter.")
|
"kind of the Resource on which to create the setter.")
|
||||||
set.Flags().StringVar(&r.Set.SetPartialField.Type, "type", "",
|
set.Flags().StringVar(&r.Set.SetPartialField.Type, "type", "",
|
||||||
"valid OpenAPI field type -- e.g. integer,boolean,string.")
|
"valid OpenAPI field type -- e.g. integer,boolean,string.")
|
||||||
|
set.Flags().BoolVar(&r.Set.SetPartialField.Partial, "partial", false,
|
||||||
|
"create a partial setter for only part of the field value.")
|
||||||
fixDocs(parent, set)
|
fixDocs(parent, set)
|
||||||
set.MarkFlagRequired("type")
|
set.MarkFlagRequired("type")
|
||||||
set.MarkFlagRequired("field")
|
set.MarkFlagRequired("field")
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ type FieldMeta struct {
|
|||||||
|
|
||||||
type XKustomize struct {
|
type XKustomize struct {
|
||||||
SetBy string `yaml:"setBy,omitempty" json:"setBy,omitempty"`
|
SetBy string `yaml:"setBy,omitempty" json:"setBy,omitempty"`
|
||||||
PartialFieldSetters []PartialFieldSetter `yaml:"partialFieldSetters" json:"partialFieldSetters"`
|
PartialFieldSetters []PartialFieldSetter `yaml:"partialSetters,omitempty" json:"partialSetters,omitempty"`
|
||||||
|
FieldSetter *PartialFieldSetter `yaml:"setter,omitempty" json:"setter,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PartialFieldSetter defines how to set part of a field rather than the full field
|
// PartialFieldSetter defines how to set part of a field rather than the full field
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ type customFieldSetter struct {
|
|||||||
|
|
||||||
Type string
|
Type string
|
||||||
|
|
||||||
|
// Partial will create a partial setter if set to true
|
||||||
|
Partial bool
|
||||||
|
|
||||||
// currentFieldName is the name of the current field being processed
|
// currentFieldName is the name of the current field being processed
|
||||||
currentFieldName string
|
currentFieldName string
|
||||||
}
|
}
|
||||||
@@ -66,11 +69,6 @@ func (m *customFieldSetter) Filter(object *yaml.RNode) (*yaml.RNode, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *customFieldSetter) create(field *yaml.RNode) error {
|
func (m *customFieldSetter) create(field *yaml.RNode) error {
|
||||||
// doesn't match the supplied value
|
|
||||||
if !strings.Contains(field.YNode().Value, m.Setter.Value) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
fm := fieldmeta.FieldMeta{}
|
fm := fieldmeta.FieldMeta{}
|
||||||
if err := fm.Read(field); err != nil {
|
if err := fm.Read(field); err != nil {
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
@@ -83,6 +81,19 @@ func (m *customFieldSetter) create(field *yaml.RNode) error {
|
|||||||
fm.Extensions.SetBy = m.SetBy
|
fm.Extensions.SetBy = m.SetBy
|
||||||
fm.Schema.Type = []string{m.Type}
|
fm.Schema.Type = []string{m.Type}
|
||||||
|
|
||||||
|
if !m.Partial {
|
||||||
|
// doesn't match the supplied value
|
||||||
|
if field.YNode().Value != m.Setter.Value {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// full setter
|
||||||
|
fm.Extensions.FieldSetter = &m.Setter
|
||||||
|
fm.Extensions.PartialFieldSetters = nil
|
||||||
|
} else {
|
||||||
|
// doesn't match the supplied value
|
||||||
|
if !strings.Contains(field.YNode().Value, m.Setter.Value) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
found := false
|
found := false
|
||||||
for i := range fm.Extensions.PartialFieldSetters {
|
for i := range fm.Extensions.PartialFieldSetters {
|
||||||
s := fm.Extensions.PartialFieldSetters[i]
|
s := fm.Extensions.PartialFieldSetters[i]
|
||||||
@@ -97,6 +108,8 @@ func (m *customFieldSetter) create(field *yaml.RNode) error {
|
|||||||
// add the setter if it wasn't found
|
// add the setter if it wasn't found
|
||||||
fm.Extensions.PartialFieldSetters = append(fm.Extensions.PartialFieldSetters, m.Setter)
|
fm.Extensions.PartialFieldSetters = append(fm.Extensions.PartialFieldSetters, m.Setter)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := fm.Write(field); err != nil {
|
if err := fm.Write(field); err != nil {
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type PerformSetters struct {
|
|||||||
|
|
||||||
func (s *PerformSetters) Filter(input []*yaml.RNode) ([]*yaml.RNode, error) {
|
func (s *PerformSetters) Filter(input []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||||
for i := range input {
|
for i := range input {
|
||||||
p := &partialFieldSetter{
|
p := &fieldSetter{
|
||||||
Name: s.Name,
|
Name: s.Name,
|
||||||
Value: s.Value,
|
Value: s.Value,
|
||||||
Description: s.Description,
|
Description: s.Description,
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ import (
|
|||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ yaml.Filter = &partialFieldSetter{}
|
var _ yaml.Filter = &fieldSetter{}
|
||||||
|
|
||||||
// partialFieldSetter sets part of a field value.
|
// fieldSetter sets part or all of a field value.
|
||||||
type partialFieldSetter struct {
|
type fieldSetter struct {
|
||||||
// Name is the name of the setter to perform.
|
// Name is the name of the setter to perform.
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ type partialFieldSetter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter implements yaml.Filter
|
// Filter implements yaml.Filter
|
||||||
func (fs *partialFieldSetter) Filter(object *yaml.RNode) (*yaml.RNode, error) {
|
func (fs *fieldSetter) Filter(object *yaml.RNode) (*yaml.RNode, error) {
|
||||||
switch object.YNode().Kind {
|
switch object.YNode().Kind {
|
||||||
case yaml.DocumentNode:
|
case yaml.DocumentNode:
|
||||||
// Document is the root of the object and always contains 1 node
|
// Document is the root of the object and always contains 1 node
|
||||||
@@ -49,7 +49,7 @@ func (fs *partialFieldSetter) Filter(object *yaml.RNode) (*yaml.RNode, error) {
|
|||||||
})
|
})
|
||||||
case yaml.ScalarNode:
|
case yaml.ScalarNode:
|
||||||
// Check if there is a setter matching the name
|
// Check if there is a setter matching the name
|
||||||
s, f, err := fs.findPartialSetter(object)
|
s, f, partial, err := fs.findSetter(object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -58,19 +58,19 @@ func (fs *partialFieldSetter) Filter(object *yaml.RNode) (*yaml.RNode, error) {
|
|||||||
return object, nil
|
return object, nil
|
||||||
}
|
}
|
||||||
// set the field value
|
// set the field value
|
||||||
return object, fs.set(object, s, f)
|
return object, fs.set(object, s, f, partial)
|
||||||
default:
|
default:
|
||||||
return object, nil
|
return object, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// findPartialSetter finds the setter matching the name if one exists
|
// findPartialSetter finds the setter matching the name if one exists
|
||||||
func (fs *partialFieldSetter) findPartialSetter(field *yaml.RNode) (
|
func (fs *fieldSetter) findSetter(field *yaml.RNode) (
|
||||||
*fieldmeta.PartialFieldSetter, *fieldmeta.FieldMeta, error) {
|
*fieldmeta.PartialFieldSetter, *fieldmeta.FieldMeta, bool, error) {
|
||||||
// check if there are any substitutions for this field
|
// check if there are any substitutions for this field
|
||||||
var fm = &fieldmeta.FieldMeta{}
|
var fm = &fieldmeta.FieldMeta{}
|
||||||
if err := fm.Read(field); err != nil {
|
if err := fm.Read(field); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, false, err
|
||||||
}
|
}
|
||||||
if fs.SetBy != "" {
|
if fs.SetBy != "" {
|
||||||
fm.Extensions.SetBy = fs.SetBy
|
fm.Extensions.SetBy = fs.SetBy
|
||||||
@@ -79,18 +79,23 @@ func (fs *partialFieldSetter) findPartialSetter(field *yaml.RNode) (
|
|||||||
fm.Schema.Description = fs.Description
|
fm.Schema.Description = fs.Description
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fm.Extensions.FieldSetter != nil && fm.Extensions.FieldSetter.Name == fs.Name {
|
||||||
|
return fm.Extensions.FieldSetter, fm, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
// check if there is a matching substitution
|
// check if there is a matching substitution
|
||||||
for i := range fm.Extensions.PartialFieldSetters {
|
for i := range fm.Extensions.PartialFieldSetters {
|
||||||
if fm.Extensions.PartialFieldSetters[i].Name == fs.Name {
|
if fm.Extensions.PartialFieldSetters[i].Name == fs.Name {
|
||||||
return &fm.Extensions.PartialFieldSetters[i], fm, nil
|
return &fm.Extensions.PartialFieldSetters[i], fm, true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil, nil
|
return nil, nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// set performs the substitution for the given field, substitution, and metadata
|
// set performs the substitution for the given field, substitution, and metadata
|
||||||
func (fs *partialFieldSetter) set(
|
func (fs *fieldSetter) set(
|
||||||
field *yaml.RNode, s *fieldmeta.PartialFieldSetter, f *fieldmeta.FieldMeta) error {
|
field *yaml.RNode, s *fieldmeta.PartialFieldSetter,
|
||||||
|
f *fieldmeta.FieldMeta, partial bool) error {
|
||||||
if s.Value == fs.Value || !strings.Contains(field.YNode().Value, s.Value) {
|
if s.Value == fs.Value || !strings.Contains(field.YNode().Value, s.Value) {
|
||||||
// no substitutions necessary -- already substituted or doesn't have the set value
|
// no substitutions necessary -- already substituted or doesn't have the set value
|
||||||
// which acts as a marker
|
// which acts as a marker
|
||||||
@@ -100,8 +105,13 @@ func (fs *partialFieldSetter) set(
|
|||||||
// record that the config has been modified
|
// record that the config has been modified
|
||||||
fs.Count++
|
fs.Count++
|
||||||
|
|
||||||
|
if !partial {
|
||||||
|
// full setter
|
||||||
|
field.YNode().Value = fs.Value
|
||||||
|
} else {
|
||||||
// replace the current value with the new value
|
// replace the current value with the new value
|
||||||
field.YNode().Value = strings.ReplaceAll(field.YNode().Value, s.Value, fs.Value)
|
field.YNode().Value = strings.ReplaceAll(field.YNode().Value, s.Value, fs.Value)
|
||||||
|
}
|
||||||
|
|
||||||
// be sure to set the tag to the matching type so the yaml doesn't incorrectly quote
|
// be sure to set the tag to the matching type so the yaml doesn't incorrectly quote
|
||||||
//integers or booleans as strings
|
//integers or booleans as strings
|
||||||
|
|||||||
@@ -54,6 +54,22 @@ func (ls *lookupSetters) lookup(field *yaml.RNode) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fm.Extensions.FieldSetter != nil {
|
||||||
|
if ls.Name != "" && ls.Name != fm.Extensions.FieldSetter.Name {
|
||||||
|
// skip this setter, it doesn't match the specified setter
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// full setter
|
||||||
|
ls.Setters = append(ls.Setters, setter{
|
||||||
|
PartialFieldSetter: *fm.Extensions.FieldSetter,
|
||||||
|
Description: fm.Schema.Description,
|
||||||
|
Type: fm.Schema.Type[0],
|
||||||
|
SetBy: fm.Extensions.SetBy,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// partial setters
|
||||||
for i := range fm.Extensions.PartialFieldSetters {
|
for i := range fm.Extensions.PartialFieldSetters {
|
||||||
if ls.Name != "" && ls.Name != fm.Extensions.PartialFieldSetters[i].Name {
|
if ls.Name != "" && ls.Name != fm.Extensions.PartialFieldSetters[i].Name {
|
||||||
// skip this setter
|
// skip this setter
|
||||||
|
|||||||
Reference in New Issue
Block a user