ad916a82 |
package admin
import (
"errors"
"fmt" |
ac38ade6 |
"io" |
ad916a82 |
|
6a7364d3 |
etcdclient "github.com/coreos/go-etcd/etcd" |
ad916a82 |
"github.com/spf13/cobra"
|
83c702b4 |
kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/kubectl"
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/runtime" |
ad916a82 |
"github.com/openshift/origin/pkg/api/latest"
authorizationapi "github.com/openshift/origin/pkg/authorization/api" |
557f1436 |
policyregistry "github.com/openshift/origin/pkg/authorization/registry/policy"
policyetcd "github.com/openshift/origin/pkg/authorization/registry/policy/etcd"
policybindingregistry "github.com/openshift/origin/pkg/authorization/registry/policybinding"
policybindingetcd "github.com/openshift/origin/pkg/authorization/registry/policybinding/etcd" |
ad916a82 |
roleregistry "github.com/openshift/origin/pkg/authorization/registry/role" |
89b6ba81 |
rolestorage "github.com/openshift/origin/pkg/authorization/registry/role/policybased"
rolebindingstorage "github.com/openshift/origin/pkg/authorization/registry/rolebinding/policybased" |
83c702b4 |
"k8s.io/kubernetes/pkg/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" |
ba6a7bc8 |
clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
clusterpolicyetcd "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy/etcd"
clusterpolicybindingregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
clusterpolicybindingetcd "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding/etcd"
clusterroleregistry "github.com/openshift/origin/pkg/authorization/registry/clusterrole"
clusterrolestorage "github.com/openshift/origin/pkg/authorization/registry/clusterrole/proxy"
clusterrolebindingstorage "github.com/openshift/origin/pkg/authorization/registry/clusterrolebinding/proxy"
|
ac38ade6 |
"github.com/openshift/origin/pkg/cmd/cli/describe" |
ad916a82 |
configapilatest "github.com/openshift/origin/pkg/cmd/server/api/latest"
"github.com/openshift/origin/pkg/cmd/server/etcd"
cmdclientcmd "github.com/openshift/origin/pkg/cmd/util/clientcmd"
templateapi "github.com/openshift/origin/pkg/template/api"
)
|
28e73694 |
const OverwriteBootstrapPolicyCommandName = "overwrite-policy"
|
ad916a82 |
type OverwriteBootstrapPolicyOptions struct {
File string
MasterConfigFile string |
28e73694 |
Force bool
Out io.Writer
CreateBootstrapPolicyCommand string |
ad916a82 |
}
|
28e73694 |
func NewCommandOverwriteBootstrapPolicy(commandName string, fullName string, createBootstrapPolicyCommand string, out io.Writer) *cobra.Command { |
ee70e7d9 |
options := &OverwriteBootstrapPolicyOptions{Out: out} |
28e73694 |
options.CreateBootstrapPolicyCommand = createBootstrapPolicyCommand |
ad916a82 |
cmd := &cobra.Command{ |
28e73694 |
Use: commandName, |
ee70e7d9 |
Short: "Reset the policy to the default values", |
e8ccd07b |
Run: func(cmd *cobra.Command, args []string) { |
ad916a82 |
if err := options.Validate(args); err != nil { |
e8ccd07b |
kcmdutil.CheckErr(kcmdutil.UsageError(cmd, err.Error())) |
ad916a82 |
}
if err := options.OverwriteBootstrapPolicy(); err != nil { |
e8ccd07b |
kcmdutil.CheckErr(err) |
ad916a82 |
}
},
}
flags := cmd.Flags()
|
ac38ade6 |
flags.BoolVarP(&options.Force, "force", "f", false, "You must confirm you really want to reset your policy. This will delete any custom settings you may have.") |
28e73694 |
flags.StringVar(&options.File, "filename", "", "The policy template file containing roles and bindings. One can be created with '"+createBootstrapPolicyCommand+"'.") |
40be29be |
flags.StringVar(&options.MasterConfigFile, "master-config", "openshift.local.config/master/master-config.yaml", "Location of the master configuration file to run from in order to connect to etcd and directly modify the policy.") |
ad916a82 |
|
ea725ace |
// autocompletion hints
cmd.MarkFlagFilename("filename")
cmd.MarkFlagFilename("master-config", "yaml", "yml")
|
ad916a82 |
return cmd
}
func (o OverwriteBootstrapPolicyOptions) Validate(args []string) error {
if len(args) != 0 {
return errors.New("no arguments are supported")
}
if len(o.File) == 0 {
return errors.New("filename must be provided")
}
if len(o.MasterConfigFile) == 0 {
return errors.New("master-config must be provided")
}
return nil
}
func (o OverwriteBootstrapPolicyOptions) OverwriteBootstrapPolicy() error {
masterConfig, err := configapilatest.ReadAndResolveMasterConfig(o.MasterConfigFile)
if err != nil {
return err
}
|
6a7364d3 |
// Connect and setup etcd interfaces
etcdClient, err := etcd.GetAndTestEtcdClient(masterConfig.EtcdClientInfo)
if err != nil {
return err
} |
c76e7b47 |
storage, err := newStorage(etcdClient, masterConfig.EtcdStorageConfig.OpenShiftStorageVersion, masterConfig.EtcdStorageConfig.OpenShiftStoragePrefix) |
ad916a82 |
if err != nil {
return err
}
|
c76e7b47 |
return OverwriteBootstrapPolicy(storage, o.File, o.CreateBootstrapPolicyCommand, o.Force, o.Out) |
ad916a82 |
}
|
c76e7b47 |
func OverwriteBootstrapPolicy(storage storage.Interface, policyFile, createBootstrapPolicyCommand string, change bool, out io.Writer) error { |
ac38ade6 |
if !change {
fmt.Fprintf(out, "Performing a dry run of policy overwrite:\n\n")
} |
28e73694 |
|
ad916a82 |
mapper := cmdclientcmd.ShortcutExpander{kubectl.ShortcutExpander{latest.RESTMapper}} |
557f1436 |
typer := kapi.Scheme |
ad916a82 |
clientMapper := resource.ClientMapperFunc(func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
return nil, nil
})
r := resource.NewBuilder(mapper, typer, clientMapper). |
ab7d732c |
FilenameParam(false, policyFile). |
ad916a82 |
Flatten().
Do()
if r.Err() != nil {
return r.Err()
}
|
c76e7b47 |
policyRegistry := policyregistry.NewRegistry(policyetcd.NewStorage(storage))
policyBindingRegistry := policybindingregistry.NewRegistry(policybindingetcd.NewStorage(storage)) |
ba6a7bc8 |
|
c76e7b47 |
clusterPolicyRegistry := clusterpolicyregistry.NewRegistry(clusterpolicyetcd.NewStorage(storage))
clusterPolicyBindingRegistry := clusterpolicybindingregistry.NewRegistry(clusterpolicybindingetcd.NewStorage(storage)) |
ba6a7bc8 |
|
89b6ba81 |
roleRegistry := roleregistry.NewRegistry(rolestorage.NewVirtualStorage(policyRegistry)) |
ba6a7bc8 |
roleBindingStorage := rolebindingstorage.NewVirtualStorage(policyRegistry, policyBindingRegistry, clusterPolicyRegistry, clusterPolicyBindingRegistry)
clusterRoleStorage := clusterrolestorage.NewClusterRoleStorage(clusterPolicyRegistry)
clusterRoleRegistry := clusterroleregistry.NewRegistry(clusterRoleStorage)
clusterRoleBindingStorage := clusterrolebindingstorage.NewClusterRoleBindingStorage(clusterPolicyRegistry, clusterPolicyBindingRegistry) |
ad916a82 |
return r.Visit(func(info *resource.Info) error {
template, ok := info.Object.(*templateapi.Template)
if !ok { |
28e73694 |
return errors.New("policy must be contained in a template. One can be created with '" + createBootstrapPolicyCommand + "'.") |
ad916a82 |
} |
5576aaec |
runtime.DecodeList(template.Objects, kapi.Scheme) |
ad916a82 |
for _, item := range template.Objects { |
ac38ade6 |
switch t := item.(type) { |
ad916a82 |
case *authorizationapi.Role: |
557f1436 |
ctx := kapi.WithNamespace(kapi.NewContext(), t.Namespace) |
ac38ade6 |
if change {
roleRegistry.DeleteRole(ctx, t.Name) |
89b6ba81 |
if _, err := roleRegistry.CreateRole(ctx, t); err != nil { |
ac38ade6 |
return err
}
} else {
fmt.Fprintf(out, "Overwrite role %s/%s\n", t.Namespace, t.Name)
if s, err := describe.DescribeRole(t); err == nil {
fmt.Fprintf(out, "%s\n", s)
} |
ad916a82 |
}
case *authorizationapi.RoleBinding: |
557f1436 |
ctx := kapi.WithNamespace(kapi.NewContext(), t.Namespace) |
ac38ade6 |
if change { |
89b6ba81 |
roleBindingStorage.Delete(ctx, t.Name, nil)
if _, err := roleBindingStorage.CreateRoleBindingWithEscalation(ctx, t); err != nil { |
ac38ade6 |
return err
}
} else {
fmt.Fprintf(out, "Overwrite role binding %s/%s\n", t.Namespace, t.Name)
if s, err := describe.DescribeRoleBinding(t, nil, nil); err == nil {
fmt.Fprintf(out, "%s\n", s)
} |
ad916a82 |
}
|
ba6a7bc8 |
case *authorizationapi.ClusterRole:
ctx := kapi.WithNamespace(kapi.NewContext(), t.Namespace)
if change {
clusterRoleRegistry.DeleteClusterRole(ctx, t.Name)
if _, err := clusterRoleRegistry.CreateClusterRole(ctx, t); err != nil {
return err
}
} else {
fmt.Fprintf(out, "Overwrite role %s/%s\n", t.Namespace, t.Name)
if s, err := describe.DescribeRole(authorizationapi.ToRole(t)); err == nil {
fmt.Fprintf(out, "%s\n", s)
}
}
case *authorizationapi.ClusterRoleBinding:
ctx := kapi.WithNamespace(kapi.NewContext(), t.Namespace)
if change {
clusterRoleBindingStorage.Delete(ctx, t.Name, nil)
if _, err := clusterRoleBindingStorage.CreateClusterRoleBindingWithEscalation(ctx, t); err != nil {
return err
}
} else {
fmt.Fprintf(out, "Overwrite role binding %s/%s\n", t.Namespace, t.Name)
if s, err := describe.DescribeRoleBinding(authorizationapi.ToRoleBinding(t), nil, nil); err == nil {
fmt.Fprintf(out, "%s\n", s)
}
}
|
ad916a82 |
default:
return errors.New("only roles and rolebindings may be created in this mode")
}
} |
ac38ade6 |
if !change {
fmt.Fprintf(out, "To make the changes described above, pass --force\n")
} |
ad916a82 |
return nil
})
} |
6a7364d3 |
|
c76e7b47 |
// newStorage returns an EtcdHelper for the provided storage version.
func newStorage(client *etcdclient.Client, version, prefix string) (oshelper storage.Interface, err error) { |
6a7364d3 |
interfaces, err := latest.InterfacesFor(version)
if err != nil { |
c76e7b47 |
return nil, err |
6a7364d3 |
} |
c76e7b47 |
return etcdstorage.NewEtcdStorage(client, interfaces.Codec, prefix), nil |
6a7364d3 |
} |