diff --git a/pkg/cmd/server/bootstrappolicy/constants.go b/pkg/cmd/server/bootstrappolicy/constants.go index 4401ee901fe3..4fc6f238c167 100644 --- a/pkg/cmd/server/bootstrappolicy/constants.go +++ b/pkg/cmd/server/bootstrappolicy/constants.go @@ -4,6 +4,7 @@ package bootstrappolicy const ( DefaultOpenShiftSharedResourcesNamespace = "openshift" DefaultOpenShiftInfraNamespace = "openshift-infra" + DefaultOpenShiftNodeNamespace = "openshift-node" ) // users @@ -98,7 +99,8 @@ const ( OpenshiftSharedResourceViewRoleName = "shared-resource-viewer" - NodeBootstrapRoleName = "system:node-bootstrapper" + NodeBootstrapRoleName = "system:node-bootstrapper" + NodeConfigReaderRoleName = "system:node-config-reader" ) // RoleBindings @@ -120,6 +122,7 @@ const ( NodeProxierRoleBindingName = NodeProxierRoleName + "s" NodeAdminRoleBindingName = NodeAdminRoleName + "s" NodeReaderRoleBindingName = NodeReaderRoleName + "s" + NodeConfigReaderRoleBindingName = NodeConfigReaderRoleName + "s" SDNReaderRoleBindingName = SDNReaderRoleName + "s" SDNManagerRoleBindingName = SDNManagerRoleName + "s" WebHooksRoleBindingName = WebHooksRoleName + "s" diff --git a/pkg/cmd/server/bootstrappolicy/policy.go b/pkg/cmd/server/bootstrappolicy/policy.go index b02bf86bf3bc..85752fc8b463 100644 --- a/pkg/cmd/server/bootstrappolicy/policy.go +++ b/pkg/cmd/server/bootstrappolicy/policy.go @@ -664,6 +664,15 @@ func GetOpenshiftBootstrapClusterRoles() []rbac.ClusterRole { // TODO: expose other things like /healthz on the node once we figure out non-resource URL policy across systems }, }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: NodeConfigReaderRoleName, + }, + Rules: []rbac.PolicyRule{ + // Allow the reader to read config maps in a given namespace with a given name. + rbac.NewRule("get").Groups(kapiGroup).Resources("configmaps").RuleOrDie(), + }, + }, { ObjectMeta: metav1.ObjectMeta{ Name: NodeRoleName, @@ -1099,3 +1108,11 @@ func GetBootstrapNamespaceRoleBindings() map[string][]rbac.RoleBinding { } return ret } + +func GetBootstrapNodeConfigProvisioningRoleBindings(namespace string) []rbac.RoleBinding { + return []rbac.RoleBinding{ + newOriginRoleBindingForClusterRole(NodeConfigReaderRoleBindingName, NodeConfigReaderRoleName, namespace). + Groups(NodesGroup). + BindingOrDie(), + } +} diff --git a/pkg/cmd/server/bootstrappolicy/web_console_role_test.go b/pkg/cmd/server/bootstrappolicy/web_console_role_test.go index 1c95fb4f4f83..7e66b84019e5 100644 --- a/pkg/cmd/server/bootstrappolicy/web_console_role_test.go +++ b/pkg/cmd/server/bootstrappolicy/web_console_role_test.go @@ -42,6 +42,7 @@ var rolesToHide = sets.NewString( "system:node", "system:node-admin", "system:node-bootstrapper", + "system:node-config-reader", "system:node-problem-detector", "system:node-proxier", "system:node-reader", diff --git a/pkg/cmd/server/origin/ensure.go b/pkg/cmd/server/origin/ensure.go index d95e47d396a4..585faa772bc8 100644 --- a/pkg/cmd/server/origin/ensure.go +++ b/pkg/cmd/server/origin/ensure.go @@ -2,10 +2,38 @@ package origin import ( genericapiserver "k8s.io/apiserver/pkg/server" + "k8s.io/kubernetes/pkg/apis/rbac" + rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest" + + "github.com/openshift/origin/pkg/cmd/server/bootstrappolicy" ) // ensureOpenShiftSharedResourcesNamespace is called as part of global policy initialization to ensure shared namespace exists func (c *MasterConfig) ensureOpenShiftSharedResourcesNamespace(context genericapiserver.PostStartHookContext) error { - ensureNamespaceServiceAccountRoleBindings(context, c.Options.PolicyConfig.OpenShiftSharedResourcesNamespace) + ns := c.Options.PolicyConfig.OpenShiftSharedResourcesNamespace + ensureNamespaceServiceAccountRoleBindings( + context, + ns, + &rbacrest.PolicyData{ + RoleBindings: map[string][]rbac.RoleBinding{ + ns: bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings(ns), + }, + }, + ) + return nil +} + +// ensureOpenShiftNodeNamespace is called as part of global policy initialization to ensure a node namespace exists +func (c *MasterConfig) ensureOpenShiftNodeNamespace(context genericapiserver.PostStartHookContext) error { + ns := bootstrappolicy.DefaultOpenShiftNodeNamespace + ensureNamespaceServiceAccountRoleBindings( + context, + ns, + &rbacrest.PolicyData{ + RoleBindings: map[string][]rbac.RoleBinding{ + ns: bootstrappolicy.GetBootstrapNodeConfigProvisioningRoleBindings(ns), + }, + }, + ) return nil } diff --git a/pkg/cmd/server/origin/master.go b/pkg/cmd/server/origin/master.go index e834e00048f1..9a6f6ebefe83 100644 --- a/pkg/cmd/server/origin/master.go +++ b/pkg/cmd/server/origin/master.go @@ -251,6 +251,7 @@ func (c *MasterConfig) Run(kubeAPIServerConfig *kubeapiserver.Config, controller } // add post-start hooks + aggregatedAPIServer.GenericAPIServer.AddPostStartHookOrDie("node.openshift.io-sharednamespace", c.ensureOpenShiftNodeNamespace) aggregatedAPIServer.GenericAPIServer.AddPostStartHookOrDie("template.openshift.io-sharednamespace", c.ensureOpenShiftSharedResourcesNamespace) aggregatedAPIServer.GenericAPIServer.AddPostStartHookOrDie("authorization.openshift.io-bootstrapclusterroles", bootstrappolicy.Policy().EnsureRBACPolicy()) aggregatedAPIServer.GenericAPIServer.AddPostStartHookOrDie("admission.openshift.io-RefreshRESTMapper", func(context apiserver.PostStartHookContext) error { diff --git a/pkg/cmd/server/origin/openshift_apiserver.go b/pkg/cmd/server/origin/openshift_apiserver.go index fb498508ce51..5d6a9cad7b3f 100644 --- a/pkg/cmd/server/origin/openshift_apiserver.go +++ b/pkg/cmd/server/origin/openshift_apiserver.go @@ -672,7 +672,15 @@ func (c *OpenshiftAPIConfig) bootstrapSCC(context genericapiserver.PostStartHook func (c *OpenshiftAPIConfig) ensureOpenShiftInfraNamespace(context genericapiserver.PostStartHookContext) error { ns := bootstrappolicy.DefaultOpenShiftInfraNamespace - ensureNamespaceServiceAccountRoleBindings(context, ns) + ensureNamespaceServiceAccountRoleBindings( + context, + ns, + &rbacrest.PolicyData{ + RoleBindings: map[string][]rbac.RoleBinding{ + ns: bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings(ns), + }, + }, + ) var coreClient coreclient.CoreInterface err := wait.Poll(1*time.Second, 30*time.Second, func() (bool, error) { @@ -692,7 +700,8 @@ func (c *OpenshiftAPIConfig) ensureOpenShiftInfraNamespace(context genericapiser // Ensure we have the bootstrap SA for Nodes _, err = coreClient.ServiceAccounts(ns).Create(&kapi.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: bootstrappolicy.InfraNodeBootstrapServiceAccountName}}) if err != nil && !kapierror.IsAlreadyExists(err) { - glog.Errorf("Error creating service account %s/%s: %v", ns, bootstrappolicy.InfraNodeBootstrapServiceAccountName, err) + utilruntime.HandleError(fmt.Errorf("Error creating service account %s/%s: %v", ns, bootstrappolicy.InfraNodeBootstrapServiceAccountName, err)) + return err } return nil @@ -700,12 +709,20 @@ func (c *OpenshiftAPIConfig) ensureOpenShiftInfraNamespace(context genericapiser // ensureDefaultNamespaceServiceAccountRoles initializes roles for service accounts in the default namespace func (c *OpenshiftAPIConfig) ensureDefaultNamespaceServiceAccountRoles(context genericapiserver.PostStartHookContext) error { - ensureNamespaceServiceAccountRoleBindings(context, metav1.NamespaceDefault) + ensureNamespaceServiceAccountRoleBindings( + context, + metav1.NamespaceDefault, + &rbacrest.PolicyData{ + RoleBindings: map[string][]rbac.RoleBinding{ + metav1.NamespaceDefault: bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings(metav1.NamespaceDefault), + }, + }, + ) return nil } // ensureNamespaceServiceAccountRoleBindings initializes roles for service accounts in the namespace -func ensureNamespaceServiceAccountRoleBindings(context genericapiserver.PostStartHookContext, namespaceName string) { +func ensureNamespaceServiceAccountRoleBindings(context genericapiserver.PostStartHookContext, namespaceName string, policyData *rbacrest.PolicyData) { const ServiceAccountRolesInitializedAnnotation = "openshift.io/sa.initialized-roles" var coreClient coreclient.CoreInterface @@ -742,11 +759,6 @@ func ensureNamespaceServiceAccountRoleBindings(context genericapiserver.PostStar return } - policyData := &rbacrest.PolicyData{ - RoleBindings: map[string][]rbac.RoleBinding{ - namespace.Name: bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings(namespace.Name), - }, - } if err := policyData.EnsureRBACPolicy()(context); err != nil { utilruntime.HandleError(err) return diff --git a/test/integration/front_proxy_test.go b/test/integration/front_proxy_test.go index 3f50cf1133f7..57a5ab4c114c 100644 --- a/test/integration/front_proxy_test.go +++ b/test/integration/front_proxy_test.go @@ -158,6 +158,7 @@ func TestFrontProxy(t *testing.T) { "kube-system", "openshift", "openshift-infra", + "openshift-node", ), }, } { diff --git a/test/integration/master_routes_test.go b/test/integration/master_routes_test.go index 5675027c138c..5e2212f2a7c5 100644 --- a/test/integration/master_routes_test.go +++ b/test/integration/master_routes_test.go @@ -100,6 +100,7 @@ var expectedIndex = []string{ // "/healthz/poststarthook/extensions/third-party-resources", // Do not enable this controller, we do not support it "/healthz/poststarthook/generic-apiserver-start-informers", "/healthz/poststarthook/kube-apiserver-autoregistration", + "/healthz/poststarthook/node.openshift.io-sharednamespace", "/healthz/poststarthook/oauth.openshift.io-EnsureBootstrapOAuthClients", "/healthz/poststarthook/project.openshift.io-projectauthorizationcache", "/healthz/poststarthook/project.openshift.io-projectcache", diff --git a/test/testdata/bootstrappolicy/bootstrap_cluster_roles.yaml b/test/testdata/bootstrappolicy/bootstrap_cluster_roles.yaml index 549908684d6e..59c356f96567 100644 --- a/test/testdata/bootstrappolicy/bootstrap_cluster_roles.yaml +++ b/test/testdata/bootstrappolicy/bootstrap_cluster_roles.yaml @@ -2177,6 +2177,21 @@ items: verbs: - create - get +- apiVersion: rbac.authorization.k8s.io/v1beta1 + kind: ClusterRole + metadata: + annotations: + authorization.openshift.io/system-only: "true" + rbac.authorization.kubernetes.io/autoupdate: "true" + creationTimestamp: null + name: system:node-config-reader + rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get - apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: diff --git a/test/testdata/bootstrappolicy/bootstrap_policy_file.yaml b/test/testdata/bootstrappolicy/bootstrap_policy_file.yaml index eb040fc21cf7..4f15ff580272 100644 --- a/test/testdata/bootstrappolicy/bootstrap_policy_file.yaml +++ b/test/testdata/bootstrappolicy/bootstrap_policy_file.yaml @@ -2379,6 +2379,22 @@ items: verbs: - create - get +- apiVersion: v1 + kind: ClusterRole + metadata: + annotations: + authorization.openshift.io/system-only: "true" + openshift.io/reconcile-protect: "false" + creationTimestamp: null + name: system:node-config-reader + rules: + - apiGroups: + - "" + attributeRestrictions: null + resources: + - configmaps + verbs: + - get - apiVersion: v1 kind: ClusterRole metadata: