代码拉取完成,页面将自动刷新
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"io"
"strings"
"github.com/spf13/cobra"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
clientgorbacv1 "k8s.io/client-go/kubernetes/typed/rbac/v1"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
var (
roleLong = templates.LongDesc(i18n.T(`
Create a role with single rule.`))
roleExample = templates.Examples(i18n.T(`
# Create a Role named "pod-reader" that allows user to perform "get", "watch" and "list" on pods
kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
# Create a Role named "pod-reader" with ResourceName specified
kubectl create role pod-reader --verb=get,list,watch --resource=pods --resource-name=readablepod --resource-name=anotherpod
# Create a Role named "foo" with API Group specified
kubectl create role foo --verb=get,list,watch --resource=rs.extensions
# Create a Role named "foo" with SubResource specified
kubectl create role foo --verb=get,list,watch --resource=pods,pods/status`))
// Valid resource verb list for validation.
validResourceVerbs = []string{"*", "get", "delete", "list", "create", "update", "patch", "watch", "proxy", "deletecollection", "use", "bind", "impersonate"}
// Specialized verbs and GroupResources
specialVerbs = map[string][]schema.GroupResource{
"use": {
{
Group: "extensions",
Resource: "podsecuritypolicies",
},
},
"bind": {
{
Group: "rbac.authorization.k8s.io",
Resource: "roles",
},
{
Group: "rbac.authorization.k8s.io",
Resource: "clusterroles",
},
},
"impersonate": {
{
Group: "",
Resource: "users",
},
{
Group: "",
Resource: "serviceaccounts",
},
{
Group: "",
Resource: "groups",
},
{
Group: "authentication.k8s.io",
Resource: "userextras",
},
},
}
)
type ResourceOptions struct {
Group string
Resource string
SubResource string
}
type CreateRoleOptions struct {
Name string
Verbs []string
Resources []ResourceOptions
ResourceNames []string
DryRun bool
OutputFormat string
Namespace string
Client clientgorbacv1.RbacV1Interface
Mapper meta.RESTMapper
Out io.Writer
PrintObject func(obj runtime.Object) error
PrintSuccess func(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource, name string, dryRun bool, operation string)
}
// Role is a command to ease creating Roles.
func NewCmdCreateRole(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
c := &CreateRoleOptions{
Out: cmdOut,
}
cmd := &cobra.Command{
Use: "role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run]",
Short: roleLong,
Long: roleLong,
Example: roleExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(c.Complete(f, cmd, args))
cmdutil.CheckErr(c.Validate())
cmdutil.CheckErr(c.RunCreateRole())
},
}
cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddValidateFlags(cmd)
cmdutil.AddPrinterFlags(cmd)
cmdutil.AddDryRunFlag(cmd)
cmd.Flags().StringSliceVar(&c.Verbs, "verb", []string{}, "Verb that applies to the resources contained in the rule")
cmd.Flags().StringSlice("resource", []string{}, "Resource that the rule applies to")
cmd.Flags().StringArrayVar(&c.ResourceNames, "resource-name", []string{}, "Resource in the white list that the rule applies to, repeat this flag for multiple items")
return cmd
}
func (c *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args)
if err != nil {
return err
}
c.Name = name
// Remove duplicate verbs.
verbs := []string{}
for _, v := range c.Verbs {
// VerbAll respresents all kinds of verbs.
if v == "*" {
verbs = []string{"*"}
break
}
if !arrayContains(verbs, v) {
verbs = append(verbs, v)
}
}
c.Verbs = verbs
c.PrintSuccess = f.PrintSuccess
// Support resource.group pattern. If no API Group specified, use "" as core API Group.
// e.g. --resource=pods,deployments.extensions
resources := cmdutil.GetFlagStringSlice(cmd, "resource")
for _, r := range resources {
sections := strings.SplitN(r, "/", 2)
resource := &ResourceOptions{}
if len(sections) == 2 {
resource.SubResource = sections[1]
}
parts := strings.SplitN(sections[0], ".", 2)
if len(parts) == 2 {
resource.Group = parts[1]
}
resource.Resource = parts[0]
c.Resources = append(c.Resources, *resource)
}
// Remove duplicate resource names.
resourceNames := []string{}
for _, n := range c.ResourceNames {
if !arrayContains(resourceNames, n) {
resourceNames = append(resourceNames, n)
}
}
c.ResourceNames = resourceNames
// Complete other options for Run.
c.Mapper, _ = f.Object()
c.DryRun = cmdutil.GetDryRunFlag(cmd)
c.OutputFormat = cmdutil.GetFlagString(cmd, "output")
c.Namespace, _, err = f.DefaultNamespace()
if err != nil {
return err
}
c.PrintObject = func(obj runtime.Object) error {
return f.PrintObject(cmd, false, c.Mapper, obj, c.Out)
}
clientset, err := f.KubernetesClientSet()
if err != nil {
return err
}
c.Client = clientset.RbacV1()
return nil
}
func (c *CreateRoleOptions) Validate() error {
if c.Name == "" {
return fmt.Errorf("name must be specified")
}
// validate verbs.
if len(c.Verbs) == 0 {
return fmt.Errorf("at least one verb must be specified")
}
for _, v := range c.Verbs {
if !arrayContains(validResourceVerbs, v) {
return fmt.Errorf("invalid verb: '%s'", v)
}
}
// validate resources.
if len(c.Resources) == 0 {
return fmt.Errorf("at least one resource must be specified")
}
return c.validateResource()
}
func (c *CreateRoleOptions) validateResource() error {
for _, r := range c.Resources {
if len(r.Resource) == 0 {
return fmt.Errorf("resource must be specified if apiGroup/subresource specified")
}
resource := schema.GroupVersionResource{Resource: r.Resource, Group: r.Group}
groupVersionResource, err := c.Mapper.ResourceFor(schema.GroupVersionResource{Resource: r.Resource, Group: r.Group})
if err == nil {
resource = groupVersionResource
}
for _, v := range c.Verbs {
if groupResources, ok := specialVerbs[v]; ok {
match := false
for _, extra := range groupResources {
if resource.Resource == extra.Resource && resource.Group == extra.Group {
match = true
err = nil
break
}
}
if !match {
return fmt.Errorf("can not perform '%s' on '%s' in group '%s'", v, resource.Resource, resource.Group)
}
}
}
if err != nil {
return err
}
}
return nil
}
func (c *CreateRoleOptions) RunCreateRole() error {
role := &rbacv1.Role{}
role.Name = c.Name
rules, err := generateResourcePolicyRules(c.Mapper, c.Verbs, c.Resources, c.ResourceNames, []string{})
if err != nil {
return err
}
role.Rules = rules
// Create role.
if !c.DryRun {
_, err = c.Client.Roles(c.Namespace).Create(role)
if err != nil {
return err
}
}
if useShortOutput := c.OutputFormat == "name"; useShortOutput || len(c.OutputFormat) == 0 {
c.PrintSuccess(c.Mapper, useShortOutput, c.Out, "roles", c.Name, c.DryRun, "created")
return nil
}
return c.PrintObject(role)
}
func arrayContains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
func generateResourcePolicyRules(mapper meta.RESTMapper, verbs []string, resources []ResourceOptions, resourceNames []string, nonResourceURLs []string) ([]rbacv1.PolicyRule, error) {
// groupResourceMapping is a apigroup-resource map. The key of this map is api group, while the value
// is a string array of resources under this api group.
// E.g. groupResourceMapping = {"extensions": ["replicasets", "deployments"], "batch":["jobs"]}
groupResourceMapping := map[string][]string{}
// This loop does the following work:
// 1. Constructs groupResourceMapping based on input resources.
// 2. Prevents pointing to non-existent resources.
// 3. Transfers resource short name to long name. E.g. rs.extensions is transferred to replicasets.extensions
for _, r := range resources {
resource := schema.GroupVersionResource{Resource: r.Resource, Group: r.Group}
groupVersionResource, err := mapper.ResourceFor(schema.GroupVersionResource{Resource: r.Resource, Group: r.Group})
if err == nil {
resource = groupVersionResource
}
if len(r.SubResource) > 0 {
resource.Resource = resource.Resource + "/" + r.SubResource
}
if !arrayContains(groupResourceMapping[resource.Group], resource.Resource) {
groupResourceMapping[resource.Group] = append(groupResourceMapping[resource.Group], resource.Resource)
}
}
// Create separate rule for each of the api group.
rules := []rbacv1.PolicyRule{}
for _, g := range sets.StringKeySet(groupResourceMapping).List() {
rule := rbacv1.PolicyRule{}
rule.Verbs = verbs
rule.Resources = groupResourceMapping[g]
rule.APIGroups = []string{g}
rule.ResourceNames = resourceNames
rules = append(rules, rule)
}
if len(nonResourceURLs) > 0 {
rule := rbacv1.PolicyRule{}
rule.Verbs = verbs
rule.NonResourceURLs = nonResourceURLs
rules = append(rules, rule)
}
return rules, nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。