Compare commits

...

5 Commits

Author SHA1 Message Date
Alexander Matyushentsev
48cced9d92 Update manifests to v1.4.2 2020-01-23 16:48:25 -08:00
Alexander Matyushentsev
bc77ea70c4 fix: correctly replace cache in namespace isolation mode (#3023) 2020-01-23 16:20:40 -08:00
Alexander Matyushentsev
f8721a7360 Update manifests to v1.4.1 2020-01-22 14:44:13 -08:00
Alexander Matyushentsev
8ada07e0f5 fix: run dep ensure (#3018) 2020-01-22 14:43:38 -08:00
Alexander Matyushentsev
de8ae9c617 fix: impossible to config RBAC if group name includes ',' (#3013)
* fix:  impossible to config RBAC if group name includes ','

* apply reviewer notes
2020-01-22 11:47:31 -08:00
12 changed files with 87 additions and 42 deletions

1
Gopkg.lock generated
View File

@@ -1933,7 +1933,6 @@
"github.com/argoproj/pkg/time",
"github.com/casbin/casbin",
"github.com/casbin/casbin/model",
"github.com/casbin/casbin/persist",
"github.com/coreos/go-oidc",
"github.com/dgrijalva/jwt-go",
"github.com/dustin/go-humanize",

View File

@@ -1 +1 @@
1.4.0
1.4.2

View File

@@ -58,14 +58,15 @@ type clusterInfo struct {
cacheSettingsSrc func() *cacheSettings
}
func (c *clusterInfo) replaceResourceCache(gk schema.GroupKind, resourceVersion string, objs []unstructured.Unstructured) {
func (c *clusterInfo) replaceResourceCache(gk schema.GroupKind, resourceVersion string, objs []unstructured.Unstructured, ns string) {
info, ok := c.apisMeta[gk]
if ok {
objByKind := make(map[kube.ResourceKey]*unstructured.Unstructured)
objByKey := make(map[kube.ResourceKey]*unstructured.Unstructured)
for i := range objs {
objByKind[kube.GetResourceKey(&objs[i])] = &objs[i]
objByKey[kube.GetResourceKey(&objs[i])] = &objs[i]
}
// update existing nodes
for i := range objs {
obj := &objs[i]
key := kube.GetResourceKey(&objs[i])
@@ -73,12 +74,13 @@ func (c *clusterInfo) replaceResourceCache(gk schema.GroupKind, resourceVersion
c.onNodeUpdated(exists, existingNode, obj, key)
}
// remove existing nodes that a no longer exist
for key, existingNode := range c.nodes {
if key.Kind != gk.Kind || key.Group != gk.Group {
if key.Kind != gk.Kind || key.Group != gk.Group || ns != "" && key.Namespace != ns {
continue
}
if _, ok := objByKind[key]; !ok {
if _, ok := objByKey[key]; !ok {
c.onNodeRemoved(key, existingNode)
}
}
@@ -186,13 +188,13 @@ func (c *clusterInfo) synced() bool {
return time.Now().Before(c.syncTime.Add(clusterSyncTimeout))
}
func (c *clusterInfo) stopWatching(gk schema.GroupKind) {
func (c *clusterInfo) stopWatching(gk schema.GroupKind, ns string) {
c.lock.Lock()
defer c.lock.Unlock()
if info, ok := c.apisMeta[gk]; ok {
info.watchCancel()
delete(c.apisMeta, gk)
c.replaceResourceCache(gk, "", []unstructured.Unstructured{})
c.replaceResourceCache(gk, "", []unstructured.Unstructured{}, ns)
log.Warnf("Stop watching %s not found on %s.", gk, c.cluster.Server)
}
}
@@ -217,8 +219,8 @@ func (c *clusterInfo) startMissingWatches() error {
info := &apiMeta{namespaced: api.Meta.Namespaced, watchCancel: cancel}
c.apisMeta[api.GroupKind] = info
err = c.processApi(client, api, func(resClient dynamic.ResourceInterface) error {
go c.watchEvents(ctx, api, info, resClient)
err = c.processApi(client, api, func(resClient dynamic.ResourceInterface, ns string) error {
go c.watchEvents(ctx, api, info, resClient, ns)
return nil
})
if err != nil {
@@ -235,7 +237,7 @@ func runSynced(lock *sync.Mutex, action func() error) error {
return action()
}
func (c *clusterInfo) watchEvents(ctx context.Context, api kube.APIResourceInfo, info *apiMeta, resClient dynamic.ResourceInterface) {
func (c *clusterInfo) watchEvents(ctx context.Context, api kube.APIResourceInfo, info *apiMeta, resClient dynamic.ResourceInterface, ns string) {
util.RetryUntilSucceed(func() (err error) {
defer func() {
if r := recover(); r != nil {
@@ -249,7 +251,7 @@ func (c *clusterInfo) watchEvents(ctx context.Context, api kube.APIResourceInfo,
if err != nil {
return err
}
c.replaceResourceCache(api.GroupKind, list.GetResourceVersion(), list.Items)
c.replaceResourceCache(api.GroupKind, list.GetResourceVersion(), list.Items, ns)
}
return nil
})
@@ -260,7 +262,7 @@ func (c *clusterInfo) watchEvents(ctx context.Context, api kube.APIResourceInfo,
w, err := resClient.Watch(metav1.ListOptions{ResourceVersion: info.resourceVersion})
if errors.IsNotFound(err) {
c.stopWatching(api.GroupKind)
c.stopWatching(api.GroupKind, ns)
return nil
}
@@ -292,7 +294,7 @@ func (c *clusterInfo) watchEvents(ctx context.Context, api kube.APIResourceInfo,
if groupOk && groupErr == nil && kindOk && kindErr == nil {
gk := schema.GroupKind{Group: group, Kind: kind}
c.stopWatching(gk)
c.stopWatching(gk, ns)
}
} else {
err = runSynced(c.lock, func() error {
@@ -313,10 +315,10 @@ func (c *clusterInfo) watchEvents(ctx context.Context, api kube.APIResourceInfo,
}, fmt.Sprintf("watch %s on %s", api.GroupKind, c.cluster.Server), ctx, watchResourcesRetryTimeout)
}
func (c *clusterInfo) processApi(client dynamic.Interface, api kube.APIResourceInfo, callback func(resClient dynamic.ResourceInterface) error) error {
func (c *clusterInfo) processApi(client dynamic.Interface, api kube.APIResourceInfo, callback func(resClient dynamic.ResourceInterface, ns string) error) error {
resClient := client.Resource(api.GroupVersionResource)
if len(c.cluster.Namespaces) == 0 {
return callback(resClient)
return callback(resClient, "")
}
if !api.Meta.Namespaced {
@@ -324,7 +326,7 @@ func (c *clusterInfo) processApi(client dynamic.Interface, api kube.APIResourceI
}
for _, ns := range c.cluster.Namespaces {
err := callback(resClient.Namespace(ns))
err := callback(resClient.Namespace(ns), ns)
if err != nil {
return err
}
@@ -357,7 +359,7 @@ func (c *clusterInfo) sync() (err error) {
}
lock := sync.Mutex{}
err = util.RunAllAsync(len(apis), func(i int) error {
return c.processApi(client, apis[i], func(resClient dynamic.ResourceInterface) error {
return c.processApi(client, apis[i], func(resClient dynamic.ResourceInterface, _ string) error {
list, err := resClient.List(metav1.ListOptions{})
if err != nil {
return err

View File

@@ -504,7 +504,7 @@ func TestWatchCacheUpdated(t *testing.T) {
podGroupKind := testPod.GroupVersionKind().GroupKind()
cluster.replaceResourceCache(podGroupKind, "updated-list-version", []unstructured.Unstructured{*updated, *added})
cluster.replaceResourceCache(podGroupKind, "updated-list-version", []unstructured.Unstructured{*updated, *added}, "")
_, ok := cluster.nodes[kube.GetResourceKey(removed)]
assert.False(t, ok)
@@ -517,6 +517,28 @@ func TestWatchCacheUpdated(t *testing.T) {
assert.True(t, ok)
}
func TestNamespaceModeReplace(t *testing.T) {
ns1Pod := testPod.DeepCopy()
ns1Pod.SetNamespace("ns1")
ns1Pod.SetName("pod1")
ns2Pod := testPod.DeepCopy()
ns2Pod.SetNamespace("ns2")
podGroupKind := testPod.GroupVersionKind().GroupKind()
cluster := newCluster(ns1Pod, ns2Pod)
err := cluster.ensureSynced()
assert.Nil(t, err)
cluster.replaceResourceCache(podGroupKind, "", nil, "ns1")
_, ok := cluster.nodes[kube.GetResourceKey(ns1Pod)]
assert.False(t, ok)
_, ok = cluster.nodes[kube.GetResourceKey(ns2Pod)]
assert.True(t, ok)
}
func TestGetDuplicatedChildren(t *testing.T) {
extensionsRS := testRS.DeepCopy()
extensionsRS.SetGroupVersionKind(schema.GroupVersionKind{Group: "extensions", Kind: kube.ReplicaSetKind, Version: "v1beta1"})

View File

@@ -12,4 +12,4 @@ bases:
images:
- name: argoproj/argocd
newName: argoproj/argocd
newTag: v1.4.0
newTag: v1.4.2

View File

@@ -18,4 +18,4 @@ bases:
images:
- name: argoproj/argocd
newName: argoproj/argocd
newTag: v1.4.0
newTag: v1.4.2

View File

@@ -2428,7 +2428,7 @@ spec:
- argocd-redis-ha-announce-2:26379
- --sentinelmaster
- argocd
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2482,7 +2482,7 @@ spec:
- cp
- /usr/local/bin/argocd-util
- /shared
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -2538,7 +2538,7 @@ spec:
- argocd-redis-ha-announce-2:26379
- --sentinelmaster
- argocd
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
initialDelaySeconds: 5
@@ -2612,7 +2612,7 @@ spec:
- argocd-redis-ha-announce-2:26379
- --sentinelmaster
- argocd
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -2343,7 +2343,7 @@ spec:
- argocd-redis-ha-announce-2:26379
- --sentinelmaster
- argocd
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2397,7 +2397,7 @@ spec:
- cp
- /usr/local/bin/argocd-util
- /shared
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -2453,7 +2453,7 @@ spec:
- argocd-redis-ha-announce-2:26379
- --sentinelmaster
- argocd
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
initialDelaySeconds: 5
@@ -2527,7 +2527,7 @@ spec:
- argocd-redis-ha-announce-2:26379
- --sentinelmaster
- argocd
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -2192,7 +2192,7 @@ spec:
- "20"
- --operation-processors
- "10"
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2246,7 +2246,7 @@ spec:
- cp
- /usr/local/bin/argocd-util
- /shared
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -2310,7 +2310,7 @@ spec:
- argocd-repo-server
- --redis
- argocd-redis:6379
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
initialDelaySeconds: 5
@@ -2361,7 +2361,7 @@ spec:
- argocd-server
- --staticassets
- /shared/app
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -2107,7 +2107,7 @@ spec:
- "20"
- --operation-processors
- "10"
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2161,7 +2161,7 @@ spec:
- cp
- /usr/local/bin/argocd-util
- /shared
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -2225,7 +2225,7 @@ spec:
- argocd-repo-server
- --redis
- argocd-redis:6379
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
initialDelaySeconds: 5
@@ -2276,7 +2276,7 @@ spec:
- argocd-server
- --staticassets
- /shared/app
image: argoproj/argocd:v1.4.0
image: argoproj/argocd:v1.4.2
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -2,6 +2,7 @@ package rbac
import (
"context"
"encoding/csv"
"errors"
"fmt"
"strings"
@@ -11,7 +12,6 @@ import (
"github.com/casbin/casbin"
"github.com/casbin/casbin/model"
"github.com/casbin/casbin/persist"
jwt "github.com/dgrijalva/jwt-go"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
@@ -270,15 +270,34 @@ func newAdapter(builtinPolicy, userDefinedPolicy, runtimePolicy string) *argocdA
func (a *argocdAdapter) LoadPolicy(model model.Model) error {
for _, policyStr := range []string{a.builtinPolicy, a.userDefinedPolicy, a.runtimePolicy} {
for _, line := range strings.Split(policyStr, "\n") {
if line == "" {
continue
if err := loadPolicyLine(strings.TrimSpace(line), model); err != nil {
return err
}
persist.LoadPolicyLine(line, model)
}
}
return nil
}
// The modified version of LoadPolicyLine function defined in "persist" package of github.com/casbin/casbin.
// Uses CVS parser to correctly handle quotes in policy line.
func loadPolicyLine(line string, model model.Model) error {
if line == "" || strings.HasPrefix(line, "#") {
return nil
}
reader := csv.NewReader(strings.NewReader(line))
reader.TrimLeadingSpace = true
tokens, err := reader.Read()
if err != nil {
return err
}
key := tokens[0]
sec := key[:1]
model[sec][key].Policy = append(model[sec][key].Policy, tokens[1:])
return nil
}
func (a *argocdAdapter) SavePolicy(model model.Model) error {
return errors.New("not implemented")
}

View File

@@ -371,6 +371,9 @@ func TestValidatePolicy(t *testing.T) {
goodPolicies := []string{
"p, role:admin, projects, delete, *, allow",
"",
"#",
`p, "role,admin", projects, delete, *, allow`,
` p, role:admin, projects, delete, *, allow `,
}
for _, good := range goodPolicies {
assert.Nil(t, ValidatePolicy(good))