Merge pull request #2739 from Shell32-Natsu/rolebinding

Role binding for serviceaccount across namesapce.
This commit is contained in:
Jeff Regan
2020-07-22 11:45:05 -07:00
committed by GitHub
2 changed files with 164 additions and 6 deletions

View File

@@ -19,7 +19,25 @@ nameSuffix: -ns2
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa
name: my-sa1
namespace: ns1
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa2
namespace: ns2
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa3
namespace: ns3
---
apiVersion: v1
kind: NotServiceAccount
metadata:
name: my-nsa
namespace: ns1
---
apiVersion: rbac.authorization.k8s.io/v1
@@ -46,7 +64,16 @@ roleRef:
name: my-role
subjects:
- kind: ServiceAccount
name: my-sa
name: my-sa1
namespace: ns1
- kind: ServiceAccount
name: my-sa2
namespace: ns2
- kind: ServiceAccount
name: my-sa3
namespace: ns3
- kind: NotServiceAccount
name: my-nsa
namespace: ns1
`)
@@ -55,7 +82,25 @@ subjects:
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa-ns2
name: my-sa1-ns2
namespace: ns1
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa2-ns2
namespace: ns2
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa3-ns2
namespace: ns3
---
apiVersion: v1
kind: NotServiceAccount
metadata:
name: my-nsa-ns2
namespace: ns1
---
apiVersion: rbac.authorization.k8s.io/v1
@@ -82,7 +127,89 @@ roleRef:
name: my-role-ns2
subjects:
- kind: ServiceAccount
name: my-sa
name: my-sa1-ns2
namespace: ns1
- kind: ServiceAccount
name: my-sa2-ns2
namespace: ns2
- kind: ServiceAccount
name: my-sa3-ns2
namespace: ns3
- kind: NotServiceAccount
name: my-nsa
namespace: ns1
`)
}
func TestRoleBindingAcrossNamespaceWoSubjects(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- resource.yaml
nameSuffix: -ns2
`)
th.WriteF("/app/resource.yaml", `
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa1
namespace: ns1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-role
namespace: ns2
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-role-binding
namespace: ns2
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: my-role
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa1-ns2
namespace: ns1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-role-ns2
namespace: ns2
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-role-binding-ns2
namespace: ns2
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: my-role-ns2
`)
}

View File

@@ -611,19 +611,50 @@ func (m *resWrangler) SubsetThatCouldBeReferencedByResource(
inputId := inputRes.CurId()
isInputIdNamespaceable := inputId.IsNamespaceableKind()
rctxm := inputRes.PrefixesSuffixesEquals
subjectNamespaces := getNamespacesForRoleBinding(inputRes)
for _, r := range m.Resources() {
// Need to match more accuratly both at the time of selection and transformation.
// OutmostPrefixSuffixEquals is not accurate enough since it is only using
// the outer most suffix and the last prefix. Use PrefixedSuffixesEquals instead.
resId := r.CurId()
if (!isInputIdNamespaceable || !resId.IsNamespaceableKind() || resId.IsNsEquals(inputId)) &&
r.InSameKustomizeCtx(rctxm) {
if (!isInputIdNamespaceable || !resId.IsNamespaceableKind() || resId.IsNsEquals(inputId) ||
isRoleBindingNamespace(&subjectNamespaces, r.GetNamespace())) && r.InSameKustomizeCtx(rctxm) {
result.append(r)
}
}
return result
}
// isRoleBindingNamespace returns true is the namespace `ns` is in role binding
// namespaces `m`
func isRoleBindingNamespace(m *map[string]bool, ns string) bool {
return (*m)[ns]
}
// getNamespacesForRoleBinding returns referenced ServiceAccount namespaces if the inputRes is
// a RoleBinding
func getNamespacesForRoleBinding(inputRes *resource.Resource) map[string]bool {
res := make(map[string]bool)
if inputRes.GetKind() != "RoleBinding" {
return res
}
subjects, err := inputRes.GetSlice("subjects")
if err != nil || subjects == nil {
return res
}
for _, s := range subjects {
subject := s.(map[string]interface{})
if subject["namespace"] == nil || subject["kind"] == nil ||
subject["kind"].(string) != "ServiceAccount" {
continue
}
res[subject["namespace"].(string)] = true
}
return res
}
func (m *resWrangler) append(res *resource.Resource) {
m.rList = append(m.rList, res)
}