未验证 提交 0d2279f5 编写于 作者: H hongming

fix somme error in controller-manager

Signed-off-by: Nhongming <talonwan@yunify.com>
上级 54fc52c0
......@@ -25,6 +25,7 @@ import (
"kubesphere.io/kubesphere/pkg/controller/s2ibinary"
"kubesphere.io/kubesphere/pkg/controller/s2irun"
"kubesphere.io/kubesphere/pkg/controller/storage/expansion"
"kubesphere.io/kubesphere/pkg/controller/user"
"kubesphere.io/kubesphere/pkg/controller/virtualservice"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
......@@ -87,6 +88,11 @@ func AddControllers(
kubernetesInformer.Apps().V1().ReplicaSets(),
kubernetesInformer.Apps().V1().StatefulSets())
userController := user.NewController(
client.Kubernetes(),
client.KubeSphere(),
kubesphereInformer.Iam().V1alpha2().Users())
controllers := map[string]manager.Runnable{
"virtualservice-controller": vsController,
"destinationrule-controller": drController,
......@@ -95,6 +101,7 @@ func AddControllers(
"s2ibinary-controller": s2iBinaryController,
"s2irun-controller": s2iRunController,
"volumeexpansion-controller": volumeExpansionController,
"user-controller": userController,
}
for name, ctrl := range controllers {
......
......@@ -49,11 +49,13 @@ func NewControllerManagerCommand() *cobra.Command {
s := options.NewKubeSphereControllerManagerOptions()
conf, err := controllerconfig.TryLoadFromDisk()
if err == nil {
// make sure LeaderElection is not nil
s = &options.KubeSphereControllerManagerOptions{
KubernetesOptions: conf.KubernetesOptions,
DevopsOptions: conf.DevopsOptions,
S3Options: conf.S3Options,
OpenPitrixOptions: conf.OpenPitrixOptions,
LeaderElection: s.LeaderElection,
}
}
......@@ -118,7 +120,6 @@ func Run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
*/
informerFactory := informers.NewInformerFactories(kubernetesClient.Kubernetes(), kubernetesClient.KubeSphere(), kubernetesClient.Istio(), kubernetesClient.Application())
informerFactory.Start(stopCh)
run := func(ctx context.Context) {
klog.V(0).Info("setting up manager")
......@@ -147,6 +148,9 @@ func Run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
klog.Fatalf("unable to register controllers to the manager: %v", err)
}
// Start cache data after all informer is registered
informerFactory.Start(stopCh)
klog.V(0).Info("Starting the controllers.")
if err = mgr.Start(stopCh); err != nil {
klog.Fatalf("unable to run the manager: %v", err)
......
......@@ -12,6 +12,9 @@ spec:
- JSONPath: .spec.email
name: Email
type: string
- JSONPath: .status.state
name: Status
type: string
group: iam.kubesphere.io
names:
categories:
......@@ -94,8 +97,8 @@ spec:
- type
type: object
type: array
phase:
description: Phase is the phase of the user.
state:
description: The user status
type: string
type: object
required:
......
......@@ -3,7 +3,7 @@ kind: User
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: user-sample
name: admin
spec:
# Add fields here
foo: bar
email: admin@kubesphere.io
password: d41d8cd98f00b204e9800998ecf8427e
......@@ -29,6 +29,7 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
// +kubebuilder:printcolumn:name="Email",type="string",JSONPath=".spec.email"
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.state"
// +kubebuilder:resource:categories="iam",scope="Cluster"
type User struct {
metav1.TypeMeta `json:",inline"`
......@@ -62,40 +63,40 @@ type UserSpec struct {
Finalizers []FinalizerName `json:"finalizers,omitempty"`
}
type UserPhase string
type UserState string
// These are the valid phases of a user.
const (
// UserActive means the user is available.
UserActive UserPhase = "Active"
UserActive UserState = "Active"
// UserDisabled means the user is disabled.
UserDisabled UserPhase = "Disabled"
UserDisabled UserState = "Disabled"
)
// UserStatus defines the observed state of User
type UserStatus struct {
// Phase is the phase of the user.
// The user status
// +optional
Phase UserPhase `json:"phase,omitempty" protobuf:"bytes,1,opt,name=phase,casttype=UserPhase"`
State UserState `json:"state,omitempty"`
// Represents the latest available observations of a namespace's current state.
// +optional
// +patchMergeKey=type
// +patchStrategy=merge
Conditions []UserCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,2,rep,name=conditions"`
Conditions []UserCondition `json:"conditions,omitempty"`
}
type UserCondition struct {
// Type of namespace controller condition.
Type UserConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=NamespaceConditionType"`
Type UserConditionType `json:"type"`
// Status of the condition, one of True, False, Unknown.
Status ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=ConditionStatus"`
Status ConditionStatus `json:"status"`
// +optional
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,4,opt,name=lastTransitionTime"`
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
// +optional
Reason string `json:"reason,omitempty" protobuf:"bytes,5,opt,name=reason"`
Reason string `json:"reason,omitempty"`
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,6,opt,name=message"`
Message string `json:"message,omitempty"`
}
type UserConditionType string
......
/*
Copyright 2019 The KubeSphere 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.
*/
*
* Copyright 2020 The KubeSphere 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 v1alpha2
......
......@@ -24,7 +24,6 @@ import (
"github.com/golang/protobuf/ptypes/wrappers"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
......@@ -44,22 +43,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/source"
)
const (
adminDescription = "Allows admin access to perform any action on any resource, it gives full control over every resource in the namespace."
operatorDescription = "The maintainer of the namespace who can manage resources other than users and roles in the namespace."
viewerDescription = "Allows viewer access to view all resources in the namespace."
)
var (
admin = rbac.Role{ObjectMeta: metav1.ObjectMeta{Name: "admin", Annotations: map[string]string{constants.DescriptionAnnotationKey: adminDescription, constants.CreatorAnnotationKey: constants.System}}, Rules: []rbac.PolicyRule{{Verbs: []string{"*"}, APIGroups: []string{"*"}, Resources: []string{"*"}}}}
operator = rbac.Role{ObjectMeta: metav1.ObjectMeta{Name: "operator", Annotations: map[string]string{constants.DescriptionAnnotationKey: operatorDescription, constants.CreatorAnnotationKey: constants.System}}, Rules: []rbac.PolicyRule{{Verbs: []string{"get", "list", "watch"}, APIGroups: []string{"*"}, Resources: []string{"*"}},
{Verbs: []string{"*"}, APIGroups: []string{"apps", "extensions", "batch", "logging.kubesphere.io", "monitoring.kubesphere.io", "iam.kubesphere.io", "autoscaling", "alerting.kubesphere.io", "openpitrix.io", "app.k8s.io", "servicemesh.kubesphere.io", "operations.kubesphere.io", "devops.kubesphere.io"}, Resources: []string{"*"}},
{Verbs: []string{"*"}, APIGroups: []string{"", "resources.kubesphere.io"}, Resources: []string{"jobs", "cronjobs", "daemonsets", "deployments", "horizontalpodautoscalers", "ingresses", "endpoints", "configmaps", "events", "persistentvolumeclaims", "pods", "podtemplates", "pods", "secrets", "services"}},
}}
viewer = rbac.Role{ObjectMeta: metav1.ObjectMeta{Name: "viewer", Annotations: map[string]string{constants.DescriptionAnnotationKey: viewerDescription, constants.CreatorAnnotationKey: constants.System}}, Rules: []rbac.PolicyRule{{Verbs: []string{"get", "list", "watch"}, APIGroups: []string{"*"}, Resources: []string{"*"}}}}
defaultRoles = []rbac.Role{admin, operator, viewer}
)
/**
* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller
* business logic. Delete these comments after modifying this file.*
......@@ -164,19 +147,6 @@ func (r *ReconcileNamespace) Reconcile(request reconcile.Request) (reconcile.Res
return reconcile.Result{}, nil
}
controlledByWorkspace, err := r.isControlledByWorkspace(instance)
if err != nil {
return reconcile.Result{}, err
}
if !controlledByWorkspace {
err = r.deleteRoleBindings(instance)
return reconcile.Result{}, err
}
if err = r.checkAndBindWorkspace(instance); err != nil {
return reconcile.Result{}, err
}
......@@ -357,24 +327,3 @@ func (r *ReconcileNamespace) deleteRouter(namespace string) error {
return nil
}
func (r *ReconcileNamespace) deleteRoleBindings(namespace *corev1.Namespace) error {
klog.V(4).Info("deleting role bindings namespace: ", namespace.Name)
adminBinding := &rbac.RoleBinding{}
adminBinding.Name = admin.Name
adminBinding.Namespace = namespace.Name
err := r.Delete(context.TODO(), adminBinding)
if err != nil && !errors.IsNotFound(err) {
klog.Errorf("deleting role binding namespace: %s, role binding: %s,error: %s", namespace.Name, adminBinding.Name, err)
return err
}
viewerBinding := &rbac.RoleBinding{}
viewerBinding.Name = viewer.Name
viewerBinding.Namespace = namespace.Name
err = r.Delete(context.TODO(), viewerBinding)
if err != nil && !errors.IsNotFound(err) {
klog.Errorf("deleting role binding namespace: %s,role binding: %s,error: %s", namespace.Name, viewerBinding.Name, err)
return err
}
return nil
}
......@@ -66,7 +66,6 @@ type Controller struct {
func NewController(kubeclientset kubernetes.Interface,
kubesphereklientset kubesphereclient.Interface,
userInformer userinformer.UserInformer) *Controller {
// Create event broadcaster
// Add sample-controller types to the default Kubernetes Scheme so Events can be
// logged for sample-controller types.
......@@ -180,7 +179,7 @@ func (c *Controller) processNextWorkItem() bool {
// Finally, if no error occurs we Forget this item so it does not
// get queued again until another change happens.
c.workqueue.Forget(obj)
klog.Info("Successfully synced", "key", key)
klog.Infof("Successfully synced %s:%s", "key", key)
return nil
}(obj)
......@@ -206,11 +205,11 @@ func (c *Controller) reconcile(key string) error {
utilruntime.HandleError(fmt.Errorf("user '%s' in work queue no longer exists", key))
return nil
}
return err
}
err = c.updateUserStatus(user)
if err != nil {
return err
}
......@@ -220,9 +219,12 @@ func (c *Controller) reconcile(key string) error {
}
func (c *Controller) updateUserStatus(user *iamv1alpha2.User) error {
userCopy := user.DeepCopy()
userCopy.Status.Phase = iamv1alpha2.UserActive
userCopy.Status.State = iamv1alpha2.UserActive
_, err := c.kubesphereClientset.IamV1alpha2().Users().Update(userCopy)
return err
}
func (c *Controller) Start(stopCh <-chan struct{}) error {
return c.Run(4, stopCh)
}
......@@ -219,7 +219,7 @@ func filterInformerActions(actions []core.Action) []core.Action {
func (f *fixture) expectUpdateUserStatusAction(user *iamv1alpha2.User) {
expect := user.DeepCopy()
expect.Status.Phase = iamv1alpha2.UserActive
expect.Status.State = iamv1alpha2.UserActive
action := core.NewUpdateAction(schema.GroupVersionResource{Resource: "users"}, "", expect)
f.actions = append(f.actions, action)
}
......
......@@ -98,7 +98,7 @@ func (f *informerFactories) Start(stopCh <-chan struct{}) {
f.ksInformerFactory.Start(stopCh)
}
if f.informerFactory != nil {
if f.istioInformerFactory != nil {
f.istioInformerFactory.Start(stopCh)
}
......
......@@ -47,7 +47,8 @@ func AddToContainer(c *restful.Container, issuer token.Issuer, options *authopti
// Implement webhook authentication interface
// https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
ws.Route(ws.POST("/authenticate").
Doc("TokenReview attempts to authenticate a token to a known user. Note: TokenReview requests may be cached by the webhook token authenticator plugin in the kube-apiserver.").
Doc("TokenReview attempts to authenticate a token to a known user. Note: TokenReview requests may be "+
"cached by the webhook token authenticator plugin in the kube-apiserver.").
Reads(auth.TokenReview{}).
To(handler.TokenReviewHandler).
Returns(http.StatusOK, api.StatusOK, auth.TokenReview{}).
......@@ -57,6 +58,14 @@ func AddToContainer(c *restful.Container, issuer token.Issuer, options *authopti
// https://tools.ietf.org/html/rfc6749#section-4.2
ws.Route(ws.GET("/authorize").
Doc("All requests for OAuth tokens involve a request to <ks-apiserver>/oauth/authorize.").
Param(ws.QueryParameter("response_type", "The value MUST be one of \"code\" for requesting an "+
"authorization code as described by [RFC6749] Section 4.1.1, \"token\" for requesting an access token (implicit grant)"+
" as described by [RFC6749] Section 4.2.2.").Required(true)).
Param(ws.QueryParameter("client_id", "The client identifier issued to the client during the "+
"registration process described by [RFC6749] Section 2.2.").Required(true)).
Param(ws.QueryParameter("redirect_uri", "After completing its interaction with the resource owner, "+
"the authorization server directs the resource owner's user-agent back to the client.The redirection endpoint "+
"URI MUST be an absolute URI as defined by [RFC3986] Section 4.3.").Required(false)).
To(handler.AuthorizeHandler))
//ws.Route(ws.POST("/token"))
......@@ -64,6 +73,19 @@ func AddToContainer(c *restful.Container, issuer token.Issuer, options *authopti
// The provider name is also used to build the callback URL.
ws.Route(ws.GET("/callback/{callback}").
Doc("OAuth callback API, the path param callback is config by identity provider").
Param(ws.QueryParameter("access_token", "The access token issued by the authorization server.").
Required(true)).
Param(ws.QueryParameter("token_type", "The type of the token issued as described in [RFC6479] Section 7.1. "+
"Value is case insensitive.").Required(true)).
Param(ws.QueryParameter("expires_in", "The lifetime in seconds of the access token. For "+
"example, the value \"3600\" denotes that the access token will "+
"expire in one hour from the time the response was generated."+
"If omitted, the authorization server SHOULD provide the "+
"expiration time via other means or document the default value.")).
Param(ws.QueryParameter("scope", "if identical to the scope requested by the client;"+
"otherwise, REQUIRED. The scope of the access token as described by [RFC6479] Section 3.3.").Required(false)).
Param(ws.QueryParameter("state", "if the \"state\" parameter was present in the client authorization request."+
"The exact value received from the client.").Required(true)).
To(handler.OAuthCallBackHandler).
Returns(http.StatusOK, api.StatusOK, oauth.Token{}))
......
......@@ -34,15 +34,17 @@ var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
func AddToContainer(c *restful.Container, config *apiserverconfig.Config) error {
webservice := runtime.NewWebService(GroupVersion)
// information about the authorization server are published.
webservice.Route(webservice.GET("/configs/oauth").To(func(request *restful.Request, response *restful.Response) {
response.WriteEntity(config.AuthenticationOptions.OAuthOptions)
}))
// information about the server configuration
webservice.Route(webservice.GET("/configs/configz").To(func(request *restful.Request, response *restful.Response) {
response.WriteAsJson(config.ToMap())
}))
webservice.Route(webservice.GET("/configs/oauth").
Doc("Information about the authorization server are published.").
To(func(request *restful.Request, response *restful.Response) {
response.WriteEntity(config.AuthenticationOptions.OAuthOptions)
}))
webservice.Route(webservice.GET("/configs/configz").
Doc("Information about the server configuration").
To(func(request *restful.Request, response *restful.Response) {
response.WriteAsJson(config.ToMap())
}))
c.Add(webservice)
return nil
......
......@@ -98,6 +98,12 @@ func NewKubernetesClient(options *KubernetesOptions) (Client, error) {
return nil, err
}
k.istio, err = istioclient.NewForConfig(config)
if err != nil {
return nil, err
}
k.master = options.Master
k.config = config
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册