diff --git a/Makefile b/Makefile index 4cbd534a..5118331f 100644 --- a/Makefile +++ b/Makefile @@ -201,7 +201,7 @@ unit-tests: $(BUILD_DIRS) ./hack/test.sh $(SRC_PKGS) \ " -ADDTL_LINTERS := goconst,gofmt,goimports,unparam +ADDTL_LINTERS := gofmt,goimports,unparam .PHONY: lint lint: $(BUILD_DIRS) diff --git a/go.mod b/go.mod index 3b927b26..8fb88969 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( k8s.io/utils v0.0.0-20220823124924-e9cbc92d1a73 kmodules.xyz/client-go v0.25.43 kmodules.xyz/offshoot-api v0.25.5 - kubestash.dev/apimachinery v0.2.0 + kubestash.dev/apimachinery v0.3.0 sigs.k8s.io/controller-runtime v0.13.1 ) @@ -109,7 +109,6 @@ require ( golang.org/x/term v0.13.0 // indirect golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect gomodules.xyz/clock v0.0.0-20200817085942-06523dba733f // indirect - gomodules.xyz/envsubst v0.2.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/mergo v0.3.13 // indirect gomodules.xyz/pointer v0.1.0 // indirect diff --git a/go.sum b/go.sum index 485b0441..6db68f23 100644 --- a/go.sum +++ b/go.sum @@ -372,8 +372,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -837,8 +837,6 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/clock v0.0.0-20200817085942-06523dba733f h1:hTyhR4r+tj1Uq7/PpFxLTzbeA0LhMVp7bEYfhkzFjdY= gomodules.xyz/clock v0.0.0-20200817085942-06523dba733f/go.mod h1:K3m7N+nBOlf91/tpv8REUGwsAgaKFwElQCuiLhm12AQ= -gomodules.xyz/envsubst v0.2.0 h1:piG4OcpUa/Mu7LxSo+2Ye8JH7pXXWM2XuCD8Ic7Hdwc= -gomodules.xyz/envsubst v0.2.0/go.mod h1:eB1KRKtXx6RSpl+WYxE8gFE7DhNJCoorHzSij7X3AQo= gomodules.xyz/flags v0.1.3 h1:jQ06+EfmoMv5NvjXvJon03dOhLU+FF0TQMWN7I6qpzs= gomodules.xyz/flags v0.1.3/go.mod h1:e+kvBLnqdEWGG670SKOYag1CXStM2Slrxq01OIK3tFs= gomodules.xyz/go-sh v0.1.0 h1:1BJAuGREh2RhePt7HRrpmjnkbgfpXlCzc42SiyZ5dkc= @@ -1069,8 +1067,8 @@ kmodules.xyz/offshoot-api v0.25.5 h1:erUtTDj9iljikd9CvrCz0E32P5mgEqq1NYxy06lxrNo kmodules.xyz/offshoot-api v0.25.5/go.mod h1:wotLtcXWHw6KrWX6Ry2EsHn2I2QTvyLX7gXAuwBjkFc= kmodules.xyz/prober v0.25.0 h1:R5uRLHJEvEtEoogj+vaTAob0Btph6+PX5IlS6hPh8PA= kmodules.xyz/prober v0.25.0/go.mod h1:z4RTnjaajNQa/vPltsiOnO3xI716I/ziD2ac2Exm+1M= -kubestash.dev/apimachinery v0.2.0 h1:xu6Um9Z0gFgMbKzUHIJAsvh+izJ6Nl4LJPyK4SUnntE= -kubestash.dev/apimachinery v0.2.0/go.mod h1:ouqYby7/IIHRJgadPc++tzh3vxtjIgk1pDzU0YRCCw4= +kubestash.dev/apimachinery v0.3.0 h1:0zkdiJeL3ONm4P53rJI9CQiTs8vF+OgOM1jbA+oM8RM= +kubestash.dev/apimachinery v0.3.0/go.mod h1:mZlerbYdxPXYFJQfOrXFDHBPV8NzZkVF1qHUsP0/Q0s= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/vendor/gomodules.xyz/envsubst/.drone.yml b/vendor/gomodules.xyz/envsubst/.drone.yml deleted file mode 100644 index 2b062137..00000000 --- a/vendor/gomodules.xyz/envsubst/.drone.yml +++ /dev/null @@ -1,8 +0,0 @@ -kind: pipeline -name: default - -steps: -- name: build - image: golang:1.11 - commands: - - go test -v ./... diff --git a/vendor/gomodules.xyz/envsubst/.gitignore b/vendor/gomodules.xyz/envsubst/.gitignore deleted file mode 100644 index 3fc8da69..00000000 --- a/vendor/gomodules.xyz/envsubst/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/envsubst -coverage.out -/vendor -.idea/ -.vscode/ diff --git a/vendor/gomodules.xyz/envsubst/LICENSE b/vendor/gomodules.xyz/envsubst/LICENSE deleted file mode 100644 index 1de55b7f..00000000 --- a/vendor/gomodules.xyz/envsubst/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 drone.io - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/gomodules.xyz/envsubst/eval.go b/vendor/gomodules.xyz/envsubst/eval.go deleted file mode 100644 index 6bc8e79d..00000000 --- a/vendor/gomodules.xyz/envsubst/eval.go +++ /dev/null @@ -1,57 +0,0 @@ -package envsubst - -import "os" - -// Eval replaces ${var} in the string based on the mapping function. -func Eval(s string, mapping func(string) string) (string, error) { - t, err := Parse(s) - if err != nil { - return s, err - } - // convert mapping to match new mapper function - mapper := func(node string, key string, args []string) (string, []string, error) { - return mapping(key), args, nil - } - return t.Execute(mapper) -} - -// EvalEnv replaces ${var} in the string according to the values of the -// current environment variables. References to undefined variables are -// replaced by the empty string. -func EvalEnv(s string) (string, error) { - return Eval(s, os.Getenv) -} - -func EvalMap(s string, values map[string]string) (string, error) { - if values == nil { - values = make(map[string]string) - } - mapper := func(node string, key string, args []string) (string, []string, error) { - v, ok := values[key] - // return error if key not found and default not specified - if !ok && !isDefault(node) { - return "", nil, &valueNotFoundError{key} - } - // if key found, remove args for default - // so that empty value will not be replaced by default value - if ok && isDefault(node) { - return v, nil, nil - } - return v, args, nil - } - - t, err := Parse(s) - if err != nil { - return s, err - } - return t.Execute(mapper) -} - -func isDefault(name string) bool { - switch name { - case "=", ":=", ":-": - return true - default: - return false - } -} diff --git a/vendor/gomodules.xyz/envsubst/funcs.go b/vendor/gomodules.xyz/envsubst/funcs.go deleted file mode 100644 index 82035c07..00000000 --- a/vendor/gomodules.xyz/envsubst/funcs.go +++ /dev/null @@ -1,246 +0,0 @@ -package envsubst - -import ( - "strconv" - "strings" - "unicode" - "unicode/utf8" - - "gomodules.xyz/envsubst/path" -) - -// defines a parameter substitution function. -type substituteFunc func(string, ...string) string - -// toLen returns the length of string s. -func toLen(s string, args ...string) string { - return strconv.Itoa(len(s)) -} - -// toLower returns a copy of the string s with all characters -// mapped to their lower case. -func toLower(s string, args ...string) string { - return strings.ToLower(s) -} - -// toUpper returns a copy of the string s with all characters -// mapped to their upper case. -func toUpper(s string, args ...string) string { - return strings.ToUpper(s) -} - -// toLowerFirst returns a copy of the string s with the first -// character mapped to its lower case. -func toLowerFirst(s string, args ...string) string { - if s == "" { - return s - } - r, n := utf8.DecodeRuneInString(s) - return string(unicode.ToLower(r)) + s[n:] -} - -// toUpperFirst returns a copy of the string s with the first -// character mapped to its upper case. -func toUpperFirst(s string, args ...string) string { - if s == "" { - return s - } - r, n := utf8.DecodeRuneInString(s) - return string(unicode.ToUpper(r)) + s[n:] -} - -// toDefault returns a copy of the string s if not empty, else -// returns a concatenation of the args without a separator. -func toDefault(s string, args ...string) string { - if len(s) == 0 && len(args) > 0 { - // don't use any separator - s = strings.Join(args, "") - } - return s -} - -// toSubstr returns a slice of the string s at the specified -// length and position. -func toSubstr(s string, args ...string) string { - if len(args) == 0 { - return s // should never happen - } - - pos, err := strconv.Atoi(args[0]) - if err != nil { - // bash returns the string if the position - // cannot be parsed. - return s - } - - if pos < 0 { - // if pos is negative (counts from the end) add it - // to length to get first character offset - pos = len(s) + pos - - // if negative offset exceeds the length of the string - // start from 0 - if pos < 0 { - pos = 0 - } - } - - if len(args) == 1 { - if pos < len(s) { - return s[pos:] - } - // if the position exceeds the length of the - // string an empty string is returned - return "" - } - - length, err := strconv.Atoi(args[1]) - if err != nil { - // bash returns the string if the length - // cannot be parsed. - return s - } - - if pos+length >= len(s) { - if pos < len(s) { - // if the position exceeds the length of the - // string just return the rest of it like bash - return s[pos:] - } - // if the position exceeds the length of the - // string an empty string is returned - return "" - } - - return s[pos : pos+length] -} - -// replaceAll returns a copy of the string s with all instances -// of the substring replaced with the replacement string. -func replaceAll(s string, args ...string) string { - switch len(args) { - case 0: - return s - case 1: - return strings.Replace(s, args[0], "", -1) - default: - return strings.Replace(s, args[0], args[1], -1) - } -} - -// replaceFirst returns a copy of the string s with the first -// instance of the substring replaced with the replacement string. -func replaceFirst(s string, args ...string) string { - switch len(args) { - case 0: - return s - case 1: - return strings.Replace(s, args[0], "", 1) - default: - return strings.Replace(s, args[0], args[1], 1) - } -} - -// replacePrefix returns a copy of the string s with the matching -// prefix replaced with the replacement string. -func replacePrefix(s string, args ...string) string { - if len(args) != 2 { - return s - } - if strings.HasPrefix(s, args[0]) { - return strings.Replace(s, args[0], args[1], 1) - } - return s -} - -// replaceSuffix returns a copy of the string s with the matching -// suffix replaced with the replacement string. -func replaceSuffix(s string, args ...string) string { - if len(args) != 2 { - return s - } - if strings.HasSuffix(s, args[0]) { - s = strings.TrimSuffix(s, args[0]) - s = s + args[1] - } - return s -} - -// TODO - -func trimShortestPrefix(s string, args ...string) string { - if len(args) != 0 { - s = trimShortest(s, args[0]) - } - return s -} - -func trimShortestSuffix(s string, args ...string) string { - if len(args) != 0 { - r := reverse(s) - rarg := reverse(args[0]) - s = reverse(trimShortest(r, rarg)) - } - return s -} - -func trimLongestPrefix(s string, args ...string) string { - if len(args) != 0 { - s = trimLongest(s, args[0]) - } - return s -} - -func trimLongestSuffix(s string, args ...string) string { - if len(args) != 0 { - r := reverse(s) - rarg := reverse(args[0]) - s = reverse(trimLongest(r, rarg)) - } - return s -} - -func trimShortest(s, arg string) string { - var shortestMatch string - for i := 0; i < len(s); i++ { - match, err := path.Match(arg, s[0:len(s)-i]) - - if err != nil { - return s - } - - if match { - shortestMatch = s[0 : len(s)-i] - } - } - - if shortestMatch != "" { - return strings.TrimPrefix(s, shortestMatch) - } - - return s -} - -func trimLongest(s, arg string) string { - for i := 0; i < len(s); i++ { - match, err := path.Match(arg, s[0:len(s)-i]) - - if err != nil { - return s - } - - if match { - return strings.TrimPrefix(s, s[0:len(s)-i]) - } - } - - return s -} - -func reverse(s string) string { - r := []rune(s) - for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { - r[i], r[j] = r[j], r[i] - } - return string(r) -} diff --git a/vendor/gomodules.xyz/envsubst/parse/node.go b/vendor/gomodules.xyz/envsubst/parse/node.go deleted file mode 100644 index 09787eb9..00000000 --- a/vendor/gomodules.xyz/envsubst/parse/node.go +++ /dev/null @@ -1,86 +0,0 @@ -package parse - -// Node is an element in the parse tree. -type Node interface { - node() -} - -// empty string node -var empty = new(TextNode) - -// a template is represented by a tree consisting of one -// or more of the following nodes. -type ( - // TextNode represents a string of text. - TextNode struct { - Value string - } - - // FuncNode represents a string function. - FuncNode struct { - Param string - Name string - Args []Node - } - - // ListNode represents a list of nodes. - ListNode struct { - Nodes []Node - } - - // ParamNode struct{ - // Name string - // } - // - // CaseNode struct { - // Name string - // First bool - // } - // - // LowerNode struct { - // Name string - // First bool - // } - // - // SubstrNode struct { - // Name string - // Pos Node - // Len Node - // } - // - // ReplaceNode struct { - // Name string - // Substring Node - // Replacement Node - // } - // - // TrimNode struct{ - // - // } - // - // DefaultNode struct { - // Name string - // Default Node - // } -) - -// newTextNode returns a new TextNode. -func newTextNode(text string) *TextNode { - return &TextNode{Value: text} -} - -// newListNode returns a new ListNode. -func newListNode(nodes ...Node) *ListNode { - return &ListNode{Nodes: nodes} -} - -// newFuncNode returns a new FuncNode. -func newFuncNode(name string) *FuncNode { - return &FuncNode{Param: name} -} - -// node() defines the node in a parse tree - -func (*TextNode) node() {} -func (*ListNode) node() {} -func (*FuncNode) node() {} diff --git a/vendor/gomodules.xyz/envsubst/parse/parse.go b/vendor/gomodules.xyz/envsubst/parse/parse.go deleted file mode 100644 index bc418fbf..00000000 --- a/vendor/gomodules.xyz/envsubst/parse/parse.go +++ /dev/null @@ -1,402 +0,0 @@ -package parse - -import ( - "errors" -) - -var ( - // ErrBadSubstitution represents a substitution parsing error. - ErrBadSubstitution = errors.New("bad substitution") - - // ErrMissingClosingBrace represents a missing closing brace "}" error. - ErrMissingClosingBrace = errors.New("missing closing brace") - - // ErrParseVariableName represents the error when unable to parse a - // variable name within a substitution. - ErrParseVariableName = errors.New("unable to parse variable name") - - // ErrParseFuncSubstitution represents the error when unable to parse the - // substitution within a function parameter. - ErrParseFuncSubstitution = errors.New("unable to parse substitution within function") - - // ErrParseDefaultFunction represent the error when unable to parse a - // default function. - ErrParseDefaultFunction = errors.New("unable to parse default function") -) - -// Tree is the representation of a single parsed SQL statement. -type Tree struct { - Root Node - - // Parsing only; cleared after parse. - scanner *scanner -} - -// Parse parses the string and returns a Tree. -func Parse(buf string) (*Tree, error) { - t := new(Tree) - t.scanner = new(scanner) - return t.Parse(buf) -} - -// Parse parses the string buffer to construct an ast -// representation for expansion. -func (t *Tree) Parse(buf string) (tree *Tree, err error) { - t.scanner.init(buf) - t.Root, err = t.parseAny() - return t, err -} - -func (t *Tree) parseAny() (Node, error) { - t.scanner.accept = acceptRune - t.scanner.mode = scanIdent | scanLbrack | scanEscape - t.scanner.escapeChars = dollar - - switch t.scanner.scan() { - case tokenIdent: - left := newTextNode( - t.scanner.string(), - ) - right, err := t.parseAny() - switch { - case err != nil: - return nil, err - case right == empty: - return left, nil - } - return newListNode(left, right), nil - case tokenEOF: - return empty, nil - case tokenLbrack: - left, err := t.parseFunc() - if err != nil { - return nil, err - } - - right, err := t.parseAny() - switch { - case err != nil: - return nil, err - case right == empty: - return left, nil - } - return newListNode(left, right), nil - } - - return nil, ErrBadSubstitution -} - -func (t *Tree) parseFunc() (Node, error) { - // Turn on all escape characters - t.scanner.escapeChars = escapeAll - switch t.scanner.peek() { - case '#': - return t.parseLenFunc() - } - - var name string - t.scanner.accept = acceptIdent - t.scanner.mode = scanIdent - - switch t.scanner.scan() { - case tokenIdent: - name = t.scanner.string() - default: - return nil, ErrParseVariableName - } - - switch t.scanner.peek() { - case ':': - return t.parseDefaultOrSubstr(name) - case '=': - return t.parseDefaultFunc(name) - case ',', '^': - return t.parseCasingFunc(name) - case '/': - return t.parseReplaceFunc(name) - case '#': - return t.parseRemoveFunc(name, acceptHashFunc) - case '%': - return t.parseRemoveFunc(name, acceptPercentFunc) - } - - t.scanner.accept = acceptIdent - t.scanner.mode = scanRbrack - switch t.scanner.scan() { - case tokenRbrack: - return newFuncNode(name), nil - default: - return nil, ErrMissingClosingBrace - } -} - -// parse a substitution function parameter. -func (t *Tree) parseParam(accept acceptFunc, mode byte) (Node, error) { - t.scanner.accept = accept - t.scanner.mode = mode | scanLbrack - switch t.scanner.scan() { - case tokenLbrack: - return t.parseFunc() - case tokenIdent: - return newTextNode( - t.scanner.string(), - ), nil - case tokenRbrack: - return newTextNode( - t.scanner.string(), - ), nil - default: - return nil, ErrParseFuncSubstitution - } -} - -// parse either a default or substring substitution function. -func (t *Tree) parseDefaultOrSubstr(name string) (Node, error) { - t.scanner.read() - r := t.scanner.peek() - t.scanner.unread() - switch r { - case '=', '-', '?', '+': - return t.parseDefaultFunc(name) - default: - return t.parseSubstrFunc(name) - } -} - -// parses the ${param:offset} string function -// parses the ${param:offset:length} string function -func (t *Tree) parseSubstrFunc(name string) (Node, error) { - node := new(FuncNode) - node.Param = name - - t.scanner.accept = acceptOneColon - t.scanner.mode = scanIdent - switch t.scanner.scan() { - case tokenIdent: - node.Name = t.scanner.string() - default: - return nil, ErrBadSubstitution - } - - // scan arg[1] - { - param, err := t.parseParam(rejectColonClose, scanIdent) - if err != nil { - return nil, err - } - - // param.Value = t.scanner.string() - node.Args = append(node.Args, param) - } - - // expect delimiter or close - t.scanner.accept = acceptColon - t.scanner.mode = scanIdent | scanRbrack - switch t.scanner.scan() { - case tokenRbrack: - return node, nil - case tokenIdent: - // no-op - default: - return nil, ErrBadSubstitution - } - - // scan arg[2] - { - param, err := t.parseParam(acceptNotClosing, scanIdent) - if err != nil { - return nil, err - } - node.Args = append(node.Args, param) - } - - return node, t.consumeRbrack() -} - -// parses the ${param%word} string function -// parses the ${param%%word} string function -// parses the ${param#word} string function -// parses the ${param##word} string function -func (t *Tree) parseRemoveFunc(name string, accept acceptFunc) (Node, error) { - node := new(FuncNode) - node.Param = name - - t.scanner.accept = accept - t.scanner.mode = scanIdent - switch t.scanner.scan() { - case tokenIdent: - node.Name = t.scanner.string() - default: - return nil, ErrBadSubstitution - } - - // scan arg[1] - { - param, err := t.parseParam(acceptNotClosing, scanIdent) - if err != nil { - return nil, err - } - - // param.Value = t.scanner.string() - node.Args = append(node.Args, param) - } - - return node, t.consumeRbrack() -} - -// parses the ${param/pattern/string} string function -// parses the ${param//pattern/string} string function -// parses the ${param/#pattern/string} string function -// parses the ${param/%pattern/string} string function -func (t *Tree) parseReplaceFunc(name string) (Node, error) { - node := new(FuncNode) - node.Param = name - - t.scanner.accept = acceptReplaceFunc - t.scanner.mode = scanIdent - switch t.scanner.scan() { - case tokenIdent: - node.Name = t.scanner.string() - default: - return nil, ErrBadSubstitution - } - - // scan arg[1] - { - param, err := t.parseParam(acceptNotSlash, scanIdent|scanEscape) - if err != nil { - return nil, err - } - node.Args = append(node.Args, param) - } - - // expect delimiter - t.scanner.accept = acceptSlash - t.scanner.mode = scanIdent - switch t.scanner.scan() { - case tokenIdent: - // no-op - default: - return nil, ErrBadSubstitution - } - - // check for blank string - switch t.scanner.peek() { - case '}': - return node, t.consumeRbrack() - } - - // scan arg[2] - { - param, err := t.parseParam(acceptNotClosing, scanIdent|scanEscape) - if err != nil { - return nil, err - } - node.Args = append(node.Args, param) - } - - return node, t.consumeRbrack() -} - -// parses the ${parameter=word} string function -// parses the ${parameter:=word} string function -// parses the ${parameter:-word} string function -// parses the ${parameter:?word} string function -// parses the ${parameter:+word} string function -func (t *Tree) parseDefaultFunc(name string) (Node, error) { - node := new(FuncNode) - node.Param = name - - t.scanner.accept = acceptDefaultFunc - if t.scanner.peek() == '=' { - t.scanner.accept = acceptOneEqual - } - t.scanner.mode = scanIdent - switch t.scanner.scan() { - case tokenIdent: - node.Name = t.scanner.string() - default: - return nil, ErrParseDefaultFunction - } - - // loop through all possible runes in default param - for { - // this acts as the break condition. Peek to see if we reached the end - switch t.scanner.peek() { - case '}': - return node, t.consumeRbrack() - } - param, err := t.parseParam(acceptNotClosing, scanIdent) - if err != nil { - return nil, err - } - - node.Args = append(node.Args, param) - } -} - -// parses the ${param,} string function -// parses the ${param,,} string function -// parses the ${param^} string function -// parses the ${param^^} string function -func (t *Tree) parseCasingFunc(name string) (Node, error) { - node := new(FuncNode) - node.Param = name - - t.scanner.accept = acceptCasingFunc - t.scanner.mode = scanIdent - switch t.scanner.scan() { - case tokenIdent: - node.Name = t.scanner.string() - default: - return nil, ErrBadSubstitution - } - - return node, t.consumeRbrack() -} - -// parses the ${#param} string function -func (t *Tree) parseLenFunc() (Node, error) { - node := new(FuncNode) - - t.scanner.accept = acceptOneHash - t.scanner.mode = scanIdent - switch t.scanner.scan() { - case tokenIdent: - node.Name = t.scanner.string() - default: - return nil, ErrBadSubstitution - } - - t.scanner.accept = acceptIdent - t.scanner.mode = scanIdent - switch t.scanner.scan() { - case tokenIdent: - node.Param = t.scanner.string() - default: - return nil, ErrBadSubstitution - } - - return node, t.consumeRbrack() -} - -// consumeRbrack consumes a right closing bracket. If a closing -// bracket token is not consumed an ErrBadSubstitution is returned. -func (t *Tree) consumeRbrack() error { - t.scanner.mode = scanRbrack - if t.scanner.scan() != tokenRbrack { - return ErrBadSubstitution - } - return nil -} - -// consumeDelimiter consumes a function argument delimiter. If a -// delimiter is not consumed an ErrBadSubstitution is returned. -// func (t *Tree) consumeDelimiter(accept acceptFunc, mode uint) error { -// t.scanner.accept = accept -// t.scanner.mode = mode -// if t.scanner.scan() != tokenRbrack { -// return ErrBadSubstitution -// } -// return nil -// } diff --git a/vendor/gomodules.xyz/envsubst/parse/scan.go b/vendor/gomodules.xyz/envsubst/parse/scan.go deleted file mode 100644 index 2710879a..00000000 --- a/vendor/gomodules.xyz/envsubst/parse/scan.go +++ /dev/null @@ -1,294 +0,0 @@ -package parse - -import ( - "unicode" - "unicode/utf8" -) - -// eof rune sent when end of file is reached -var eof = rune(0) - -// token is a lexical token. -type token uint - -// list of lexical tokens. -const ( - // special tokens - tokenIllegal token = iota - tokenEOF - - // identifiers and literals - tokenIdent - - // operators and delimiters - tokenLbrack - tokenRbrack - tokenQuote -) - -// predefined mode bits to control recognition of tokens. -const ( - scanIdent byte = 1 << iota - scanLbrack - scanRbrack - scanEscape -) - -// predefined mode bits to control escape tokens. -const ( - dollar byte = 1 << iota - backslash - escapeAll = dollar | backslash -) - -// returns true if rune is accepted. -type acceptFunc func(r rune, i int) bool - -// scanner implements a lexical scanner that reads unicode -// characters and tokens from a string buffer. -type scanner struct { - buf string - pos int - start int - width int - mode byte - escapeChars byte - - accept acceptFunc -} - -// init initializes a scanner with a new buffer. -func (s *scanner) init(buf string) { - s.buf = buf - s.pos = 0 - s.start = 0 - s.width = 0 - s.accept = nil -} - -// read returns the next unicode character. It returns eof at -// the end of the string buffer. -func (s *scanner) read() rune { - if s.pos >= len(s.buf) { - s.width = 0 - return eof - } - r, w := utf8.DecodeRuneInString(s.buf[s.pos:]) - s.width = w - s.pos += s.width - return r -} - -func (s *scanner) unread() { - s.pos -= s.width -} - -// skip skips over the curring unicode character in the buffer -// by slicing and removing from the buffer. -func (s *scanner) skip() { - l := s.buf[:s.pos-1] - r := s.buf[s.pos:] - s.buf = l + r -} - -// peek returns the next unicode character in the buffer without -// advancing the scanner. It returns eof if the scanner's position -// is at the last character of the source. -func (s *scanner) peek() rune { - r := s.read() - s.unread() - return r -} - -// string returns the string corresponding to the most recently -// scanned token. Valid after calling scan(). -func (s *scanner) string() string { - return s.buf[s.start:s.pos] -} - -// tests if the bit exists for a given character bit -func (s *scanner) shouldEscape(character byte) bool { - return s.escapeChars&character != 0 -} - -// scan reads the next token or Unicode character from source and -// returns it. It returns EOF at the end of the source. -func (s *scanner) scan() token { - s.start = s.pos - r := s.read() - switch { - case r == eof: - return tokenEOF - case s.scanLbrack(r): - return tokenLbrack - case s.scanRbrack(r): - return tokenRbrack - case s.scanIdent(r): - return tokenIdent - } - return tokenIllegal -} - -// scanIdent reads the next token or Unicode character from source -// and returns true if the Ident character is accepted. -func (s *scanner) scanIdent(r rune) bool { - if s.mode&scanIdent == 0 { - return false - } - if s.scanEscaped(r) { - s.skip() - } else if !s.accept(r, s.pos-s.start) { - return false - } -loop: - for { - r := s.read() - switch { - case r == eof: - s.unread() - break loop - case s.scanLbrack(r): - s.unread() - s.unread() - break loop - } - if s.scanEscaped(r) { - s.skip() - continue - } - if !s.accept(r, s.pos-s.start) { - s.unread() - break loop - } - } - return true -} - -// scanLbrack reads the next token or Unicode character from source -// and returns true if the open bracket is encountered. -func (s *scanner) scanLbrack(r rune) bool { - if s.mode&scanLbrack == 0 { - return false - } - if r == '$' { - if s.read() == '{' { - return true - } - s.unread() - } - return false -} - -// scanRbrack reads the next token or Unicode character from source -// and returns true if the closing bracket is encountered. -func (s *scanner) scanRbrack(r rune) bool { - if s.mode&scanRbrack == 0 { - return false - } - return r == '}' -} - -// scanEscaped reads the next token or Unicode character from source -// and returns true if it being escaped and should be skipped. -func (s *scanner) scanEscaped(r rune) bool { - if s.mode&scanEscape == 0 { - return false - } - if r == '$' && s.shouldEscape(dollar) { - if s.peek() == '$' { - return true - } - } - if r == '\\' && s.shouldEscape(backslash) { - switch s.peek() { - case '/', '\\': - return true - default: - return false - } - } - - return false -} - -// -// scanner functions accept or reject runes. -// - -func acceptRune(r rune, i int) bool { - return true -} - -func acceptIdent(r rune, i int) bool { - return unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' -} - -func acceptColon(r rune, i int) bool { - return r == ':' -} - -func acceptOneHash(r rune, i int) bool { - return r == '#' && i == 1 -} - -func acceptNone(r rune, i int) bool { - return false -} - -func acceptNotClosing(r rune, i int) bool { - return r != '}' -} - -func acceptHashFunc(r rune, i int) bool { - return r == '#' && i < 3 -} - -func acceptPercentFunc(r rune, i int) bool { - return r == '%' && i < 3 -} - -func acceptDefaultFunc(r rune, i int) bool { - switch { - case i == 1 && r == ':': - return true - case i == 2 && (r == '=' || r == '-' || r == '?' || r == '+'): - return true - default: - return false - } -} - -func acceptReplaceFunc(r rune, i int) bool { - switch { - case i == 1 && r == '/': - return true - case i == 2 && (r == '/' || r == '#' || r == '%'): - return true - default: - return false - } -} - -func acceptOneEqual(r rune, i int) bool { - return i == 1 && r == '=' -} - -func acceptOneColon(r rune, i int) bool { - return i == 1 && r == ':' -} - -func rejectColonClose(r rune, i int) bool { - return r != ':' && r != '}' -} - -func acceptSlash(r rune, i int) bool { - return r == '/' -} - -func acceptNotSlash(r rune, i int) bool { - return r != '/' -} - -func acceptCasingFunc(r rune, i int) bool { - return (r == ',' || r == '^') && i < 3 -} diff --git a/vendor/gomodules.xyz/envsubst/path/match.go b/vendor/gomodules.xyz/envsubst/path/match.go deleted file mode 100644 index 9306b0c9..00000000 --- a/vendor/gomodules.xyz/envsubst/path/match.go +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package path - -import ( - "errors" - "unicode/utf8" -) - -// ErrBadPattern indicates a globbing pattern was malformed. -var ErrBadPattern = errors.New("syntax error in pattern") - -// Match reports whether name matches the shell file name pattern. -// The pattern syntax is: -// -// pattern: -// { term } -// term: -// '*' matches any sequence of non-/ characters -// '?' matches any single non-/ character -// '[' [ '^' ] { character-range } ']' -// character class (must be non-empty) -// c matches character c (c != '*', '?', '\\', '[') -// '\\' c matches character c -// -// character-range: -// c matches character c (c != '\\', '-', ']') -// '\\' c matches character c -// lo '-' hi matches character c for lo <= c <= hi -// -// Match requires pattern to match all of name, not just a substring. -// The only possible returned error is ErrBadPattern, when pattern -// is malformed. -// -func Match(pattern, name string) (matched bool, err error) { -Pattern: - for len(pattern) > 0 { - var star bool - var chunk string - star, chunk, pattern = scanChunk(pattern) - if star && chunk == "" { - // Trailing * matches rest of string unless it has a /. - // return !strings.Contains(name, "/"), nil - - // Return rest of string - return true, nil - } - // Look for match at current position. - t, ok, err := matchChunk(chunk, name) - // if we're the last chunk, make sure we've exhausted the name - // otherwise we'll give a false result even if we could still match - // using the star - if ok && (len(t) == 0 || len(pattern) > 0) { - name = t - continue - } - if err != nil { - return false, err - } - if star { - // Look for match skipping i+1 bytes. - for i := 0; i < len(name); i++ { - t, ok, err := matchChunk(chunk, name[i+1:]) - if ok { - // if we're the last chunk, make sure we exhausted the name - if len(pattern) == 0 && len(t) > 0 { - continue - } - name = t - continue Pattern - } - if err != nil { - return false, err - } - } - } - return false, nil - } - return len(name) == 0, nil -} - -// scanChunk gets the next segment of pattern, which is a non-star string -// possibly preceded by a star. -func scanChunk(pattern string) (star bool, chunk, rest string) { - for len(pattern) > 0 && pattern[0] == '*' { - pattern = pattern[1:] - star = true - } - inrange := false - var i int -Scan: - for i = 0; i < len(pattern); i++ { - switch pattern[i] { - case '\\': - // error check handled in matchChunk: bad pattern. - if i+1 < len(pattern) { - i++ - } - case '[': - inrange = true - case ']': - inrange = false - case '*': - if !inrange { - break Scan - } - } - } - return star, pattern[0:i], pattern[i:] -} - -// matchChunk checks whether chunk matches the beginning of s. -// If so, it returns the remainder of s (after the match). -// Chunk is all single-character operators: literals, char classes, and ?. -func matchChunk(chunk, s string) (rest string, ok bool, err error) { - for len(chunk) > 0 { - if len(s) == 0 { - return - } - switch chunk[0] { - case '[': - // character class - r, n := utf8.DecodeRuneInString(s) - s = s[n:] - chunk = chunk[1:] - // possibly negated - notNegated := true - if len(chunk) > 0 && chunk[0] == '^' { - notNegated = false - chunk = chunk[1:] - } - // parse all ranges - match := false - nrange := 0 - for { - if len(chunk) > 0 && chunk[0] == ']' && nrange > 0 { - chunk = chunk[1:] - break - } - var lo, hi rune - if lo, chunk, err = getEsc(chunk); err != nil { - return - } - hi = lo - if chunk[0] == '-' { - if hi, chunk, err = getEsc(chunk[1:]); err != nil { - return - } - } - if lo <= r && r <= hi { - match = true - } - nrange++ - } - if match != notNegated { - return - } - - case '?': - _, n := utf8.DecodeRuneInString(s) - s = s[n:] - chunk = chunk[1:] - - case '\\': - chunk = chunk[1:] - if len(chunk) == 0 { - err = ErrBadPattern - return - } - fallthrough - - default: - if chunk[0] != s[0] { - return - } - s = s[1:] - chunk = chunk[1:] - } - } - return s, true, nil -} - -// getEsc gets a possibly-escaped character from chunk, for a character class. -func getEsc(chunk string) (r rune, nchunk string, err error) { - if len(chunk) == 0 || chunk[0] == '-' || chunk[0] == ']' { - err = ErrBadPattern - return - } - if chunk[0] == '\\' { - chunk = chunk[1:] - if len(chunk) == 0 { - err = ErrBadPattern - return - } - } - r, n := utf8.DecodeRuneInString(chunk) - if r == utf8.RuneError && n == 1 { - err = ErrBadPattern - } - nchunk = chunk[n:] - if len(nchunk) == 0 { - err = ErrBadPattern - } - return -} diff --git a/vendor/gomodules.xyz/envsubst/readme.md b/vendor/gomodules.xyz/envsubst/readme.md deleted file mode 100644 index f5284129..00000000 --- a/vendor/gomodules.xyz/envsubst/readme.md +++ /dev/null @@ -1,44 +0,0 @@ -# envsubst - -`envsubst` is a Go package for expanding variables in a string using `${var}` syntax. -Includes support for bash string replacement functions. - -## Documentation - -[Documentation can be found on GoDoc][doc]. - -## Supported Functions - -| __Expression__ | __Meaning__ | -| ----------------- | -------------- | -| `${var}` | Value of `$var` -| `${#var}` | String length of `$var` -| `${var^}` | Uppercase first character of `$var` -| `${var^^}` | Uppercase all characters in `$var` -| `${var,}` | Lowercase first character of `$var` -| `${var,,}` | Lowercase all characters in `$var` -| `${var:n}` | Offset `$var` `n` characters from start -| `${var:n:len}` | Offset `$var` `n` characters with max length of `len` -| `${var#pattern}` | Strip shortest `pattern` match from start -| `${var##pattern}` | Strip longest `pattern` match from start -| `${var%pattern}` | Strip shortest `pattern` match from end -| `${var%%pattern}` | Strip longest `pattern` match from end -| `${var-default` | If `$var` is not set, evaluate expression as `$default` -| `${var:-default` | If `$var` is not set or is empty, evaluate expression as `$default` -| `${var=default` | If `$var` is not set, evaluate expression as `$default` -| `${var:=default` | If `$var` is not set or is empty, evaluate expression as `$default` -| `${var/pattern/replacement}` | Replace as few `pattern` matches as possible with `replacement` -| `${var//pattern/replacement}` | Replace as many `pattern` matches as possible with `replacement` -| `${var/#pattern/replacement}` | Replace `pattern` match with `replacement` from `$var` start -| `${var/%pattern/replacement}` | Replace `pattern` match with `replacement` from `$var` end - -For a deeper reference, see [bash-hackers](https://wiki.bash-hackers.org/syntax/pe#case_modification) or [gnu pattern matching](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html). - -## Unsupported Functions - -* `${var-default}` -* `${var+default}` -* `${var:?default}` -* `${var:+default}` - -[doc]: http://godoc.org/gomodules.xyz/envsubst diff --git a/vendor/gomodules.xyz/envsubst/template.go b/vendor/gomodules.xyz/envsubst/template.go deleted file mode 100644 index 0a26ce3f..00000000 --- a/vendor/gomodules.xyz/envsubst/template.go +++ /dev/null @@ -1,180 +0,0 @@ -package envsubst - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - - "gomodules.xyz/envsubst/parse" -) - -type valueNotFoundError struct { - key string -} - -var _ error = &valueNotFoundError{} - -func (e *valueNotFoundError) Error() string { - return fmt.Sprintf("input/default value not found for key %s", e.key) -} - -func IsValueNotFoundError(v interface{}) bool { - switch v.(type) { - case *valueNotFoundError: - return true - } - return false -} - -// state represents the state of template execution. It is not part of the -// template so that multiple executions can run in parallel. -type state struct { - template *Template - writer io.Writer - node parse.Node // current node - - // maps variable names to values with additional behaviours - // returns value, args and error - mapper func(node string, key string, args []string) (string, []string, error) -} - -// Template is the representation of a parsed shell format string. -type Template struct { - tree *parse.Tree -} - -// Parse creates a new shell format template and parses the template -// definition from string s. -func Parse(s string) (t *Template, err error) { - t = new(Template) - t.tree, err = parse.Parse(s) - if err != nil { - return nil, err - } - return t, nil -} - -// ParseFile creates a new shell format template and parses the template -// definition from the named file. -func ParseFile(path string) (*Template, error) { - b, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - return Parse(string(b)) -} - -// Execute applies a parsed template to the specified data mapping. -func (t *Template) Execute(mapping func(node string, key string, args []string) (string, []string, error)) (str string, err error) { - b := new(bytes.Buffer) - s := new(state) - s.node = t.tree.Root - s.mapper = mapping - s.writer = b - err = t.eval(s) - if err != nil { - return - } - return b.String(), nil -} - -func (t *Template) eval(s *state) (err error) { - switch node := s.node.(type) { - case *parse.TextNode: - err = t.evalText(s, node) - case *parse.FuncNode: - err = t.evalFunc(s, node) - case *parse.ListNode: - err = t.evalList(s, node) - } - return err -} - -func (t *Template) evalText(s *state, node *parse.TextNode) error { - _, err := io.WriteString(s.writer, node.Value) - return err -} - -func (t *Template) evalList(s *state, node *parse.ListNode) (err error) { - for _, n := range node.Nodes { - s.node = n - err = t.eval(s) - if err != nil { - return err - } - } - return nil -} - -func (t *Template) evalFunc(s *state, node *parse.FuncNode) error { - var w = s.writer - var buf bytes.Buffer - var args []string - for _, n := range node.Args { - buf.Reset() - s.writer = &buf - s.node = n - err := t.eval(s) - if err != nil { - return err - } - args = append(args, buf.String()) - } - - // restore the origin writer - s.writer = w - s.node = node - - v, args, err := s.mapper(node.Name, node.Param, args) - if err != nil { - return err - } - - fn := lookupFunc(node.Name, len(args)) - - _, err = io.WriteString(s.writer, fn(v, args...)) - return err -} - -// lookupFunc returns the parameters substitution function by name. If the -// named function does not exists, a default function is returned. -func lookupFunc(name string, args int) substituteFunc { - switch name { - case ",": - return toLowerFirst - case ",,": - return toLower - case "^": - return toUpperFirst - case "^^": - return toUpper - case "#": - if args == 0 { - return toLen - } - return trimShortestPrefix - case "##": - return trimLongestPrefix - case "%": - return trimShortestSuffix - case "%%": - return trimLongestSuffix - case ":": - return toSubstr - case "/#": - return replacePrefix - case "/%": - return replaceSuffix - case "/": - return replaceFirst - case "//": - return replaceAll - case "=", ":=", ":-": - return toDefault - case ":?", ":+", "-", "+": - return toDefault - default: - return toDefault - } -} diff --git a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/backupblueprint_webhook.go b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/backupblueprint_webhook.go index 2d22b96e..3c438f98 100644 --- a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/backupblueprint_webhook.go +++ b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/backupblueprint_webhook.go @@ -65,24 +65,22 @@ var _ webhook.Validator = &BackupBlueprint{} func (r *BackupBlueprint) ValidateCreate() error { backupblueprintlog.Info("validate create", "name", r.Name) - c, err := getNewRuntimeClient() - if err != nil { - return fmt.Errorf("failed to set Kubernetes client, Reason: %w", err) + if err := r.validateUsagePolicy(); err != nil { + return err } - return r.validateBackendsAgainstUsagePolicy(context.Background(), c) + return r.validateBackendsAgainstUsagePolicy(context.Background(), apis.GetRuntimeClient()) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type func (r *BackupBlueprint) ValidateUpdate(old runtime.Object) error { backupblueprintlog.Info("validate update", "name", r.Name) - c, err := getNewRuntimeClient() - if err != nil { - return fmt.Errorf("failed to set Kubernetes client, Reason: %w", err) + if err := r.validateUsagePolicy(); err != nil { + return err } - return r.validateBackendsAgainstUsagePolicy(context.Background(), c) + return r.validateBackendsAgainstUsagePolicy(context.Background(), apis.GetRuntimeClient()) } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type @@ -145,3 +143,11 @@ func (r *BackupBlueprint) getBackupStorage(ctx context.Context, c client.Client, } return bs, nil } + +func (r *BackupBlueprint) validateUsagePolicy() error { + if *r.Spec.UsagePolicy.AllowedNamespaces.From == apis.NamespacesFromSelector && + r.Spec.UsagePolicy.AllowedNamespaces.Selector == nil { + return fmt.Errorf("selector cannot be empty for usage policy of type %q", apis.NamespacesFromSelector) + } + return nil +} diff --git a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/backupconfiguration_webhook.go b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/backupconfiguration_webhook.go index a99af027..829dd903 100644 --- a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/backupconfiguration_webhook.go +++ b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/backupconfiguration_webhook.go @@ -23,16 +23,14 @@ import ( kerr "k8s.io/apimachinery/pkg/api/errors" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - restclient "k8s.io/client-go/rest" kmapi "kmodules.xyz/client-go/api/v1" "kubestash.dev/apimachinery/apis" storageapi "kubestash.dev/apimachinery/apis/storage/v1alpha1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" + "sync" ) // log is for logging in this package. @@ -54,10 +52,7 @@ var _ webhook.Defaulter = &BackupConfiguration{} func (b *BackupConfiguration) Default() { backupconfigurationlog.Info("default", "name", b.Name) - c, err := getNewRuntimeClient() - if err != nil { - backupconfigurationlog.Error(err, "failed to set Kubernetes client") - } + c := apis.GetRuntimeClient() if len(b.Spec.Backends) == 0 { b.setDefaultBackend(context.Background(), c) @@ -191,50 +186,27 @@ var _ webhook.Validator = &BackupConfiguration{} func (b *BackupConfiguration) ValidateCreate() error { backupconfigurationlog.Info("validate create", apis.KeyName, b.Name) - c, err := getNewRuntimeClient() - if err != nil { - return fmt.Errorf("failed to set Kubernetes client, Reason: %w", err) - } + c := apis.GetRuntimeClient() - if err = b.validateBackends(); err != nil { + if err := b.validateBackends(); err != nil { return err } - if err = b.validateSessions(context.Background(), c); err != nil { + if err := b.validateSessions(context.Background(), c); err != nil { return err } - if err = b.validateBackendsAgainstUsagePolicy(context.Background(), c); err != nil { + if err := b.validateBackendsAgainstUsagePolicy(context.Background(), c); err != nil { return err } return b.validateHookTemplatesAgainstUsagePolicy(context.Background(), c) } -func getNewRuntimeClient() (client.Client, error) { - config, err := restclient.InClusterConfig() - if err != nil { - return nil, fmt.Errorf("failed to get Kubernetes config. Reason: %w", err) - } - scheme := runtime.NewScheme() - utilruntime.Must(storageapi.AddToScheme(scheme)) - utilruntime.Must(core.AddToScheme(scheme)) - utilruntime.Must(AddToScheme(scheme)) - - mapper, err := apiutil.NewDynamicRESTMapper(config) - if err != nil { - return nil, err - } - - return client.New(config, client.Options{ - Scheme: scheme, - Mapper: mapper, - Opts: client.WarningHandlerOptions{ - SuppressWarnings: false, - AllowDuplicateLogs: false, - }, - }) -} +var ( + rc client.Client + once sync.Once +) func (b *BackupConfiguration) validateBackends() error { if len(b.Spec.Backends) == 0 { @@ -651,20 +623,16 @@ func (b *BackupConfiguration) getHookTemplatesFromHookInfo(hooks []HookInfo) []H // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type func (b *BackupConfiguration) ValidateUpdate(old runtime.Object) error { backupconfigurationlog.Info("validate update", apis.KeyName, b.Name) - c, err := getNewRuntimeClient() - if err != nil { - return fmt.Errorf("failed to set Kubernetes client. Reason: %w", err) - } - - if err = b.validateBackends(); err != nil { + c := apis.GetRuntimeClient() + if err := b.validateBackends(); err != nil { return err } - if err = b.validateSessions(context.Background(), c); err != nil { + if err := b.validateSessions(context.Background(), c); err != nil { return err } - if err = b.validateBackendsAgainstUsagePolicy(context.Background(), c); err != nil { + if err := b.validateBackendsAgainstUsagePolicy(context.Background(), c); err != nil { return err } diff --git a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/hooktemplate_webhook.go b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/hooktemplate_webhook.go index 09256949..29c985b5 100644 --- a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/hooktemplate_webhook.go +++ b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/hooktemplate_webhook.go @@ -67,6 +67,10 @@ func (r *HookTemplate) ValidateCreate() error { return err } + if err := r.validateUsagePolicy(); err != nil { + return err + } + return r.validateExecutorInfo() } @@ -82,6 +86,10 @@ func (r *HookTemplate) ValidateUpdate(old runtime.Object) error { return err } + if err := r.validateUsagePolicy(); err != nil { + return err + } + return r.validateExecutorInfo() } @@ -134,3 +142,11 @@ func (r *HookTemplate) validateActionForNonFunctionExecutor() error { } return nil } + +func (r *HookTemplate) validateUsagePolicy() error { + if *r.Spec.UsagePolicy.AllowedNamespaces.From == apis.NamespacesFromSelector && + r.Spec.UsagePolicy.AllowedNamespaces.Selector == nil { + return fmt.Errorf("selector cannot be empty for usage policy of type %q", apis.NamespacesFromSelector) + } + return nil +} diff --git a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/restoresession_types.go b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/restoresession_types.go index 49dbd9e4..e039d61b 100644 --- a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/restoresession_types.go +++ b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/restoresession_types.go @@ -90,6 +90,14 @@ type ManifestRestoreOptions struct { // Postgres specifies the options for selecting particular Postgres components to restore in manifest restore // +optional Postgres *KubeDBManifestOptions `json:"postgres,omitempty"` + + // MySQL specifies the options for selecting particular MySQL components to restore in manifest restore + // +optional + MySQL *KubeDBManifestOptions `json:"mySQL,omitempty"` + + // MariaDB specifies the options for selecting particular MariaDB components to restore in manifest restore + // +optional + MariaDB *KubeDBManifestOptions `json:"mariaDB,omitempty"` } type KubeDBManifestOptions struct { diff --git a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/restoresession_webhook.go b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/restoresession_webhook.go index 88656ebb..1ef12f14 100644 --- a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/restoresession_webhook.go +++ b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/restoresession_webhook.go @@ -23,6 +23,7 @@ import ( kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "kubestash.dev/apimachinery/apis" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -49,32 +50,22 @@ var _ webhook.Validator = &RestoreSession{} func (r *RestoreSession) ValidateCreate() error { restoresessionlog.Info("validate create", "name", r.Name) - c, err := getNewRuntimeClient() - if err != nil { - return fmt.Errorf("failed to set Kubernetes client, Reason: %w", err) - } - if err := r.ValidateDataSource(); err != nil { return err } - return r.validateHookTemplatesAgainstUsagePolicy(context.Background(), c) + return r.validateHookTemplatesAgainstUsagePolicy(context.Background(), apis.GetRuntimeClient()) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type func (r *RestoreSession) ValidateUpdate(old runtime.Object) error { restoresessionlog.Info("validate update", "name", r.Name) - c, err := getNewRuntimeClient() - if err != nil { - return fmt.Errorf("failed to set Kubernetes client, Reason: %w", err) - } - if err := r.ValidateDataSource(); err != nil { return err } - return r.validateHookTemplatesAgainstUsagePolicy(context.Background(), c) + return r.validateHookTemplatesAgainstUsagePolicy(context.Background(), apis.GetRuntimeClient()) } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type diff --git a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/zz_generated.deepcopy.go b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/zz_generated.deepcopy.go index 8f9a889d..85e3c5f3 100644 --- a/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/kubestash.dev/apimachinery/apis/core/v1alpha1/zz_generated.deepcopy.go @@ -1034,6 +1034,16 @@ func (in *ManifestRestoreOptions) DeepCopyInto(out *ManifestRestoreOptions) { *out = new(KubeDBManifestOptions) **out = **in } + if in.MySQL != nil { + in, out := &in.MySQL, &out.MySQL + *out = new(KubeDBManifestOptions) + **out = **in + } + if in.MariaDB != nil { + in, out := &in.MariaDB, &out.MariaDB + *out = new(KubeDBManifestOptions) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManifestRestoreOptions. diff --git a/vendor/kubestash.dev/apimachinery/apis/helpers.go b/vendor/kubestash.dev/apimachinery/apis/helpers.go index 0a3fd926..58c0dee0 100644 --- a/vendor/kubestash.dev/apimachinery/apis/helpers.go +++ b/vendor/kubestash.dev/apimachinery/apis/helpers.go @@ -17,10 +17,29 @@ limitations under the License. package apis import ( - "encoding/json" - "gomodules.xyz/envsubst" + "sync" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var ( + once sync.Once + kc client.Client ) +func GetRuntimeClient() client.Client { + if kc == nil { + panic("runtime client is not initialized!") + } + return kc +} + +func SetRuntimeClient(client client.Client) { + once.Do(func() { + kc = client + }) +} + func UpsertLabels(oldLabels, newLabels map[string]string) map[string]string { if oldLabels == nil { oldLabels = make(map[string]string, len(newLabels)) @@ -30,16 +49,3 @@ func UpsertLabels(oldLabels, newLabels map[string]string) map[string]string { } return oldLabels } - -func ResolveWithInputs(obj interface{}, inputs map[string]string) error { - // convert to JSON, apply replacements and convert back to struct - jsonObj, err := json.Marshal(obj) - if err != nil { - return err - } - resolved, err := envsubst.EvalMap(string(jsonObj), inputs) - if err != nil { - return err - } - return json.Unmarshal([]byte(resolved), obj) -} diff --git a/vendor/kubestash.dev/apimachinery/apis/storage/v1alpha1/backupstorage_webhook.go b/vendor/kubestash.dev/apimachinery/apis/storage/v1alpha1/backupstorage_webhook.go index 89dd4b08..89b06f58 100644 --- a/vendor/kubestash.dev/apimachinery/apis/storage/v1alpha1/backupstorage_webhook.go +++ b/vendor/kubestash.dev/apimachinery/apis/storage/v1alpha1/backupstorage_webhook.go @@ -20,13 +20,10 @@ import ( "context" "fmt" "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - restclient "k8s.io/client-go/rest" "kubestash.dev/apimachinery/apis" "reflect" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" ) @@ -64,10 +61,7 @@ var _ webhook.Validator = &BackupStorage{} func (r *BackupStorage) ValidateCreate() error { backupstoragelog.Info("validate create", "name", r.Name) - c, err := getNewRuntimeClient() - if err != nil { - return fmt.Errorf("failed to set Kubernetes client. Reason: %w", err) - } + c := apis.GetRuntimeClient() if r.Spec.Default { if err := r.validateSingleDefaultBackupStorageInSameNamespace(context.Background(), c); err != nil { @@ -75,6 +69,10 @@ func (r *BackupStorage) ValidateCreate() error { } } + if err := r.validateUsagePolicy(); err != nil { + return err + } + return r.validateUniqueDirectory(context.Background(), c) } @@ -82,18 +80,19 @@ func (r *BackupStorage) ValidateCreate() error { func (r *BackupStorage) ValidateUpdate(old runtime.Object) error { backupstoragelog.Info("validate update", "name", r.Name) - c, err := getNewRuntimeClient() - if err != nil { - return fmt.Errorf("failed to set Kubernetes client. Reason: %w", err) - } + c := apis.GetRuntimeClient() if r.Spec.Default { - if err = r.validateSingleDefaultBackupStorageInSameNamespace(context.Background(), c); err != nil { + if err := r.validateSingleDefaultBackupStorageInSameNamespace(context.Background(), c); err != nil { return err } } - if err = r.validateUpdateStorage(old.(*BackupStorage)); err != nil { + if err := r.validateUsagePolicy(); err != nil { + return err + } + + if err := r.validateUpdateStorage(old.(*BackupStorage)); err != nil { return err } @@ -133,6 +132,14 @@ func (r *BackupStorage) validateSingleDefaultBackupStorageInSameNamespace(ctx co return nil } +func (r *BackupStorage) validateUsagePolicy() error { + if *r.Spec.UsagePolicy.AllowedNamespaces.From == apis.NamespacesFromSelector && + r.Spec.UsagePolicy.AllowedNamespaces.Selector == nil { + return fmt.Errorf("selector cannot be empty for usage policy of type %q", apis.NamespacesFromSelector) + } + return nil +} + func (r *BackupStorage) isSameBackupStorage(bs BackupStorage) bool { if r.Namespace == bs.Namespace && r.Name == bs.Name { @@ -208,26 +215,3 @@ func (r *BackupStorage) isPointToSameDir(bs BackupStorage) bool { return false } } - -func getNewRuntimeClient() (client.Client, error) { - config, err := restclient.InClusterConfig() - if err != nil { - return nil, fmt.Errorf("failed to get Kubernetes config. Reason: %w", err) - } - scheme := runtime.NewScheme() - utilruntime.Must(AddToScheme(scheme)) - - mapper, err := apiutil.NewDynamicRESTMapper(config) - if err != nil { - return nil, err - } - - return client.New(config, client.Options{ - Scheme: scheme, - Mapper: mapper, - Opts: client.WarningHandlerOptions{ - SuppressWarnings: false, - AllowDuplicateLogs: false, - }, - }) -} diff --git a/vendor/kubestash.dev/apimachinery/apis/storage/v1alpha1/retentionpolicy_webhook.go b/vendor/kubestash.dev/apimachinery/apis/storage/v1alpha1/retentionpolicy_webhook.go index 4e3a5e94..169229fc 100644 --- a/vendor/kubestash.dev/apimachinery/apis/storage/v1alpha1/retentionpolicy_webhook.go +++ b/vendor/kubestash.dev/apimachinery/apis/storage/v1alpha1/retentionpolicy_webhook.go @@ -80,10 +80,7 @@ var _ webhook.Validator = &RetentionPolicy{} func (r *RetentionPolicy) ValidateCreate() error { retentionpolicylog.Info("validate create", "name", r.Name) - c, err := getNewRuntimeClient() - if err != nil { - return fmt.Errorf("failed to set Kubernetes client. Reason: %w", err) - } + c := apis.GetRuntimeClient() if err := r.validateMaxRetentionPeriodFormat(); err != nil { return err @@ -92,6 +89,11 @@ func (r *RetentionPolicy) ValidateCreate() error { if err := r.validateProvidedPolicy(); err != nil { return err } + + if err := r.validateUsagePolicy(); err != nil { + return err + } + return r.validateSingleDefaultRetentionPolicyInSameNamespace(context.Background(), c) } @@ -99,10 +101,7 @@ func (r *RetentionPolicy) ValidateCreate() error { func (r *RetentionPolicy) ValidateUpdate(old runtime.Object) error { retentionpolicylog.Info("validate update", "name", r.Name) - c, err := getNewRuntimeClient() - if err != nil { - return fmt.Errorf("failed to set Kubernetes client. Reason: %w", err) - } + c := apis.GetRuntimeClient() if err := r.validateMaxRetentionPeriodFormat(); err != nil { return err @@ -111,6 +110,11 @@ func (r *RetentionPolicy) ValidateUpdate(old runtime.Object) error { if err := r.validateProvidedPolicy(); err != nil { return err } + + if err := r.validateUsagePolicy(); err != nil { + return err + } + return r.validateSingleDefaultRetentionPolicyInSameNamespace(context.Background(), c) } @@ -133,6 +137,10 @@ func (r *RetentionPolicy) validateProvidedPolicy() error { } func (r *RetentionPolicy) validateSingleDefaultRetentionPolicyInSameNamespace(ctx context.Context, c client.Client) error { + if !r.Spec.Default { + return nil + } + rpList := RetentionPolicyList{} if err := c.List(ctx, &rpList, client.InNamespace(r.Namespace)); err != nil { return err @@ -156,6 +164,14 @@ func (r *RetentionPolicy) isSameRetentionPolicy(rp RetentionPolicy) bool { return false } +func (r *RetentionPolicy) validateUsagePolicy() error { + if *r.Spec.UsagePolicy.AllowedNamespaces.From == apis.NamespacesFromSelector && + r.Spec.UsagePolicy.AllowedNamespaces.Selector == nil { + return fmt.Errorf("selector cannot be empty for usage policy of type %q", apis.NamespacesFromSelector) + } + return nil +} + // ValidateDelete implements webhook.Validator so a webhook will be registered for the type func (r *RetentionPolicy) ValidateDelete() error { retentionpolicylog.Info("validate delete", "name", r.Name) diff --git a/vendor/kubestash.dev/apimachinery/crds/core.kubestash.com_restoresessions.yaml b/vendor/kubestash.dev/apimachinery/crds/core.kubestash.com_restoresessions.yaml index 6474b2ba..4b869be6 100644 --- a/vendor/kubestash.dev/apimachinery/crds/core.kubestash.com_restoresessions.yaml +++ b/vendor/kubestash.dev/apimachinery/crds/core.kubestash.com_restoresessions.yaml @@ -20879,6 +20879,39 @@ spec: description: ManifestOptions provide options to select particular manifest object to restore properties: + mariaDB: + description: MariaDB specifies the options for selecting particular + MariaDB components to restore in manifest restore + properties: + authSecret: + description: AuthSecret specifies whether to restore the AuthSecret + manifest or not + type: boolean + authSecretName: + description: AuthSecretName specifies new name of the AuthSecret + yaml after restore + type: string + configSecret: + description: ConfigSecret specifies whether to restore the + ConfigSecret manifest or not + type: boolean + configSecretName: + description: ConfigSecretName specifies new name of the ConfigSecret + yaml after restore + type: string + db: + description: DB specifies whether to restore the DB manifest + or not + type: boolean + dbName: + description: DBName specifies the new name of the DB yaml + after restore + type: string + issuerRefName: + description: IssuerRefName specifies new name of the IssuerRef + after restore + type: string + type: object mongoDB: description: MongoDB specifies the options for selecting particular MongoDB components to restore in manifest restore @@ -20912,6 +20945,39 @@ spec: after restore type: string type: object + mySQL: + description: MySQL specifies the options for selecting particular + MySQL components to restore in manifest restore + properties: + authSecret: + description: AuthSecret specifies whether to restore the AuthSecret + manifest or not + type: boolean + authSecretName: + description: AuthSecretName specifies new name of the AuthSecret + yaml after restore + type: string + configSecret: + description: ConfigSecret specifies whether to restore the + ConfigSecret manifest or not + type: boolean + configSecretName: + description: ConfigSecretName specifies new name of the ConfigSecret + yaml after restore + type: string + db: + description: DB specifies whether to restore the DB manifest + or not + type: boolean + dbName: + description: DBName specifies the new name of the DB yaml + after restore + type: string + issuerRefName: + description: IssuerRefName specifies new name of the IssuerRef + after restore + type: string + type: object postgres: description: Postgres specifies the options for selecting particular Postgres components to restore in manifest restore diff --git a/vendor/modules.txt b/vendor/modules.txt index 9e02393e..3fac92e2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -348,11 +348,6 @@ golang.org/x/time/rate # gomodules.xyz/clock v0.0.0-20200817085942-06523dba733f ## explicit; go 1.14 gomodules.xyz/clock -# gomodules.xyz/envsubst v0.2.0 -## explicit; go 1.19 -gomodules.xyz/envsubst -gomodules.xyz/envsubst/parse -gomodules.xyz/envsubst/path # gomodules.xyz/flags v0.1.3 ## explicit; go 1.16 gomodules.xyz/flags @@ -822,7 +817,7 @@ kmodules.xyz/offshoot-api/api/v1 # kmodules.xyz/prober v0.25.0 ## explicit; go 1.18 kmodules.xyz/prober/api/v1 -# kubestash.dev/apimachinery v0.2.0 +# kubestash.dev/apimachinery v0.3.0 ## explicit; go 1.20 kubestash.dev/apimachinery/apis kubestash.dev/apimachinery/apis/config/v1alpha1