func DefaultTemplate() *templateapi.Template { ret := &templateapi.Template{} ret.Name = DefaultTemplateName ns := "${" + ProjectNameParam + "}" project := &projectapi.Project{} project.Name = ns project.Annotations = map[string]string{ projectapi.ProjectDescription: "${" + ProjectDescriptionParam + "}", projectapi.ProjectDisplayName: "${" + ProjectDisplayNameParam + "}", } ret.Objects = append(ret.Objects, project) binding := &authorizationapi.RoleBinding{} binding.Name = "admins" binding.Namespace = ns binding.Users = util.NewStringSet("${" + ProjectAdminUserParam + "}") binding.RoleRef.Name = bootstrappolicy.AdminRoleName ret.Objects = append(ret.Objects, binding) serviceAccountRoleBindings := bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings(ns) for i := range serviceAccountRoleBindings { ret.Objects = append(ret.Objects, &serviceAccountRoleBindings[i]) } for _, parameterName := range parameters { parameter := templateapi.Parameter{} parameter.Name = parameterName ret.Parameters = append(ret.Parameters, parameter) } return ret }
// ensureNamespaceServiceAccountRoleBindings initializes roles for service accounts in the namespace func (c *MasterConfig) ensureNamespaceServiceAccountRoleBindings(namespace *kapi.Namespace) { const ServiceAccountRolesInitializedAnnotation = "openshift.io/sa.initialized-roles" // Short-circuit if we're already initialized if namespace.Annotations[ServiceAccountRolesInitializedAnnotation] == "true" { return } hasErrors := false for _, binding := range bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings(namespace.Name) { addRole := &policy.RoleModificationOptions{ RoleName: binding.RoleRef.Name, RoleNamespace: binding.RoleRef.Namespace, RoleBindingAccessor: policy.NewLocalRoleBindingAccessor(namespace.Name, c.ServiceAccountRoleBindingClient()), Subjects: binding.Subjects, } if err := addRole.AddRole(); err != nil { glog.Errorf("Could not add service accounts to the %v role in the %q namespace: %v\n", binding.RoleRef.Name, namespace.Name, err) hasErrors = true } } // If we had errors, don't register initialization so we can try again if hasErrors { return } if namespace.Annotations == nil { namespace.Annotations = map[string]string{} } namespace.Annotations[ServiceAccountRolesInitializedAnnotation] = "true" if _, err := c.KubeClient().Namespaces().Update(namespace); err != nil { glog.Errorf("Error recording adding service account roles to %q namespace: %v", namespace.Name, err) } }
func TestBootstrapProjectRoleBindings(t *testing.T) { roleBindings := bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings("myproject") list := &api.List{} for i := range roleBindings { list.Items = append(list.Items, &roleBindings[i]) } testObjects(t, list, "bootstrap_service_account_project_role_bindings.yaml") }
func (o *NewProjectOptions) Run(useNodeSelector bool) error { if _, err := o.Client.Projects().Get(o.ProjectName); err != nil { if !kerrors.IsNotFound(err) { return err } } else { return fmt.Errorf("project %v already exists", o.ProjectName) } project := &projectapi.Project{} project.Name = o.ProjectName project.Annotations = make(map[string]string) project.Annotations[projectapi.ProjectDescription] = o.Description project.Annotations[projectapi.ProjectDisplayName] = o.DisplayName if useNodeSelector { project.Annotations[projectapi.ProjectNodeSelector] = o.NodeSelector } project, err := o.Client.Projects().Create(project) if err != nil { return err } fmt.Printf("Created project %v\n", o.ProjectName) errs := []error{} if len(o.AdminUser) != 0 { adduser := &policy.RoleModificationOptions{ RoleName: o.AdminRole, RoleBindingAccessor: policy.NewLocalRoleBindingAccessor(project.Name, o.Client), Users: []string{o.AdminUser}, } if err := adduser.AddRole(); err != nil { fmt.Printf("%v could not be added to the %v role: %v\n", o.AdminUser, o.AdminRole, err) errs = append(errs, err) } } for _, binding := range bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings(o.ProjectName) { addRole := &policy.RoleModificationOptions{ RoleName: binding.RoleRef.Name, RoleNamespace: binding.RoleRef.Namespace, RoleBindingAccessor: policy.NewLocalRoleBindingAccessor(o.ProjectName, o.Client), Users: binding.Users.List(), Groups: binding.Groups.List(), } if err := addRole.AddRole(); err != nil { fmt.Printf("Could not add service accounts to the %v role: %v\n", binding.RoleRef.Name, err) errs = append(errs, err) } } return errorsutil.NewAggregate(errs) }
// ensureDefaultNamespaceServiceAccountRoles initializes roles for service accounts in the default namespace func (c *MasterConfig) ensureDefaultNamespaceServiceAccountRoles() { const ServiceAccountRolesInitializedAnnotation = "openshift.io/sa.initialized-roles" // Wait for the default namespace var defaultNamespace *kapi.Namespace for i := 0; i < 30; i++ { ns, err := c.KubeClient().Namespaces().Get(kapi.NamespaceDefault) if err == nil { defaultNamespace = ns break } if kapierror.IsNotFound(err) { time.Sleep(time.Second) continue } glog.Errorf("Error adding service account roles to default namespace: %v", err) return } if defaultNamespace == nil { glog.Errorf("Default namespace not found, could not initialize default service account roles") return } // Short-circuit if we're already initialized if defaultNamespace.Annotations[ServiceAccountRolesInitializedAnnotation] == "true" { return } hasErrors := false for _, binding := range bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings(kapi.NamespaceDefault) { addRole := &policy.RoleModificationOptions{ RoleName: binding.RoleRef.Name, RoleNamespace: binding.RoleRef.Namespace, RoleBindingAccessor: policy.NewLocalRoleBindingAccessor(kapi.NamespaceDefault, c.ServiceAccountRoleBindingClient()), Users: binding.Users.List(), Groups: binding.Groups.List(), } if err := addRole.AddRole(); err != nil { glog.Errorf("Could not add service accounts to the %v role in the %v namespace: %v\n", binding.RoleRef.Name, kapi.NamespaceDefault, err) hasErrors = true } } // If we had errors, don't register initialization so we can try again if !hasErrors { if defaultNamespace.Annotations == nil { defaultNamespace.Annotations = map[string]string{} } defaultNamespace.Annotations[ServiceAccountRolesInitializedAnnotation] = "true" if _, err := c.KubeClient().Namespaces().Update(defaultNamespace); err != nil { glog.Errorf("Error recording adding service account roles to default namespace: %v", err) } } }
func DefaultTemplate() *templateapi.Template { ret := &templateapi.Template{} ret.Name = DefaultTemplateName ns := "${" + ProjectNameParam + "}" templateContents := []runtime.Object{} project := &projectapi.Project{} project.Name = ns project.Annotations = map[string]string{ projectapi.ProjectDescription: "${" + ProjectDescriptionParam + "}", projectapi.ProjectDisplayName: "${" + ProjectDisplayNameParam + "}", projectapi.ProjectRequester: "${" + ProjectRequesterParam + "}", } templateContents = append(templateContents, project) serviceAccountRoleBindings := bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings(ns) for i := range serviceAccountRoleBindings { templateContents = append(templateContents, &serviceAccountRoleBindings[i]) } binding := &authorizationapi.RoleBinding{} binding.Name = bootstrappolicy.AdminRoleName binding.Namespace = ns binding.Subjects = []kapi.ObjectReference{{Kind: authorizationapi.UserKind, Name: "${" + ProjectAdminUserParam + "}"}} binding.RoleRef.Name = bootstrappolicy.AdminRoleName templateContents = append(templateContents, binding) if err := templateapi.AddObjectsToTemplate(ret, templateContents, latest.Version); err != nil { // this should never happen because we're tightly controlling what goes in. panic(err) } for _, parameterName := range parameters { parameter := templateapi.Parameter{} parameter.Name = parameterName ret.Parameters = append(ret.Parameters, parameter) } return ret }