Change:
/kind bug What happened: I deployed a fresh custom HA kubernetes v1.10.2 cluster with 3 nodes (all controller and worker currently, more workers planned). I then created a namespace called "stummi" and a rolebinding with "user=stummi clusterrole=admin" in this namespace. User stummi (successfully authenticated by TLS client certificate) was not able to list pods or anything else in his namespace: While trying to figure things out, I downgraded to v1.8.11 (a version without cluster role aggregation, that worked) and also tried v1.11 alpha2 (which did not work). I never purged my etcd and I sadly do not have logs from before the different versions. Shortly after posting on slack and before writing this ticket, I dumped the cluster roles in question: Note the rules. What you expected to happen: I expected user stummi to be able to do most things in his namespace. How to reproduce it (as minimally and precisely as possible): Anything else we need to know?: I posted this problem on slack and helped me and wanted this issue opened. /sig auth The cluster is deployed with ansible and I can give the playbooks when required. Environment: Kubernetes version (use ):Cloud provider or hardware configuration: 3 virtual machines (2 cores, 8GB memory) OS (e.g. from /etc/os-release): Debian Stretch Kernel (e.g. ): Install tools: custom ansible playbooks Others: Please let me know if you need more information. I'm happy to provide everything you need to fix this :)
/assign

Discussion:
_, result.MissingAggregationRuleSelectors = aggregationRuleCovers(existing.GetAggregationRule(), expected.GetAggregationRule()) switch { <ins> case expected.GetAggregationRule() == nil && existing.GetAggregationRule() != nil: // we didn't expect this to be an aggregated role at all, remove the existing aggregation result.Role.SetAggregationRule(nil) result.Operation = ReconcileUpdate </ins> case !removeExtraPermissions && len(result.MissingAggregationRuleSelectors) > 0: // add missing rules in the union case aggregationRule := result.Role.GetAggregationRule()

expectedReconciledRole:       aggregatedRole(aggregationrule([]map[string]string{{"alpha": "bravo"}, {"foo": "bar"}})), expectedReconciliationNeeded: true, }, <ins> "unexpected aggregation": { // desired role is not aggregated expectedRole: role(rules("pods", "nodes", "secrets"), nil, nil), // existing role is aggregated actualRole:             aggregatedRole(aggregationrule([]map[string]string{{"alpha": "bravo"}})), removeExtraPermissions: false, // reconciled role should have desired permissions and not be aggregated expectedReconciledRole:       role(rules("pods", "nodes", "secrets"), nil, nil), expectedReconciliationNeeded: true, }, "unexpected aggregation with differing permissions": { // desired role is not aggregated expectedRole: role(rules("pods", "nodes", "secrets"), nil, nil), // existing role is aggregated and has other permissions actualRole: func() *rbac.ClusterRole { r := aggregatedRole(aggregationrule([]map[string]string{{"alpha": "bravo"}})) r.Rules = rules("deployments") return r }(), removeExtraPermissions: false, // reconciled role should have aggregation removed, preserve differing permissions, and include desired permissions expectedReconciledRole:       role(rules("deployments", "pods", "nodes", "secrets"), nil, nil), expectedReconciliationNeeded: true, }, </ins> } for k, tc := range tests {

if err != nil { return err } <ins> if existingRole.AggregationRule != nil { // the old role already moved to an aggregated role, so there are no custom rules to migrate at this point return nil } </ins> glog.V(1).Infof("migrating %v to %v", existingRole.Name, newName) existingRole.Name = newName existingRole.ResourceVersion = "" // clear this so the object can be created.