From 2f51cc4ce46ae886f71be0b56b7d06aa89521e63 Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 19 Jan 2017 16:35:04 -0500 Subject: [PATCH] move client auth plugins --- pkg/util/jsonpath/doc.go | 20 - pkg/util/jsonpath/jsonpath.go | 498 ------------------ pkg/util/jsonpath/node.go | 239 --------- pkg/util/jsonpath/parser.go | 433 --------------- plugin/pkg/client/auth/BUILD | 35 -- plugin/pkg/client/auth/gcp/BUILD | 45 -- plugin/pkg/client/auth/gcp/OWNERS | 3 - plugin/pkg/client/auth/gcp/gcp.go | 274 ---------- plugin/pkg/client/auth/gcp/gcp_test.go | 211 -------- plugin/pkg/client/auth/oidc/BUILD | 48 -- plugin/pkg/client/auth/oidc/OWNERS | 2 - plugin/pkg/client/auth/oidc/oidc.go | 333 ------------ plugin/pkg/client/auth/oidc/oidc_test.go | 384 -------------- plugin/pkg/client/auth/plugins.go | 23 - staging/copy.sh | 5 +- .../k8s.io/client-go/pkg/util/jsonpath/doc.go | 2 +- .../pkg}/util/jsonpath/jsonpath_test.go | 0 .../pkg}/util/jsonpath/parser_test.go | 0 .../plugin/pkg/client/auth/oidc/oidc_test.go | 2 +- 19 files changed, 5 insertions(+), 2552 deletions(-) delete mode 100644 pkg/util/jsonpath/doc.go delete mode 100644 pkg/util/jsonpath/jsonpath.go delete mode 100644 pkg/util/jsonpath/node.go delete mode 100644 pkg/util/jsonpath/parser.go delete mode 100644 plugin/pkg/client/auth/BUILD delete mode 100644 plugin/pkg/client/auth/gcp/BUILD delete mode 100644 plugin/pkg/client/auth/gcp/OWNERS delete mode 100644 plugin/pkg/client/auth/gcp/gcp.go delete mode 100644 plugin/pkg/client/auth/gcp/gcp_test.go delete mode 100644 plugin/pkg/client/auth/oidc/BUILD delete mode 100644 plugin/pkg/client/auth/oidc/OWNERS delete mode 100644 plugin/pkg/client/auth/oidc/oidc.go delete mode 100644 plugin/pkg/client/auth/oidc/oidc_test.go delete mode 100644 plugin/pkg/client/auth/plugins.go rename {pkg => staging/src/k8s.io/client-go/pkg}/util/jsonpath/jsonpath_test.go (100%) rename {pkg => staging/src/k8s.io/client-go/pkg}/util/jsonpath/parser_test.go (100%) diff --git a/pkg/util/jsonpath/doc.go b/pkg/util/jsonpath/doc.go deleted file mode 100644 index 0077f30355c..00000000000 --- a/pkg/util/jsonpath/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// package jsonpath is a template engine using jsonpath syntax, -// which can be seen at http://goessner.net/articles/JsonPath/. -// In addition, it has {range} {end} function to iterate list and slice. -package jsonpath // import "k8s.io/kubernetes/pkg/util/jsonpath" diff --git a/pkg/util/jsonpath/jsonpath.go b/pkg/util/jsonpath/jsonpath.go deleted file mode 100644 index d84a1855976..00000000000 --- a/pkg/util/jsonpath/jsonpath.go +++ /dev/null @@ -1,498 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package jsonpath - -import ( - "bytes" - "fmt" - "io" - "reflect" - "strings" - - "k8s.io/kubernetes/third_party/forked/golang/template" -) - -type JSONPath struct { - name string - parser *Parser - stack [][]reflect.Value //push and pop values in different scopes - cur []reflect.Value //current scope values - beginRange int - inRange int - endRange int - - allowMissingKeys bool -} - -func New(name string) *JSONPath { - return &JSONPath{ - name: name, - beginRange: 0, - inRange: 0, - endRange: 0, - } -} - -// AllowMissingKeys allows a caller to specify whether they want an error if a field or map key -// cannot be located, or simply an empty result. The receiver is returned for chaining. -func (j *JSONPath) AllowMissingKeys(allow bool) *JSONPath { - j.allowMissingKeys = allow - return j -} - -// Parse parse the given template, return error -func (j *JSONPath) Parse(text string) (err error) { - j.parser, err = Parse(j.name, text) - return -} - -// Execute bounds data into template and write the result -func (j *JSONPath) Execute(wr io.Writer, data interface{}) error { - fullResults, err := j.FindResults(data) - if err != nil { - return err - } - for ix := range fullResults { - if err := j.PrintResults(wr, fullResults[ix]); err != nil { - return err - } - } - return nil -} - -func (j *JSONPath) FindResults(data interface{}) ([][]reflect.Value, error) { - if j.parser == nil { - return nil, fmt.Errorf("%s is an incomplete jsonpath template", j.name) - } - - j.cur = []reflect.Value{reflect.ValueOf(data)} - nodes := j.parser.Root.Nodes - fullResult := [][]reflect.Value{} - for i := 0; i < len(nodes); i++ { - node := nodes[i] - results, err := j.walk(j.cur, node) - if err != nil { - return nil, err - } - - //encounter an end node, break the current block - if j.endRange > 0 && j.endRange <= j.inRange { - j.endRange -= 1 - break - } - //encounter a range node, start a range loop - if j.beginRange > 0 { - j.beginRange -= 1 - j.inRange += 1 - for k, value := range results { - j.parser.Root.Nodes = nodes[i+1:] - if k == len(results)-1 { - j.inRange -= 1 - } - nextResults, err := j.FindResults(value.Interface()) - if err != nil { - return nil, err - } - fullResult = append(fullResult, nextResults...) - } - break - } - fullResult = append(fullResult, results) - } - return fullResult, nil -} - -// PrintResults write the results into writer -func (j *JSONPath) PrintResults(wr io.Writer, results []reflect.Value) error { - for i, r := range results { - text, err := j.evalToText(r) - if err != nil { - return err - } - if i != len(results)-1 { - text = append(text, ' ') - } - if _, err = wr.Write(text); err != nil { - return err - } - } - return nil -} - -// walk visits tree rooted at the given node in DFS order -func (j *JSONPath) walk(value []reflect.Value, node Node) ([]reflect.Value, error) { - switch node := node.(type) { - case *ListNode: - return j.evalList(value, node) - case *TextNode: - return []reflect.Value{reflect.ValueOf(node.Text)}, nil - case *FieldNode: - return j.evalField(value, node) - case *ArrayNode: - return j.evalArray(value, node) - case *FilterNode: - return j.evalFilter(value, node) - case *IntNode: - return j.evalInt(value, node) - case *FloatNode: - return j.evalFloat(value, node) - case *WildcardNode: - return j.evalWildcard(value, node) - case *RecursiveNode: - return j.evalRecursive(value, node) - case *UnionNode: - return j.evalUnion(value, node) - case *IdentifierNode: - return j.evalIdentifier(value, node) - default: - return value, fmt.Errorf("unexpected Node %v", node) - } -} - -// evalInt evaluates IntNode -func (j *JSONPath) evalInt(input []reflect.Value, node *IntNode) ([]reflect.Value, error) { - result := make([]reflect.Value, len(input)) - for i := range input { - result[i] = reflect.ValueOf(node.Value) - } - return result, nil -} - -// evalFloat evaluates FloatNode -func (j *JSONPath) evalFloat(input []reflect.Value, node *FloatNode) ([]reflect.Value, error) { - result := make([]reflect.Value, len(input)) - for i := range input { - result[i] = reflect.ValueOf(node.Value) - } - return result, nil -} - -// evalList evaluates ListNode -func (j *JSONPath) evalList(value []reflect.Value, node *ListNode) ([]reflect.Value, error) { - var err error - curValue := value - for _, node := range node.Nodes { - curValue, err = j.walk(curValue, node) - if err != nil { - return curValue, err - } - } - return curValue, nil -} - -// evalIdentifier evaluates IdentifierNode -func (j *JSONPath) evalIdentifier(input []reflect.Value, node *IdentifierNode) ([]reflect.Value, error) { - results := []reflect.Value{} - switch node.Name { - case "range": - j.stack = append(j.stack, j.cur) - j.beginRange += 1 - results = input - case "end": - if j.endRange < j.inRange { //inside a loop, break the current block - j.endRange += 1 - break - } - // the loop is about to end, pop value and continue the following execution - if len(j.stack) > 0 { - j.cur, j.stack = j.stack[len(j.stack)-1], j.stack[:len(j.stack)-1] - } else { - return results, fmt.Errorf("not in range, nothing to end") - } - default: - return input, fmt.Errorf("unrecognized identifier %v", node.Name) - } - return results, nil -} - -// evalArray evaluates ArrayNode -func (j *JSONPath) evalArray(input []reflect.Value, node *ArrayNode) ([]reflect.Value, error) { - result := []reflect.Value{} - for _, value := range input { - - value, isNil := template.Indirect(value) - if isNil { - continue - } - if value.Kind() != reflect.Array && value.Kind() != reflect.Slice { - return input, fmt.Errorf("%v is not array or slice", value.Type()) - } - params := node.Params - if !params[0].Known { - params[0].Value = 0 - } - if params[0].Value < 0 { - params[0].Value += value.Len() - } - if !params[1].Known { - params[1].Value = value.Len() - } - - if params[1].Value < 0 { - params[1].Value += value.Len() - } - - sliceLength := value.Len() - if params[1].Value != params[0].Value { // if you're requesting zero elements, allow it through. - if params[0].Value >= sliceLength { - return input, fmt.Errorf("array index out of bounds: index %d, length %d", params[0].Value, sliceLength) - } - if params[1].Value > sliceLength { - return input, fmt.Errorf("array index out of bounds: index %d, length %d", params[1].Value-1, sliceLength) - } - } - - if !params[2].Known { - value = value.Slice(params[0].Value, params[1].Value) - } else { - value = value.Slice3(params[0].Value, params[1].Value, params[2].Value) - } - for i := 0; i < value.Len(); i++ { - result = append(result, value.Index(i)) - } - } - return result, nil -} - -// evalUnion evaluates UnionNode -func (j *JSONPath) evalUnion(input []reflect.Value, node *UnionNode) ([]reflect.Value, error) { - result := []reflect.Value{} - for _, listNode := range node.Nodes { - temp, err := j.evalList(input, listNode) - if err != nil { - return input, err - } - result = append(result, temp...) - } - return result, nil -} - -func (j *JSONPath) findFieldInValue(value *reflect.Value, node *FieldNode) (reflect.Value, error) { - t := value.Type() - var inlineValue *reflect.Value - for ix := 0; ix < t.NumField(); ix++ { - f := t.Field(ix) - jsonTag := f.Tag.Get("json") - parts := strings.Split(jsonTag, ",") - if len(parts) == 0 { - continue - } - if parts[0] == node.Value { - return value.Field(ix), nil - } - if len(parts[0]) == 0 { - val := value.Field(ix) - inlineValue = &val - } - } - if inlineValue != nil { - if inlineValue.Kind() == reflect.Struct { - // handle 'inline' - match, err := j.findFieldInValue(inlineValue, node) - if err != nil { - return reflect.Value{}, err - } - if match.IsValid() { - return match, nil - } - } - } - return value.FieldByName(node.Value), nil -} - -// evalField evaluates field of struct or key of map. -func (j *JSONPath) evalField(input []reflect.Value, node *FieldNode) ([]reflect.Value, error) { - results := []reflect.Value{} - // If there's no input, there's no output - if len(input) == 0 { - return results, nil - } - for _, value := range input { - var result reflect.Value - value, isNil := template.Indirect(value) - if isNil { - continue - } - - if value.Kind() == reflect.Struct { - var err error - if result, err = j.findFieldInValue(&value, node); err != nil { - return nil, err - } - } else if value.Kind() == reflect.Map { - mapKeyType := value.Type().Key() - nodeValue := reflect.ValueOf(node.Value) - // node value type must be convertible to map key type - if !nodeValue.Type().ConvertibleTo(mapKeyType) { - return results, fmt.Errorf("%s is not convertible to %s", nodeValue, mapKeyType) - } - result = value.MapIndex(nodeValue.Convert(mapKeyType)) - } - if result.IsValid() { - results = append(results, result) - } - } - if len(results) == 0 { - if j.allowMissingKeys { - return results, nil - } - return results, fmt.Errorf("%s is not found", node.Value) - } - return results, nil -} - -// evalWildcard extract all contents of the given value -func (j *JSONPath) evalWildcard(input []reflect.Value, node *WildcardNode) ([]reflect.Value, error) { - results := []reflect.Value{} - for _, value := range input { - value, isNil := template.Indirect(value) - if isNil { - continue - } - - kind := value.Kind() - if kind == reflect.Struct { - for i := 0; i < value.NumField(); i++ { - results = append(results, value.Field(i)) - } - } else if kind == reflect.Map { - for _, key := range value.MapKeys() { - results = append(results, value.MapIndex(key)) - } - } else if kind == reflect.Array || kind == reflect.Slice || kind == reflect.String { - for i := 0; i < value.Len(); i++ { - results = append(results, value.Index(i)) - } - } - } - return results, nil -} - -// evalRecursive visit the given value recursively and push all of them to result -func (j *JSONPath) evalRecursive(input []reflect.Value, node *RecursiveNode) ([]reflect.Value, error) { - result := []reflect.Value{} - for _, value := range input { - results := []reflect.Value{} - value, isNil := template.Indirect(value) - if isNil { - continue - } - - kind := value.Kind() - if kind == reflect.Struct { - for i := 0; i < value.NumField(); i++ { - results = append(results, value.Field(i)) - } - } else if kind == reflect.Map { - for _, key := range value.MapKeys() { - results = append(results, value.MapIndex(key)) - } - } else if kind == reflect.Array || kind == reflect.Slice || kind == reflect.String { - for i := 0; i < value.Len(); i++ { - results = append(results, value.Index(i)) - } - } - if len(results) != 0 { - result = append(result, value) - output, err := j.evalRecursive(results, node) - if err != nil { - return result, err - } - result = append(result, output...) - } - } - return result, nil -} - -// evalFilter filter array according to FilterNode -func (j *JSONPath) evalFilter(input []reflect.Value, node *FilterNode) ([]reflect.Value, error) { - results := []reflect.Value{} - for _, value := range input { - value, _ = template.Indirect(value) - - if value.Kind() != reflect.Array && value.Kind() != reflect.Slice { - return input, fmt.Errorf("%v is not array or slice and cannot be filtered", value) - } - for i := 0; i < value.Len(); i++ { - temp := []reflect.Value{value.Index(i)} - lefts, err := j.evalList(temp, node.Left) - - //case exists - if node.Operator == "exists" { - if len(lefts) > 0 { - results = append(results, value.Index(i)) - } - continue - } - - if err != nil { - return input, err - } - - var left, right interface{} - if len(lefts) != 1 { - return input, fmt.Errorf("can only compare one element at a time") - } - left = lefts[0].Interface() - - rights, err := j.evalList(temp, node.Right) - if err != nil { - return input, err - } - if len(rights) != 1 { - return input, fmt.Errorf("can only compare one element at a time") - } - right = rights[0].Interface() - - pass := false - switch node.Operator { - case "<": - pass, err = template.Less(left, right) - case ">": - pass, err = template.Greater(left, right) - case "==": - pass, err = template.Equal(left, right) - case "!=": - pass, err = template.NotEqual(left, right) - case "<=": - pass, err = template.LessEqual(left, right) - case ">=": - pass, err = template.GreaterEqual(left, right) - default: - return results, fmt.Errorf("unrecognized filter operator %s", node.Operator) - } - if err != nil { - return results, err - } - if pass { - results = append(results, value.Index(i)) - } - } - } - return results, nil -} - -// evalToText translates reflect value to corresponding text -func (j *JSONPath) evalToText(v reflect.Value) ([]byte, error) { - iface, ok := template.PrintableValue(v) - if !ok { - return nil, fmt.Errorf("can't print type %s", v.Type()) - } - var buffer bytes.Buffer - fmt.Fprint(&buffer, iface) - return buffer.Bytes(), nil -} diff --git a/pkg/util/jsonpath/node.go b/pkg/util/jsonpath/node.go deleted file mode 100644 index f0a27853d84..00000000000 --- a/pkg/util/jsonpath/node.go +++ /dev/null @@ -1,239 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package jsonpath - -import "fmt" - -// NodeType identifies the type of a parse tree node. -type NodeType int - -// Type returns itself and provides an easy default implementation -func (t NodeType) Type() NodeType { - return t -} - -func (t NodeType) String() string { - return NodeTypeName[t] -} - -const ( - NodeText NodeType = iota - NodeArray - NodeList - NodeField - NodeIdentifier - NodeFilter - NodeInt - NodeFloat - NodeWildcard - NodeRecursive - NodeUnion -) - -var NodeTypeName = map[NodeType]string{ - NodeText: "NodeText", - NodeArray: "NodeArray", - NodeList: "NodeList", - NodeField: "NodeField", - NodeIdentifier: "NodeIdentifier", - NodeFilter: "NodeFilter", - NodeInt: "NodeInt", - NodeFloat: "NodeFloat", - NodeWildcard: "NodeWildcard", - NodeRecursive: "NodeRecursive", - NodeUnion: "NodeUnion", -} - -type Node interface { - Type() NodeType - String() string -} - -// ListNode holds a sequence of nodes. -type ListNode struct { - NodeType - Nodes []Node // The element nodes in lexical order. -} - -func newList() *ListNode { - return &ListNode{NodeType: NodeList} -} - -func (l *ListNode) append(n Node) { - l.Nodes = append(l.Nodes, n) -} - -func (l *ListNode) String() string { - return fmt.Sprintf("%s", l.Type()) -} - -// TextNode holds plain text. -type TextNode struct { - NodeType - Text string // The text; may span newlines. -} - -func newText(text string) *TextNode { - return &TextNode{NodeType: NodeText, Text: text} -} - -func (t *TextNode) String() string { - return fmt.Sprintf("%s: %s", t.Type(), t.Text) -} - -// FieldNode holds field of struct -type FieldNode struct { - NodeType - Value string -} - -func newField(value string) *FieldNode { - return &FieldNode{NodeType: NodeField, Value: value} -} - -func (f *FieldNode) String() string { - return fmt.Sprintf("%s: %s", f.Type(), f.Value) -} - -// IdentifierNode holds an identifier -type IdentifierNode struct { - NodeType - Name string -} - -func newIdentifier(value string) *IdentifierNode { - return &IdentifierNode{ - NodeType: NodeIdentifier, - Name: value, - } -} - -func (f *IdentifierNode) String() string { - return fmt.Sprintf("%s: %s", f.Type(), f.Name) -} - -// ParamsEntry holds param information for ArrayNode -type ParamsEntry struct { - Value int - Known bool //whether the value is known when parse it -} - -// ArrayNode holds start, end, step information for array index selection -type ArrayNode struct { - NodeType - Params [3]ParamsEntry //start, end, step -} - -func newArray(params [3]ParamsEntry) *ArrayNode { - return &ArrayNode{ - NodeType: NodeArray, - Params: params, - } -} - -func (a *ArrayNode) String() string { - return fmt.Sprintf("%s: %v", a.Type(), a.Params) -} - -// FilterNode holds operand and operator information for filter -type FilterNode struct { - NodeType - Left *ListNode - Right *ListNode - Operator string -} - -func newFilter(left, right *ListNode, operator string) *FilterNode { - return &FilterNode{ - NodeType: NodeFilter, - Left: left, - Right: right, - Operator: operator, - } -} - -func (f *FilterNode) String() string { - return fmt.Sprintf("%s: %s %s %s", f.Type(), f.Left, f.Operator, f.Right) -} - -// IntNode holds integer value -type IntNode struct { - NodeType - Value int -} - -func newInt(num int) *IntNode { - return &IntNode{NodeType: NodeInt, Value: num} -} - -func (i *IntNode) String() string { - return fmt.Sprintf("%s: %d", i.Type(), i.Value) -} - -// FloatNode holds float value -type FloatNode struct { - NodeType - Value float64 -} - -func newFloat(num float64) *FloatNode { - return &FloatNode{NodeType: NodeFloat, Value: num} -} - -func (i *FloatNode) String() string { - return fmt.Sprintf("%s: %f", i.Type(), i.Value) -} - -// WildcardNode means a wildcard -type WildcardNode struct { - NodeType -} - -func newWildcard() *WildcardNode { - return &WildcardNode{NodeType: NodeWildcard} -} - -func (i *WildcardNode) String() string { - return fmt.Sprintf("%s", i.Type()) -} - -// RecursiveNode means a recursive descent operator -type RecursiveNode struct { - NodeType -} - -func newRecursive() *RecursiveNode { - return &RecursiveNode{NodeType: NodeRecursive} -} - -func (r *RecursiveNode) String() string { - return fmt.Sprintf("%s", r.Type()) -} - -// UnionNode is union of ListNode -type UnionNode struct { - NodeType - Nodes []*ListNode -} - -func newUnion(nodes []*ListNode) *UnionNode { - return &UnionNode{NodeType: NodeUnion, Nodes: nodes} -} - -func (u *UnionNode) String() string { - return fmt.Sprintf("%s", u.Type()) -} diff --git a/pkg/util/jsonpath/parser.go b/pkg/util/jsonpath/parser.go deleted file mode 100644 index 7dc38d31fc3..00000000000 --- a/pkg/util/jsonpath/parser.go +++ /dev/null @@ -1,433 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package jsonpath - -import ( - "fmt" - "regexp" - "strconv" - "strings" - "unicode" - "unicode/utf8" -) - -const eof = -1 - -const ( - leftDelim = "{" - rightDelim = "}" -) - -type Parser struct { - Name string - Root *ListNode - input string - cur *ListNode - pos int - start int - width int -} - -// Parse parsed the given text and return a node Parser. -// If an error is encountered, parsing stops and an empty -// Parser is returned with the error -func Parse(name, text string) (*Parser, error) { - p := NewParser(name) - err := p.Parse(text) - if err != nil { - p = nil - } - return p, err -} - -func NewParser(name string) *Parser { - return &Parser{ - Name: name, - } -} - -// parseAction parsed the expression inside delimiter -func parseAction(name, text string) (*Parser, error) { - p, err := Parse(name, fmt.Sprintf("%s%s%s", leftDelim, text, rightDelim)) - // when error happens, p will be nil, so we need to return here - if err != nil { - return p, err - } - p.Root = p.Root.Nodes[0].(*ListNode) - return p, nil -} - -func (p *Parser) Parse(text string) error { - p.input = text - p.Root = newList() - p.pos = 0 - return p.parseText(p.Root) -} - -// consumeText return the parsed text since last cosumeText -func (p *Parser) consumeText() string { - value := p.input[p.start:p.pos] - p.start = p.pos - return value -} - -// next returns the next rune in the input. -func (p *Parser) next() rune { - if int(p.pos) >= len(p.input) { - p.width = 0 - return eof - } - r, w := utf8.DecodeRuneInString(p.input[p.pos:]) - p.width = w - p.pos += p.width - return r -} - -// peek returns but does not consume the next rune in the input. -func (p *Parser) peek() rune { - r := p.next() - p.backup() - return r -} - -// backup steps back one rune. Can only be called once per call of next. -func (p *Parser) backup() { - p.pos -= p.width -} - -func (p *Parser) parseText(cur *ListNode) error { - for { - if strings.HasPrefix(p.input[p.pos:], leftDelim) { - if p.pos > p.start { - cur.append(newText(p.consumeText())) - } - return p.parseLeftDelim(cur) - } - if p.next() == eof { - break - } - } - // Correctly reached EOF. - if p.pos > p.start { - cur.append(newText(p.consumeText())) - } - return nil -} - -// parseLeftDelim scans the left delimiter, which is known to be present. -func (p *Parser) parseLeftDelim(cur *ListNode) error { - p.pos += len(leftDelim) - p.consumeText() - newNode := newList() - cur.append(newNode) - cur = newNode - return p.parseInsideAction(cur) -} - -func (p *Parser) parseInsideAction(cur *ListNode) error { - prefixMap := map[string]func(*ListNode) error{ - rightDelim: p.parseRightDelim, - "[?(": p.parseFilter, - "..": p.parseRecursive, - } - for prefix, parseFunc := range prefixMap { - if strings.HasPrefix(p.input[p.pos:], prefix) { - return parseFunc(cur) - } - } - - switch r := p.next(); { - case r == eof || isEndOfLine(r): - return fmt.Errorf("unclosed action") - case r == ' ': - p.consumeText() - case r == '@' || r == '$': //the current object, just pass it - p.consumeText() - case r == '[': - return p.parseArray(cur) - case r == '"': - return p.parseQuote(cur) - case r == '.': - return p.parseField(cur) - case r == '+' || r == '-' || unicode.IsDigit(r): - p.backup() - return p.parseNumber(cur) - case isAlphaNumeric(r): - p.backup() - return p.parseIdentifier(cur) - default: - return fmt.Errorf("unrecognized character in action: %#U", r) - } - return p.parseInsideAction(cur) -} - -// parseRightDelim scans the right delimiter, which is known to be present. -func (p *Parser) parseRightDelim(cur *ListNode) error { - p.pos += len(rightDelim) - p.consumeText() - cur = p.Root - return p.parseText(cur) -} - -// parseIdentifier scans build-in keywords, like "range" "end" -func (p *Parser) parseIdentifier(cur *ListNode) error { - var r rune - for { - r = p.next() - if isTerminator(r) { - p.backup() - break - } - } - value := p.consumeText() - cur.append(newIdentifier(value)) - return p.parseInsideAction(cur) -} - -// parseRecursive scans the recursive desent operator .. -func (p *Parser) parseRecursive(cur *ListNode) error { - p.pos += len("..") - p.consumeText() - cur.append(newRecursive()) - if r := p.peek(); isAlphaNumeric(r) { - return p.parseField(cur) - } - return p.parseInsideAction(cur) -} - -// parseNumber scans number -func (p *Parser) parseNumber(cur *ListNode) error { - r := p.peek() - if r == '+' || r == '-' { - r = p.next() - } - for { - r = p.next() - if r != '.' && !unicode.IsDigit(r) { - p.backup() - break - } - } - value := p.consumeText() - i, err := strconv.Atoi(value) - if err == nil { - cur.append(newInt(i)) - return p.parseInsideAction(cur) - } - d, err := strconv.ParseFloat(value, 64) - if err == nil { - cur.append(newFloat(d)) - return p.parseInsideAction(cur) - } - return fmt.Errorf("cannot parse number %s", value) -} - -// parseArray scans array index selection -func (p *Parser) parseArray(cur *ListNode) error { -Loop: - for { - switch p.next() { - case eof, '\n': - return fmt.Errorf("unterminated array") - case ']': - break Loop - } - } - text := p.consumeText() - text = string(text[1 : len(text)-1]) - if text == "*" { - text = ":" - } - - //union operator - strs := strings.Split(text, ",") - if len(strs) > 1 { - union := []*ListNode{} - for _, str := range strs { - parser, err := parseAction("union", fmt.Sprintf("[%s]", strings.Trim(str, " "))) - if err != nil { - return err - } - union = append(union, parser.Root) - } - cur.append(newUnion(union)) - return p.parseInsideAction(cur) - } - - // dict key - reg := regexp.MustCompile(`^'([^']*)'$`) - value := reg.FindStringSubmatch(text) - if value != nil { - parser, err := parseAction("arraydict", fmt.Sprintf(".%s", value[1])) - if err != nil { - return err - } - for _, node := range parser.Root.Nodes { - cur.append(node) - } - return p.parseInsideAction(cur) - } - - //slice operator - reg = regexp.MustCompile(`^(-?[\d]*)(:-?[\d]*)?(:[\d]*)?$`) - value = reg.FindStringSubmatch(text) - if value == nil { - return fmt.Errorf("invalid array index %s", text) - } - value = value[1:] - params := [3]ParamsEntry{} - for i := 0; i < 3; i++ { - if value[i] != "" { - if i > 0 { - value[i] = value[i][1:] - } - if i > 0 && value[i] == "" { - params[i].Known = false - } else { - var err error - params[i].Known = true - params[i].Value, err = strconv.Atoi(value[i]) - if err != nil { - return fmt.Errorf("array index %s is not a number", value[i]) - } - } - } else { - if i == 1 { - params[i].Known = true - params[i].Value = params[0].Value + 1 - } else { - params[i].Known = false - params[i].Value = 0 - } - } - } - cur.append(newArray(params)) - return p.parseInsideAction(cur) -} - -// parseFilter scans filter inside array selection -func (p *Parser) parseFilter(cur *ListNode) error { - p.pos += len("[?(") - p.consumeText() -Loop: - for { - switch p.next() { - case eof, '\n': - return fmt.Errorf("unterminated filter") - case ')': - break Loop - } - } - if p.next() != ']' { - return fmt.Errorf("unclosed array expect ]") - } - reg := regexp.MustCompile(`^([^!<>=]+)([!<>=]+)(.+?)$`) - text := p.consumeText() - text = string(text[:len(text)-2]) - value := reg.FindStringSubmatch(text) - if value == nil { - parser, err := parseAction("text", text) - if err != nil { - return err - } - cur.append(newFilter(parser.Root, newList(), "exists")) - } else { - leftParser, err := parseAction("left", value[1]) - if err != nil { - return err - } - rightParser, err := parseAction("right", value[3]) - if err != nil { - return err - } - cur.append(newFilter(leftParser.Root, rightParser.Root, value[2])) - } - return p.parseInsideAction(cur) -} - -// parseQuote unquotes string inside double quote -func (p *Parser) parseQuote(cur *ListNode) error { -Loop: - for { - switch p.next() { - case eof, '\n': - return fmt.Errorf("unterminated quoted string") - case '"': - break Loop - } - } - value := p.consumeText() - s, err := strconv.Unquote(value) - if err != nil { - return fmt.Errorf("unquote string %s error %v", value, err) - } - cur.append(newText(s)) - return p.parseInsideAction(cur) -} - -// parseField scans a field until a terminator -func (p *Parser) parseField(cur *ListNode) error { - p.consumeText() - for p.advance() { - } - value := p.consumeText() - if value == "*" { - cur.append(newWildcard()) - } else { - cur.append(newField(strings.Replace(value, "\\", "", -1))) - } - return p.parseInsideAction(cur) -} - -// advance scans until next non-escaped terminator -func (p *Parser) advance() bool { - r := p.next() - if r == '\\' { - p.next() - } else if isTerminator(r) { - p.backup() - return false - } - return true -} - -// isTerminator reports whether the input is at valid termination character to appear after an identifier. -func isTerminator(r rune) bool { - if isSpace(r) || isEndOfLine(r) { - return true - } - switch r { - case eof, '.', ',', '[', ']', '$', '@', '{', '}': - return true - } - return false -} - -// isSpace reports whether r is a space character. -func isSpace(r rune) bool { - return r == ' ' || r == '\t' -} - -// isEndOfLine reports whether r is an end-of-line character. -func isEndOfLine(r rune) bool { - return r == '\r' || r == '\n' -} - -// isAlphaNumeric reports whether r is an alphabetic, digit, or underscore. -func isAlphaNumeric(r rune) bool { - return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r) -} diff --git a/plugin/pkg/client/auth/BUILD b/plugin/pkg/client/auth/BUILD deleted file mode 100644 index 11c15383f4c..00000000000 --- a/plugin/pkg/client/auth/BUILD +++ /dev/null @@ -1,35 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -licenses(["notice"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["plugins.go"], - tags = ["automanaged"], - deps = [ - "//plugin/pkg/client/auth/gcp:go_default_library", - "//plugin/pkg/client/auth/oidc:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//plugin/pkg/client/auth/gcp:all-srcs", - "//plugin/pkg/client/auth/oidc:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/plugin/pkg/client/auth/gcp/BUILD b/plugin/pkg/client/auth/gcp/BUILD deleted file mode 100644 index 9ee4167c241..00000000000 --- a/plugin/pkg/client/auth/gcp/BUILD +++ /dev/null @@ -1,45 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -licenses(["notice"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", - "go_test", -) - -go_library( - name = "go_default_library", - srcs = ["gcp.go"], - tags = ["automanaged"], - deps = [ - "//pkg/util/jsonpath:go_default_library", - "//vendor:github.com/golang/glog", - "//vendor:golang.org/x/net/context", - "//vendor:golang.org/x/oauth2", - "//vendor:golang.org/x/oauth2/google", - "//vendor:k8s.io/apimachinery/pkg/util/yaml", - "//vendor:k8s.io/client-go/rest", - ], -) - -go_test( - name = "go_default_test", - srcs = ["gcp_test.go"], - library = ":go_default_library", - tags = ["automanaged"], - deps = ["//vendor:golang.org/x/oauth2"], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], -) diff --git a/plugin/pkg/client/auth/gcp/OWNERS b/plugin/pkg/client/auth/gcp/OWNERS deleted file mode 100644 index d75421c5efd..00000000000 --- a/plugin/pkg/client/auth/gcp/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -assignees: - - cjcullen - - jlowdermilk diff --git a/plugin/pkg/client/auth/gcp/gcp.go b/plugin/pkg/client/auth/gcp/gcp.go deleted file mode 100644 index 8cde8a46d5b..00000000000 --- a/plugin/pkg/client/auth/gcp/gcp.go +++ /dev/null @@ -1,274 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gcp - -import ( - "bytes" - "encoding/json" - "fmt" - "net/http" - "os/exec" - "strings" - "sync" - "time" - - "github.com/golang/glog" - "golang.org/x/net/context" - "golang.org/x/oauth2" - "golang.org/x/oauth2/google" - "k8s.io/apimachinery/pkg/util/yaml" - restclient "k8s.io/client-go/rest" - "k8s.io/kubernetes/pkg/util/jsonpath" -) - -func init() { - if err := restclient.RegisterAuthProviderPlugin("gcp", newGCPAuthProvider); err != nil { - glog.Fatalf("Failed to register gcp auth plugin: %v", err) - } -} - -// gcpAuthProvider is an auth provider plugin that uses GCP credentials to provide -// tokens for kubectl to authenticate itself to the apiserver. A sample json config -// is provided below with all recognized options described. -// -// { -// 'auth-provider': { -// # Required -// "name": "gcp", -// -// 'config': { -// # Caching options -// -// # Raw string data representing cached access token. -// "access-token": "ya29.CjWdA4GiBPTt", -// # RFC3339Nano expiration timestamp for cached access token. -// "expiry": "2016-10-31 22:31:9.123", -// -// # Command execution options -// # These options direct the plugin to execute a specified command and parse -// # token and expiry time from the output of the command. -// -// # Command to execute for access token. String is split on whitespace -// # with first field treated as the executable, remaining fields as args. -// # Command output will be parsed as JSON. -// "cmd-path": "/usr/bin/gcloud config config-helper --output=json", -// -// # JSONPath to the string field that represents the access token in -// # command output. If omitted, defaults to "{.access_token}". -// "token-key": "{.credential.access_token}", -// -// # JSONPath to the string field that represents expiration timestamp -// # of the access token in the command output. If omitted, defaults to -// # "{.token_expiry}" -// "expiry-key": ""{.credential.token_expiry}", -// -// # golang reference time in the format that the expiration timestamp uses. -// # If omitted, defaults to time.RFC3339Nano -// "time-fmt": "2006-01-02 15:04:05.999999999" -// } -// } -// } -// -type gcpAuthProvider struct { - tokenSource oauth2.TokenSource - persister restclient.AuthProviderConfigPersister -} - -func newGCPAuthProvider(_ string, gcpConfig map[string]string, persister restclient.AuthProviderConfigPersister) (restclient.AuthProvider, error) { - cmd, useCmd := gcpConfig["cmd-path"] - var ts oauth2.TokenSource - var err error - if useCmd { - ts, err = newCmdTokenSource(cmd, gcpConfig["token-key"], gcpConfig["expiry-key"], gcpConfig["time-fmt"]) - } else { - ts, err = google.DefaultTokenSource(context.Background(), "https://www.googleapis.com/auth/cloud-platform") - } - if err != nil { - return nil, err - } - cts, err := newCachedTokenSource(gcpConfig["access-token"], gcpConfig["expiry"], persister, ts, gcpConfig) - if err != nil { - return nil, err - } - return &gcpAuthProvider{cts, persister}, nil -} - -func (g *gcpAuthProvider) WrapTransport(rt http.RoundTripper) http.RoundTripper { - return &oauth2.Transport{ - Source: g.tokenSource, - Base: rt, - } -} - -func (g *gcpAuthProvider) Login() error { return nil } - -type cachedTokenSource struct { - lk sync.Mutex - source oauth2.TokenSource - accessToken string - expiry time.Time - persister restclient.AuthProviderConfigPersister - cache map[string]string -} - -func newCachedTokenSource(accessToken, expiry string, persister restclient.AuthProviderConfigPersister, ts oauth2.TokenSource, cache map[string]string) (*cachedTokenSource, error) { - var expiryTime time.Time - if parsedTime, err := time.Parse(time.RFC3339Nano, expiry); err == nil { - expiryTime = parsedTime - } - if cache == nil { - cache = make(map[string]string) - } - return &cachedTokenSource{ - source: ts, - accessToken: accessToken, - expiry: expiryTime, - persister: persister, - cache: cache, - }, nil -} - -func (t *cachedTokenSource) Token() (*oauth2.Token, error) { - tok := t.cachedToken() - if tok.Valid() && !tok.Expiry.IsZero() { - return tok, nil - } - tok, err := t.source.Token() - if err != nil { - return nil, err - } - cache := t.update(tok) - if t.persister != nil { - if err := t.persister.Persist(cache); err != nil { - glog.V(4).Infof("Failed to persist token: %v", err) - } - } - return tok, nil -} - -func (t *cachedTokenSource) cachedToken() *oauth2.Token { - t.lk.Lock() - defer t.lk.Unlock() - return &oauth2.Token{ - AccessToken: t.accessToken, - TokenType: "Bearer", - Expiry: t.expiry, - } -} - -func (t *cachedTokenSource) update(tok *oauth2.Token) map[string]string { - t.lk.Lock() - defer t.lk.Unlock() - t.accessToken = tok.AccessToken - t.expiry = tok.Expiry - ret := map[string]string{} - for k, v := range t.cache { - ret[k] = v - } - ret["access-token"] = t.accessToken - ret["expiry"] = t.expiry.Format(time.RFC3339Nano) - return ret -} - -type commandTokenSource struct { - cmd string - args []string - tokenKey string - expiryKey string - timeFmt string -} - -func newCmdTokenSource(cmd, tokenKey, expiryKey, timeFmt string) (*commandTokenSource, error) { - if len(timeFmt) == 0 { - timeFmt = time.RFC3339Nano - } - if len(tokenKey) == 0 { - tokenKey = "{.access_token}" - } - if len(expiryKey) == 0 { - expiryKey = "{.token_expiry}" - } - fields := strings.Fields(cmd) - if len(fields) == 0 { - return nil, fmt.Errorf("missing access token cmd") - } - return &commandTokenSource{ - cmd: fields[0], - args: fields[1:], - tokenKey: tokenKey, - expiryKey: expiryKey, - timeFmt: timeFmt, - }, nil -} - -func (c *commandTokenSource) Token() (*oauth2.Token, error) { - fullCmd := fmt.Sprintf("%s %s", c.cmd, strings.Join(c.args, " ")) - cmd := exec.Command(c.cmd, c.args...) - output, err := cmd.Output() - if err != nil { - return nil, fmt.Errorf("error executing access token command %q: %v", fullCmd, err) - } - token, err := c.parseTokenCmdOutput(output) - if err != nil { - return nil, fmt.Errorf("error parsing output for access token command %q: %v", fullCmd, err) - } - return token, nil -} - -func (c *commandTokenSource) parseTokenCmdOutput(output []byte) (*oauth2.Token, error) { - output, err := yaml.ToJSON(output) - if err != nil { - return nil, err - } - var data interface{} - if err := json.Unmarshal(output, &data); err != nil { - return nil, err - } - - accessToken, err := parseJSONPath(data, "token-key", c.tokenKey) - if err != nil { - return nil, fmt.Errorf("error parsing token-key %q: %v", c.tokenKey, err) - } - expiryStr, err := parseJSONPath(data, "expiry-key", c.expiryKey) - if err != nil { - return nil, fmt.Errorf("error parsing expiry-key %q: %v", c.expiryKey, err) - } - var expiry time.Time - if t, err := time.Parse(c.timeFmt, expiryStr); err != nil { - glog.V(4).Infof("Failed to parse token expiry from %s (fmt=%s): %v", expiryStr, c.timeFmt, err) - } else { - expiry = t - } - - return &oauth2.Token{ - AccessToken: accessToken, - TokenType: "Bearer", - Expiry: expiry, - }, nil -} - -func parseJSONPath(input interface{}, name, template string) (string, error) { - j := jsonpath.New(name) - buf := new(bytes.Buffer) - if err := j.Parse(template); err != nil { - return "", err - } - if err := j.Execute(buf, input); err != nil { - return "", err - } - return buf.String(), nil -} diff --git a/plugin/pkg/client/auth/gcp/gcp_test.go b/plugin/pkg/client/auth/gcp/gcp_test.go deleted file mode 100644 index cb64b8380ca..00000000000 --- a/plugin/pkg/client/auth/gcp/gcp_test.go +++ /dev/null @@ -1,211 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gcp - -import ( - "fmt" - "reflect" - "strings" - "sync" - "testing" - "time" - - "golang.org/x/oauth2" -) - -func TestCmdTokenSource(t *testing.T) { - fakeExpiry := time.Date(2016, 10, 31, 22, 31, 9, 123000000, time.UTC) - customFmt := "2006-01-02 15:04:05.999999999" - - tests := []struct { - name string - output []byte - cmd, tokenKey, expiryKey, timeFmt string - tok *oauth2.Token - expectErr error - }{ - { - "defaults", - []byte(`{ - "access_token": "faketoken", - "token_expiry": "2016-10-31T22:31:09.123000000Z" -}`), - "/fake/cmd/path", "", "", "", - &oauth2.Token{ - AccessToken: "faketoken", - TokenType: "Bearer", - Expiry: fakeExpiry, - }, - nil, - }, - { - "custom keys", - []byte(`{ - "token": "faketoken", - "token_expiry": { - "datetime": "2016-10-31 22:31:09.123" - } -}`), - "/fake/cmd/path", "{.token}", "{.token_expiry.datetime}", customFmt, - &oauth2.Token{ - AccessToken: "faketoken", - TokenType: "Bearer", - Expiry: fakeExpiry, - }, - nil, - }, - { - "missing cmd", - nil, - "", "", "", "", - nil, - fmt.Errorf("missing access token cmd"), - }, - { - "missing token-key", - []byte(`{ - "broken": "faketoken", - "token_expiry": { - "datetime": "2016-10-31 22:31:09.123000000Z" - } -}`), - "/fake/cmd/path", "{.token}", "", "", - nil, - fmt.Errorf("error parsing token-key %q", "{.token}"), - }, - { - "missing expiry-key", - []byte(`{ - "access_token": "faketoken", - "expires": "2016-10-31T22:31:09.123000000Z" -}`), - "/fake/cmd/path", "", "{.expiry}", "", - nil, - fmt.Errorf("error parsing expiry-key %q", "{.expiry}"), - }, - { - "invalid expiry timestamp", - []byte(`{ - "access_token": "faketoken", - "token_expiry": "sometime soon, idk" -}`), - "/fake/cmd/path", "", "", "", - &oauth2.Token{ - AccessToken: "faketoken", - TokenType: "Bearer", - Expiry: time.Time{}, - }, - nil, - }, - { - "bad JSON", - []byte(`{ - "access_token": "faketoken", - "token_expiry": "sometime soon, idk" - ------ -`), - "/fake/cmd", "", "", "", - nil, - fmt.Errorf("invalid character '-' after object key:value pair"), - }, - } - - for _, tc := range tests { - ts, err := newCmdTokenSource(tc.cmd, tc.tokenKey, tc.expiryKey, tc.timeFmt) - if err != nil { - if !strings.Contains(err.Error(), tc.expectErr.Error()) { - t.Errorf("%s newCmdTokenSource error: %v, want %v", tc.name, err, tc.expectErr) - } - continue - } - tok, err := ts.parseTokenCmdOutput(tc.output) - - if err != tc.expectErr && !strings.Contains(err.Error(), tc.expectErr.Error()) { - t.Errorf("%s parseCmdTokenSource error: %v, want %v", tc.name, err, tc.expectErr) - } - if !reflect.DeepEqual(tok, tc.tok) { - t.Errorf("%s got token %v, want %v", tc.name, tok, tc.tok) - } - } -} - -type fakePersister struct { - lk sync.Mutex - cache map[string]string -} - -func (f *fakePersister) Persist(cache map[string]string) error { - f.lk.Lock() - defer f.lk.Unlock() - f.cache = map[string]string{} - for k, v := range cache { - f.cache[k] = v - } - return nil -} - -func (f *fakePersister) read() map[string]string { - ret := map[string]string{} - f.lk.Lock() - for k, v := range f.cache { - ret[k] = v - } - return ret -} - -type fakeTokenSource struct { - token *oauth2.Token - err error -} - -func (f *fakeTokenSource) Token() (*oauth2.Token, error) { - return f.token, f.err -} - -func TestCachedTokenSource(t *testing.T) { - tok := &oauth2.Token{AccessToken: "fakeaccesstoken"} - persister := &fakePersister{} - source := &fakeTokenSource{ - token: tok, - err: nil, - } - cache := map[string]string{ - "foo": "bar", - "baz": "bazinga", - } - ts, err := newCachedTokenSource("fakeaccesstoken", "", persister, source, cache) - if err != nil { - t.Fatal(err) - } - var wg sync.WaitGroup - wg.Add(10) - for i := 0; i < 10; i++ { - go func() { - _, err := ts.Token() - if err != nil { - t.Errorf("unexpected error: %s", err) - } - wg.Done() - }() - } - wg.Wait() - cache["access-token"] = "fakeaccesstoken" - cache["expiry"] = tok.Expiry.Format(time.RFC3339Nano) - if got := persister.read(); !reflect.DeepEqual(got, cache) { - t.Errorf("got cache %v, want %v", got, cache) - } -} diff --git a/plugin/pkg/client/auth/oidc/BUILD b/plugin/pkg/client/auth/oidc/BUILD deleted file mode 100644 index 522a4a4e746..00000000000 --- a/plugin/pkg/client/auth/oidc/BUILD +++ /dev/null @@ -1,48 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -licenses(["notice"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", - "go_test", -) - -go_library( - name = "go_default_library", - srcs = ["oidc.go"], - tags = ["automanaged"], - deps = [ - "//vendor:github.com/coreos/go-oidc/jose", - "//vendor:github.com/coreos/go-oidc/oauth2", - "//vendor:github.com/coreos/go-oidc/oidc", - "//vendor:github.com/golang/glog", - "//vendor:k8s.io/client-go/rest", - ], -) - -go_test( - name = "go_default_test", - srcs = ["oidc_test.go"], - library = ":go_default_library", - tags = ["automanaged"], - deps = [ - "//plugin/pkg/auth/authenticator/token/oidc/testing:go_default_library", - "//vendor:github.com/coreos/go-oidc/jose", - "//vendor:github.com/coreos/go-oidc/key", - "//vendor:github.com/coreos/go-oidc/oauth2", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], -) diff --git a/plugin/pkg/client/auth/oidc/OWNERS b/plugin/pkg/client/auth/oidc/OWNERS deleted file mode 100644 index 2f80bc7e10f..00000000000 --- a/plugin/pkg/client/auth/oidc/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -assignees: - - ericchiang diff --git a/plugin/pkg/client/auth/oidc/oidc.go b/plugin/pkg/client/auth/oidc/oidc.go deleted file mode 100644 index ca5b72cbd60..00000000000 --- a/plugin/pkg/client/auth/oidc/oidc.go +++ /dev/null @@ -1,333 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package oidc - -import ( - "encoding/base64" - "errors" - "fmt" - "net/http" - "strings" - "sync" - "time" - - "github.com/coreos/go-oidc/jose" - "github.com/coreos/go-oidc/oauth2" - "github.com/coreos/go-oidc/oidc" - "github.com/golang/glog" - - restclient "k8s.io/client-go/rest" -) - -const ( - cfgIssuerUrl = "idp-issuer-url" - cfgClientID = "client-id" - cfgClientSecret = "client-secret" - cfgCertificateAuthority = "idp-certificate-authority" - cfgCertificateAuthorityData = "idp-certificate-authority-data" - cfgExtraScopes = "extra-scopes" - cfgIDToken = "id-token" - cfgRefreshToken = "refresh-token" -) - -func init() { - if err := restclient.RegisterAuthProviderPlugin("oidc", newOIDCAuthProvider); err != nil { - glog.Fatalf("Failed to register oidc auth plugin: %v", err) - } -} - -// expiryDelta determines how earlier a token should be considered -// expired than its actual expiration time. It is used to avoid late -// expirations due to client-server time mismatches. -// -// NOTE(ericchiang): this is take from golang.org/x/oauth2 -const expiryDelta = 10 * time.Second - -var cache = newClientCache() - -// Like TLS transports, keep a cache of OIDC clients indexed by issuer URL. -type clientCache struct { - mu sync.RWMutex - cache map[cacheKey]*oidcAuthProvider -} - -func newClientCache() *clientCache { - return &clientCache{cache: make(map[cacheKey]*oidcAuthProvider)} -} - -type cacheKey struct { - // Canonical issuer URL string of the provider. - issuerURL string - - clientID string - clientSecret string - - // Don't use CA as cache key because we only add a cache entry if we can connect - // to the issuer in the first place. A valid CA is a prerequisite. -} - -func (c *clientCache) getClient(issuer, clientID, clientSecret string) (*oidcAuthProvider, bool) { - c.mu.RLock() - defer c.mu.RUnlock() - client, ok := c.cache[cacheKey{issuer, clientID, clientSecret}] - return client, ok -} - -// setClient attempts to put the client in the cache but may return any clients -// with the same keys set before. This is so there's only ever one client for a provider. -func (c *clientCache) setClient(issuer, clientID, clientSecret string, client *oidcAuthProvider) *oidcAuthProvider { - c.mu.Lock() - defer c.mu.Unlock() - key := cacheKey{issuer, clientID, clientSecret} - - // If another client has already initialized a client for the given provider we want - // to use that client instead of the one we're trying to set. This is so all transports - // share a client and can coordinate around the same mutex when refreshing and writing - // to the kubeconfig. - if oldClient, ok := c.cache[key]; ok { - return oldClient - } - - c.cache[key] = client - return client -} - -func newOIDCAuthProvider(_ string, cfg map[string]string, persister restclient.AuthProviderConfigPersister) (restclient.AuthProvider, error) { - issuer := cfg[cfgIssuerUrl] - if issuer == "" { - return nil, fmt.Errorf("Must provide %s", cfgIssuerUrl) - } - - clientID := cfg[cfgClientID] - if clientID == "" { - return nil, fmt.Errorf("Must provide %s", cfgClientID) - } - - clientSecret := cfg[cfgClientSecret] - if clientSecret == "" { - return nil, fmt.Errorf("Must provide %s", cfgClientSecret) - } - - // Check cache for existing provider. - if provider, ok := cache.getClient(issuer, clientID, clientSecret); ok { - return provider, nil - } - - var certAuthData []byte - var err error - if cfg[cfgCertificateAuthorityData] != "" { - certAuthData, err = base64.StdEncoding.DecodeString(cfg[cfgCertificateAuthorityData]) - if err != nil { - return nil, err - } - } - - clientConfig := restclient.Config{ - TLSClientConfig: restclient.TLSClientConfig{ - CAFile: cfg[cfgCertificateAuthority], - CAData: certAuthData, - }, - } - - trans, err := restclient.TransportFor(&clientConfig) - if err != nil { - return nil, err - } - hc := &http.Client{Transport: trans} - - providerCfg, err := oidc.FetchProviderConfig(hc, issuer) - if err != nil { - return nil, fmt.Errorf("error fetching provider config: %v", err) - } - - scopes := strings.Split(cfg[cfgExtraScopes], ",") - oidcCfg := oidc.ClientConfig{ - HTTPClient: hc, - Credentials: oidc.ClientCredentials{ - ID: clientID, - Secret: clientSecret, - }, - ProviderConfig: providerCfg, - Scope: append(scopes, oidc.DefaultScope...), - } - client, err := oidc.NewClient(oidcCfg) - if err != nil { - return nil, fmt.Errorf("error creating OIDC Client: %v", err) - } - - provider := &oidcAuthProvider{ - client: &oidcClient{client}, - cfg: cfg, - persister: persister, - now: time.Now, - } - - return cache.setClient(issuer, clientID, clientSecret, provider), nil -} - -type oidcAuthProvider struct { - // Interface rather than a raw *oidc.Client for testing. - client OIDCClient - - // Stubbed out for testing. - now func() time.Time - - // Mutex guards persisting to the kubeconfig file and allows synchronized - // updates to the in-memory config. It also ensures concurrent calls to - // the RoundTripper only trigger a single refresh request. - mu sync.Mutex - cfg map[string]string - persister restclient.AuthProviderConfigPersister -} - -func (p *oidcAuthProvider) WrapTransport(rt http.RoundTripper) http.RoundTripper { - return &roundTripper{ - wrapped: rt, - provider: p, - } -} - -func (p *oidcAuthProvider) Login() error { - return errors.New("not yet implemented") -} - -type OIDCClient interface { - refreshToken(rt string) (oauth2.TokenResponse, error) - verifyJWT(jwt *jose.JWT) error -} - -type roundTripper struct { - provider *oidcAuthProvider - wrapped http.RoundTripper -} - -func (r *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - token, err := r.provider.idToken() - if err != nil { - return nil, err - } - - // shallow copy of the struct - r2 := new(http.Request) - *r2 = *req - // deep copy of the Header so we don't modify the original - // request's Header (as per RoundTripper contract). - r2.Header = make(http.Header) - for k, s := range req.Header { - r2.Header[k] = s - } - r2.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) - - return r.wrapped.RoundTrip(r2) -} - -func (p *oidcAuthProvider) idToken() (string, error) { - p.mu.Lock() - defer p.mu.Unlock() - - if idToken, ok := p.cfg[cfgIDToken]; ok && len(idToken) > 0 { - valid, err := verifyJWTExpiry(p.now(), idToken) - if err != nil { - return "", err - } - if valid { - // If the cached id token is still valid use it. - return idToken, nil - } - } - - // Try to request a new token using the refresh token. - rt, ok := p.cfg[cfgRefreshToken] - if !ok || len(rt) == 0 { - return "", errors.New("No valid id-token, and cannot refresh without refresh-token") - } - - tokens, err := p.client.refreshToken(rt) - if err != nil { - return "", fmt.Errorf("could not refresh token: %v", err) - } - jwt, err := jose.ParseJWT(tokens.IDToken) - if err != nil { - return "", err - } - - if err := p.client.verifyJWT(&jwt); err != nil { - return "", err - } - - // Create a new config to persist. - newCfg := make(map[string]string) - for key, val := range p.cfg { - newCfg[key] = val - } - - if tokens.RefreshToken != "" && tokens.RefreshToken != rt { - newCfg[cfgRefreshToken] = tokens.RefreshToken - } - - newCfg[cfgIDToken] = tokens.IDToken - if err = p.persister.Persist(newCfg); err != nil { - return "", fmt.Errorf("could not perist new tokens: %v", err) - } - - // Update the in memory config to reflect the on disk one. - p.cfg = newCfg - - return tokens.IDToken, nil -} - -// oidcClient is the real implementation of the OIDCClient interface, which is -// used for testing. -type oidcClient struct { - client *oidc.Client -} - -func (o *oidcClient) refreshToken(rt string) (oauth2.TokenResponse, error) { - oac, err := o.client.OAuthClient() - if err != nil { - return oauth2.TokenResponse{}, err - } - - return oac.RequestToken(oauth2.GrantTypeRefreshToken, rt) -} - -func (o *oidcClient) verifyJWT(jwt *jose.JWT) error { - return o.client.VerifyJWT(*jwt) -} - -func verifyJWTExpiry(now time.Time, s string) (valid bool, err error) { - jwt, err := jose.ParseJWT(s) - if err != nil { - return false, fmt.Errorf("invalid %q", cfgIDToken) - } - claims, err := jwt.Claims() - if err != nil { - return false, err - } - - exp, ok, err := claims.TimeClaim("exp") - switch { - case err != nil: - return false, fmt.Errorf("failed to parse 'exp' claim: %v", err) - case !ok: - return false, errors.New("missing required 'exp' claim") - case exp.After(now.Add(expiryDelta)): - return true, nil - } - - return false, nil -} diff --git a/plugin/pkg/client/auth/oidc/oidc_test.go b/plugin/pkg/client/auth/oidc/oidc_test.go deleted file mode 100644 index 16e11492818..00000000000 --- a/plugin/pkg/client/auth/oidc/oidc_test.go +++ /dev/null @@ -1,384 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package oidc - -import ( - "encoding/base64" - "errors" - "io/ioutil" - "os" - "path" - "reflect" - "testing" - "time" - - "github.com/coreos/go-oidc/jose" - "github.com/coreos/go-oidc/key" - "github.com/coreos/go-oidc/oauth2" - - oidctesting "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc/testing" -) - -func clearCache() { - cache = newClientCache() -} - -type persister struct{} - -// we don't need to actually persist anything because there's no way for us to -// read from a persister. -func (p *persister) Persist(map[string]string) error { return nil } - -type noRefreshOIDCClient struct{} - -func (c *noRefreshOIDCClient) refreshToken(rt string) (oauth2.TokenResponse, error) { - return oauth2.TokenResponse{}, errors.New("alwaysErrOIDCClient: cannot refresh token") -} - -func (c *noRefreshOIDCClient) verifyJWT(jwt *jose.JWT) error { - return nil -} - -type mockOIDCClient struct { - tokenResponse oauth2.TokenResponse -} - -func (c *mockOIDCClient) refreshToken(rt string) (oauth2.TokenResponse, error) { - return c.tokenResponse, nil -} - -func (c *mockOIDCClient) verifyJWT(jwt *jose.JWT) error { - return nil -} - -func TestNewOIDCAuthProvider(t *testing.T) { - tempDir, err := ioutil.TempDir(os.TempDir(), "oidc_test") - if err != nil { - t.Fatalf("Cannot make temp dir %v", err) - } - cert := path.Join(tempDir, "oidc-cert") - key := path.Join(tempDir, "oidc-key") - defer os.RemoveAll(tempDir) - - oidctesting.GenerateSelfSignedCert(t, "127.0.0.1", cert, key) - op := oidctesting.NewOIDCProvider(t, "") - srv, err := op.ServeTLSWithKeyPair(cert, key) - if err != nil { - t.Fatalf("Cannot start server %v", err) - } - defer srv.Close() - - certData, err := ioutil.ReadFile(cert) - if err != nil { - t.Fatalf("Could not read cert bytes %v", err) - } - - makeToken := func(exp time.Time) *jose.JWT { - jwt, err := jose.NewSignedJWT(jose.Claims(map[string]interface{}{ - "exp": exp.UTC().Unix(), - }), op.PrivKey.Signer()) - if err != nil { - t.Fatalf("Could not create signed JWT %v", err) - } - return jwt - } - - t0 := time.Now() - - goodToken := makeToken(t0.Add(time.Hour)).Encode() - expiredToken := makeToken(t0.Add(-time.Hour)).Encode() - - tests := []struct { - name string - - cfg map[string]string - wantInitErr bool - - client OIDCClient - wantCfg map[string]string - wantTokenErr bool - }{ - { - // A Valid configuration - name: "no id token and no refresh token", - cfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthority: cert, - cfgClientID: "client-id", - cfgClientSecret: "client-secret", - }, - wantTokenErr: true, - }, - { - name: "valid config with an initial token", - cfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthority: cert, - cfgClientID: "client-id", - cfgClientSecret: "client-secret", - cfgIDToken: goodToken, - }, - client: new(noRefreshOIDCClient), - wantCfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthority: cert, - cfgClientID: "client-id", - cfgClientSecret: "client-secret", - cfgIDToken: goodToken, - }, - }, - { - name: "invalid ID token with a refresh token", - cfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthority: cert, - cfgClientID: "client-id", - cfgClientSecret: "client-secret", - cfgRefreshToken: "foo", - cfgIDToken: expiredToken, - }, - client: &mockOIDCClient{ - tokenResponse: oauth2.TokenResponse{ - IDToken: goodToken, - }, - }, - wantCfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthority: cert, - cfgClientID: "client-id", - cfgClientSecret: "client-secret", - cfgRefreshToken: "foo", - cfgIDToken: goodToken, - }, - }, - { - name: "invalid ID token with a refresh token, server returns new refresh token", - cfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthority: cert, - cfgClientID: "client-id", - cfgClientSecret: "client-secret", - cfgRefreshToken: "foo", - cfgIDToken: expiredToken, - }, - client: &mockOIDCClient{ - tokenResponse: oauth2.TokenResponse{ - IDToken: goodToken, - RefreshToken: "bar", - }, - }, - wantCfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthority: cert, - cfgClientID: "client-id", - cfgClientSecret: "client-secret", - cfgRefreshToken: "bar", - cfgIDToken: goodToken, - }, - }, - { - name: "expired token and no refresh otken", - cfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthority: cert, - cfgClientID: "client-id", - cfgClientSecret: "client-secret", - cfgIDToken: expiredToken, - }, - wantTokenErr: true, - }, - { - name: "valid base64d ca", - cfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthorityData: base64.StdEncoding.EncodeToString(certData), - cfgClientID: "client-id", - cfgClientSecret: "client-secret", - }, - client: new(noRefreshOIDCClient), - wantTokenErr: true, - }, - { - name: "missing client ID", - cfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthority: cert, - cfgClientSecret: "client-secret", - }, - wantInitErr: true, - }, - { - name: "missing client secret", - cfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgCertificateAuthority: cert, - cfgClientID: "client-id", - }, - wantInitErr: true, - }, - { - name: "missing issuer URL", - cfg: map[string]string{ - cfgCertificateAuthority: cert, - cfgClientID: "client-id", - cfgClientSecret: "secret", - }, - wantInitErr: true, - }, - { - name: "missing TLS config", - cfg: map[string]string{ - cfgIssuerUrl: srv.URL, - cfgClientID: "client-id", - cfgClientSecret: "secret", - }, - wantInitErr: true, - }, - } - - for _, tt := range tests { - clearCache() - - p, err := newOIDCAuthProvider("cluster.example.com", tt.cfg, new(persister)) - if tt.wantInitErr { - if err == nil { - t.Errorf("%s: want non-nil err", tt.name) - } - continue - } - - if err != nil { - t.Errorf("%s: unexpected error on newOIDCAuthProvider: %v", tt.name, err) - continue - } - - provider := p.(*oidcAuthProvider) - provider.client = tt.client - provider.now = func() time.Time { return t0 } - - if _, err := provider.idToken(); err != nil { - if !tt.wantTokenErr { - t.Errorf("%s: failed to get id token: %v", tt.name, err) - } - continue - } - if tt.wantTokenErr { - t.Errorf("%s: expected to not get id token: %v", tt.name, err) - continue - } - - if !reflect.DeepEqual(tt.wantCfg, provider.cfg) { - t.Errorf("%s: expected config %#v got %#v", tt.name, tt.wantCfg, provider.cfg) - } - } -} - -func TestVerifyJWTExpiry(t *testing.T) { - privKey, err := key.GeneratePrivateKey() - if err != nil { - t.Fatalf("can't generate private key: %v", err) - } - makeToken := func(s string, exp time.Time, count int) *jose.JWT { - jwt, err := jose.NewSignedJWT(jose.Claims(map[string]interface{}{ - "test": s, - "exp": exp.UTC().Unix(), - "count": count, - }), privKey.Signer()) - if err != nil { - t.Fatalf("Could not create signed JWT %v", err) - } - return jwt - } - - t0 := time.Now() - - tests := []struct { - name string - jwt *jose.JWT - now time.Time - wantErr bool - wantExpired bool - }{ - { - name: "valid jwt", - jwt: makeToken("foo", t0.Add(time.Hour), 1), - now: t0, - }, - { - name: "invalid jwt", - jwt: &jose.JWT{}, - now: t0, - wantErr: true, - }, - { - name: "expired jwt", - jwt: makeToken("foo", t0.Add(-time.Hour), 1), - now: t0, - wantExpired: true, - }, - { - name: "jwt expires soon enough to be marked expired", - jwt: makeToken("foo", t0, 1), - now: t0, - wantExpired: true, - }, - } - - for _, tc := range tests { - func() { - valid, err := verifyJWTExpiry(tc.now, tc.jwt.Encode()) - if err != nil { - if !tc.wantErr { - t.Errorf("%s: %v", tc.name, err) - } - return - } - if tc.wantErr { - t.Errorf("%s: expected error", tc.name) - return - } - - if valid && tc.wantExpired { - t.Errorf("%s: expected token to be expired", tc.name) - } - if !valid && !tc.wantExpired { - t.Errorf("%s: expected token to be valid", tc.name) - } - }() - } -} - -func TestClientCache(t *testing.T) { - cache := newClientCache() - - if _, ok := cache.getClient("issuer1", "id1", "secret1"); ok { - t.Fatalf("got client before putting one in the cache") - } - - cli1 := new(oidcAuthProvider) - cli2 := new(oidcAuthProvider) - - gotcli := cache.setClient("issuer1", "id1", "secret1", cli1) - if cli1 != gotcli { - t.Fatalf("set first client and got a different one") - } - - gotcli = cache.setClient("issuer1", "id1", "secret1", cli2) - if cli1 != gotcli { - t.Fatalf("set a second client and didn't get the first") - } -} diff --git a/plugin/pkg/client/auth/plugins.go b/plugin/pkg/client/auth/plugins.go deleted file mode 100644 index 21813b05812..00000000000 --- a/plugin/pkg/client/auth/plugins.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package auth - -import ( - // Initialize all known client auth plugins. - _ "k8s.io/kubernetes/plugin/pkg/client/auth/gcp" - _ "k8s.io/kubernetes/plugin/pkg/client/auth/oidc" -) diff --git a/staging/copy.sh b/staging/copy.sh index 73c6913404a..fea5e965813 100755 --- a/staging/copy.sh +++ b/staging/copy.sh @@ -75,11 +75,14 @@ save "tools/clientcmd/api" save "rest" # remove the rest/fake until we're authoritative for it (need to update for registry) rm -rf ${CLIENT_REPO_TEMP}/rest/fake +save "pkg/third_party" save "pkg/util/cert" save "pkg/util/clock" save "pkg/util/flowcontrol" save "pkg/util/integer" +save "pkg/util/jsonpath" save "pkg/util/testing" +save "plugin" @@ -105,7 +108,6 @@ mkcp "/pkg/client/unversioned/auth" "/pkg/client/unversioned" mkcp "/pkg/client/unversioned/clientcmd" "/pkg/client/unversioned" mkcp "/pkg/client/unversioned/portforward" "/pkg/client/unversioned" -mkcp "/plugin/pkg/client/auth" "/plugin/pkg/client" mkcp "/pkg/util/workqueue" "pkg/util" # remove this folder because it imports prometheus rm -rf "${CLIENT_REPO_TEMP}/pkg/util/workqueue/prometheus" @@ -208,7 +210,6 @@ if [ "$(find "${CLIENT_REPO_TEMP}"/pkg/client -type f -name "*.go")" ]; then else rm -r "${CLIENT_REPO_TEMP}"/pkg/client fi -mvfolder third_party pkg/third_party mvfolder federation pkg/federation echo "running gofmt" diff --git a/staging/src/k8s.io/client-go/pkg/util/jsonpath/doc.go b/staging/src/k8s.io/client-go/pkg/util/jsonpath/doc.go index 2a6e1706170..bdbd056c2f9 100644 --- a/staging/src/k8s.io/client-go/pkg/util/jsonpath/doc.go +++ b/staging/src/k8s.io/client-go/pkg/util/jsonpath/doc.go @@ -17,4 +17,4 @@ limitations under the License. // package jsonpath is a template engine using jsonpath syntax, // which can be seen at http://goessner.net/articles/JsonPath/. // In addition, it has {range} {end} function to iterate list and slice. -package jsonpath +package jsonpath // import "k8s.io/client-go/pkg/util/jsonpath" diff --git a/pkg/util/jsonpath/jsonpath_test.go b/staging/src/k8s.io/client-go/pkg/util/jsonpath/jsonpath_test.go similarity index 100% rename from pkg/util/jsonpath/jsonpath_test.go rename to staging/src/k8s.io/client-go/pkg/util/jsonpath/jsonpath_test.go diff --git a/pkg/util/jsonpath/parser_test.go b/staging/src/k8s.io/client-go/pkg/util/jsonpath/parser_test.go similarity index 100% rename from pkg/util/jsonpath/parser_test.go rename to staging/src/k8s.io/client-go/pkg/util/jsonpath/parser_test.go diff --git a/staging/src/k8s.io/client-go/plugin/pkg/client/auth/oidc/oidc_test.go b/staging/src/k8s.io/client-go/plugin/pkg/client/auth/oidc/oidc_test.go index 7ef319b277d..16e11492818 100644 --- a/staging/src/k8s.io/client-go/plugin/pkg/client/auth/oidc/oidc_test.go +++ b/staging/src/k8s.io/client-go/plugin/pkg/client/auth/oidc/oidc_test.go @@ -30,7 +30,7 @@ import ( "github.com/coreos/go-oidc/key" "github.com/coreos/go-oidc/oauth2" - oidctesting "k8s.io/client-go/plugin/pkg/auth/authenticator/token/oidc/testing" + oidctesting "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc/testing" ) func clearCache() {