improve IAM module

Signed-off-by: hongming <talonwan@yunify.com>
This commit is contained in:
hongming
2020-05-22 09:35:05 +08:00
parent 0d12529051
commit 8f93266ec0
640 changed files with 50221 additions and 18179 deletions

View File

@@ -35,7 +35,7 @@ type PathElement struct {
// Key selects the list element which has fields matching those given.
// The containing object must be an associative list with map typed
// elements.
Key *value.Map
Key *value.FieldList
// Value selects the list element with the given value. The containing
// object must be an associative list with a primitive typed element
@@ -62,7 +62,7 @@ func (e PathElement) Less(rhs PathElement) bool {
if rhs.Key == nil {
return true
}
return e.Key.Less(rhs.Key)
return e.Key.Less(*rhs.Key)
} else if rhs.Key != nil {
return false
}
@@ -101,13 +101,11 @@ func (e PathElement) String() string {
case e.FieldName != nil:
return "." + *e.FieldName
case e.Key != nil:
strs := make([]string, len(e.Key.Items))
for i, k := range e.Key.Items {
strs := make([]string, len(*e.Key))
for i, k := range *e.Key {
strs[i] = fmt.Sprintf("%v=%v", k.Name, k.Value)
}
// The order must be canonical, since we use the string value
// in a set structure.
sort.Strings(strs)
// Keys are supposed to be sorted.
return "[" + strings.Join(strs, ",") + "]"
case e.Value != nil:
return fmt.Sprintf("[=%v]", e.Value)
@@ -123,18 +121,19 @@ func (e PathElement) String() string {
// names (type must be string) with values (type must be value.Value). If these
// conditions are not met, KeyByFields will panic--it's intended for static
// construction and shouldn't have user-produced values passed to it.
func KeyByFields(nameValues ...interface{}) []value.Field {
func KeyByFields(nameValues ...interface{}) *value.FieldList {
if len(nameValues)%2 != 0 {
panic("must have a value for every name")
}
out := []value.Field{}
out := value.FieldList{}
for i := 0; i < len(nameValues)-1; i += 2 {
out = append(out, value.Field{
Name: nameValues[i].(string),
Value: nameValues[i+1].(value.Value),
})
}
return out
out.Sort()
return &out
}
// PathElementSet is a set of path elements.
@@ -143,6 +142,12 @@ type PathElementSet struct {
members sortedPathElements
}
func MakePathElementSet(size int) PathElementSet {
return PathElementSet{
members: make(sortedPathElements, 0, size),
}
}
type sortedPathElements []PathElement
// Implement the sort interface; this would permit bulk creation, which would

View File

@@ -104,7 +104,7 @@ func GuessBestListPathElement(index int, item value.Value) PathElement {
return PathElement{Index: &index}
}
var keys []value.Field
var keys value.FieldList
for _, name := range AssociativeListCandidateFieldNames {
f, ok := item.MapValue.Get(name)
if !ok {
@@ -117,7 +117,8 @@ func GuessBestListPathElement(index int, item value.Value) PathElement {
keys = append(keys, *f)
}
if len(keys) > 0 {
return PathElement{Key: &value.Map{Items: keys}}
keys.Sort()
return PathElement{Key: &keys}
}
return PathElement{Index: &index}
}

View File

@@ -88,11 +88,11 @@ func MakePath(parts ...interface{}) (Path, error) {
fp = append(fp, PathElement{Index: &t})
case string:
fp = append(fp, PathElement{FieldName: &t})
case []value.Field:
if len(t) == 0 {
case *value.FieldList:
if len(*t) == 0 {
return nil, fmt.Errorf("associative list key type path elements must have at least one key (got zero)")
}
fp = append(fp, PathElement{Key: &value.Map{Items: t}})
fp = append(fp, PathElement{Key: t})
case value.Value:
// TODO: understand schema and verify that this is a set type
// TODO: make a copy of t

View File

@@ -0,0 +1,85 @@
/*
Copyright 2018 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 fieldpath
import (
"sort"
"sigs.k8s.io/structured-merge-diff/value"
)
// PathElementValueMap is a map from PathElement to value.Value.
//
// TODO(apelisse): We have multiple very similar implementation of this
// for PathElementSet and SetNodeMap, so we could probably share the
// code.
type PathElementValueMap struct {
members sortedPathElementValues
}
func MakePathElementValueMap(size int) PathElementValueMap {
return PathElementValueMap{
members: make(sortedPathElementValues, 0, size),
}
}
type pathElementValue struct {
PathElement PathElement
Value value.Value
}
type sortedPathElementValues []pathElementValue
// Implement the sort interface; this would permit bulk creation, which would
// be faster than doing it one at a time via Insert.
func (spev sortedPathElementValues) Len() int { return len(spev) }
func (spev sortedPathElementValues) Less(i, j int) bool {
return spev[i].PathElement.Less(spev[j].PathElement)
}
func (spev sortedPathElementValues) Swap(i, j int) { spev[i], spev[j] = spev[j], spev[i] }
// Insert adds the pathelement and associated value in the map.
func (s *PathElementValueMap) Insert(pe PathElement, v value.Value) {
loc := sort.Search(len(s.members), func(i int) bool {
return !s.members[i].PathElement.Less(pe)
})
if loc == len(s.members) {
s.members = append(s.members, pathElementValue{pe, v})
return
}
if s.members[loc].PathElement.Equals(pe) {
return
}
s.members = append(s.members, pathElementValue{})
copy(s.members[loc+1:], s.members[loc:])
s.members[loc] = pathElementValue{pe, v}
}
// Get retrieves the value associated with the given PathElement from the map.
// (nil, false) is returned if there is no such PathElement.
func (s *PathElementValueMap) Get(pe PathElement) (value.Value, bool) {
loc := sort.Search(len(s.members), func(i int) bool {
return !s.members[i].PathElement.Less(pe)
})
if loc == len(s.members) {
return value.Value{}, false
}
if s.members[loc].PathElement.Equals(pe) {
return s.members[loc].Value, true
}
return value.Value{}, false
}

View File

@@ -83,14 +83,18 @@ func DeserializePathElement(s string) (PathElement, error) {
case peKeySepBytes[0]:
iter := readPool.BorrowIterator(b)
defer readPool.ReturnIterator(iter)
v, err := value.ReadJSONIter(iter)
if err != nil {
return PathElement{}, err
}
if v.MapValue == nil {
return PathElement{}, fmt.Errorf("expected key value pairs but got %#v", v)
}
return PathElement{Key: v.MapValue}, nil
fields := value.FieldList{}
iter.ReadObjectCB(func(iter *jsoniter.Iterator, key string) bool {
v, err := value.ReadJSONIter(iter)
if err != nil {
iter.Error = err
return false
}
fields = append(fields, value.Field{Name: key, Value: v})
return true
})
fields.Sort()
return PathElement{Key: &fields}, iter.Error
case peIndexSepBytes[0]:
i, err := strconv.Atoi(s[2:])
if err != nil {
@@ -129,8 +133,15 @@ func serializePathElementToWriter(w io.Writer, pe PathElement) error {
if _, err := stream.Write(peKeySepBytes); err != nil {
return err
}
v := value.Value{MapValue: pe.Key}
v.WriteJSONStream(stream)
stream.WriteObjectStart()
for i, field := range *pe.Key {
if i > 0 {
stream.WriteMore()
}
stream.WriteObjectField(field.Name)
field.Value.WriteJSONStream(stream)
}
stream.WriteObjectEnd()
case pe.Value != nil:
if _, err := stream.Write(peValueSepBytes); err != nil {
return err