Merge pull request #5067 from leseb/misc-controller-runtime
Misc controller runtime fixes
This commit is contained in:
14 files changed
+176
-106
No files matched your search
@@ -4,7 +4,7 @@ go 1.13
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go v1.16.26
|
||||
github.com/banzaicloud/k8s-objectmatcher v1.2.2
|
||||
github.com/banzaicloud/k8s-objectmatcher v1.1.0
|
||||
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea
|
||||
github.com/coreos/prometheus-operator v0.34.0
|
||||
github.com/corpix/uarand v0.1.1 // indirect
|
||||
@@ -33,7 +33,7 @@ require (
|
||||
k8s.io/kube-controller-manager v0.0.0
|
||||
k8s.io/kubernetes v1.17.2
|
||||
k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6
|
||||
sigs.k8s.io/controller-runtime v0.4.0
|
||||
sigs.k8s.io/controller-runtime v0.5.1
|
||||
sigs.k8s.io/sig-storage-lib-external-provisioner v4.1.0+incompatible
|
||||
)
|
||||
|
||||
|
||||
@@ -53,6 +53,12 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l
|
||||
github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM=
|
||||
github.com/aws/aws-sdk-go v1.16.26 h1:GWkl3rkRO/JGRTWoLLIqwf7AWC4/W/1hMOUZqmX0js4=
|
||||
github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/banzaicloud/k8s-objectmatcher v1.1.0 h1:KHWn9Oxh21xsaGKBHWElkaRrr4ypCDyrh15OB1zHtAw=
|
||||
github.com/banzaicloud/k8s-objectmatcher v1.1.0/go.mod h1:gGaElvgkqa0Lk1khRr+jel/nsCLfzhLnD3CEWozpk9k=
|
||||
github.com/banzaicloud/k8s-objectmatcher v1.1.1 h1:OWS/mUIb7HWI27pOYdxix4xu3nekNOvmS+Y3r9L5mFE=
|
||||
github.com/banzaicloud/k8s-objectmatcher v1.1.1/go.mod h1:NTk6nNix5oP7/lE/5/YxFO87+241sDmTOKvoZ9E+Muw=
|
||||
github.com/banzaicloud/k8s-objectmatcher v1.2.0 h1:ogya2/veg371s8jxWV2/NAtraMLnRqX+RELWJ8275JM=
|
||||
github.com/banzaicloud/k8s-objectmatcher v1.2.0/go.mod h1:+kRcvF2kyA0u8k9AvTYgtt8zhv30Gi8ITKdMWqh7j+A=
|
||||
github.com/banzaicloud/k8s-objectmatcher v1.2.2 h1:WekhVqrRa/wUCPuESExwRjy5R+BDTf/s7DKP99y8MvY=
|
||||
github.com/banzaicloud/k8s-objectmatcher v1.2.2/go.mod h1:+kRcvF2kyA0u8k9AvTYgtt8zhv30Gi8ITKdMWqh7j+A=
|
||||
github.com/bazelbuild/bazel-gazelle v0.18.2/go.mod h1:D0ehMSbS+vesFsLGiD6JXu3mVEzOlfUl8wNnq+x/9p0=
|
||||
@@ -270,6 +276,7 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er
|
||||
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff h1:kOkM9whyQYodu09SJ6W3NCsHG7crFaJILQ22Gozp3lg=
|
||||
github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE=
|
||||
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
@@ -501,6 +508,8 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
@@ -508,6 +517,8 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
|
||||
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
@@ -665,6 +676,8 @@ go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
|
||||
@@ -691,6 +704,7 @@ golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -780,6 +794,7 @@ golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -967,6 +982,8 @@ mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskX
|
||||
sigs.k8s.io/controller-runtime v0.2.0-beta.2/go.mod h1:TSH2R0nSz4WAlUUlNnOFcOR/VUhfwBLlmtq2X6AiQCA=
|
||||
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
|
||||
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
||||
sigs.k8s.io/controller-runtime v0.5.1 h1:TNidCfVoU/cs2i+9xoTcL/l7yhl0bDhYXU0NCG6wmiE=
|
||||
sigs.k8s.io/controller-runtime v0.5.1/go.mod h1:Uojny7gvg55YLQnEGnPzRE3dC4ik2tRlZJgOUCWXAV4=
|
||||
sigs.k8s.io/controller-tools v0.2.2-0.20190919191502-76a25b63325a/go.mod h1:8SNGuj163x/sMwydREj7ld5mIMJu1cDanIfnx6xsU70=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||
sigs.k8s.io/sig-storage-lib-external-provisioner v4.1.0+incompatible h1:pp7GUmQZKI57EjGnjkY88V4QbVuMpkw/ijKXqL67EsI=
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
|
||||
"github.com/rook/rook/pkg/clusterd"
|
||||
cephclient "github.com/rook/rook/pkg/daemon/ceph/client"
|
||||
"github.com/rook/rook/pkg/operator/k8sutil"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -44,7 +43,7 @@ var (
|
||||
)
|
||||
|
||||
// IsReadyToReconcile determines if a controller is ready to reconcile or not
|
||||
func IsReadyToReconcile(client client.Client, clustercontext *clusterd.Context, namespacedName types.NamespacedName) (cephv1.ClusterSpec, bool, bool, reconcile.Result) {
|
||||
func IsReadyToReconcile(client client.Client, clustercontext *clusterd.Context, namespacedName types.NamespacedName, controllerName string) (cephv1.ClusterSpec, bool, bool, reconcile.Result) {
|
||||
namespacedName.Name = namespacedName.Namespace
|
||||
cephClusterExists := true
|
||||
|
||||
@@ -55,34 +54,36 @@ func IsReadyToReconcile(client client.Client, clustercontext *clusterd.Context,
|
||||
if err != nil {
|
||||
if kerrors.IsNotFound(err) {
|
||||
cephClusterExists = false
|
||||
logger.Errorf("CephCluster resource %q not found in namespace %q", namespacedName.Name, namespacedName.Namespace)
|
||||
return cephv1.ClusterSpec{}, false, cephClusterExists, ImmediateRetryResult
|
||||
logger.Errorf("%q: CephCluster resource %q not found in namespace %q", controllerName, namespacedName.Name, namespacedName.Namespace)
|
||||
return cephv1.ClusterSpec{}, false, cephClusterExists, WaitForRequeueIfCephClusterNotReady
|
||||
} else if err != nil {
|
||||
logger.Errorf("failed to fetch CephCluster %v", err)
|
||||
logger.Errorf("%q:failed to fetch CephCluster %v", controllerName, err)
|
||||
return cephv1.ClusterSpec{}, false, cephClusterExists, ImmediateRetryResult
|
||||
}
|
||||
}
|
||||
|
||||
logger.Debugf("CephCluster resource %q found in namespace %q", namespacedName.Name, namespacedName.Namespace)
|
||||
logger.Debugf("%q: CephCluster resource %q found in namespace %q", controllerName, namespacedName.Name, namespacedName.Namespace)
|
||||
|
||||
// If the cluster is ready
|
||||
if cephCluster.Status.Phase == k8sutil.ReadyStatus {
|
||||
// Test a Ceph command to verify the Operator is ready
|
||||
// This is done to silence errors when the operator just started and cannot reconcile yet
|
||||
_, err = cephclient.Status(clustercontext, namespacedName.Namespace)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "error calling conf_read_file") {
|
||||
logger.Info("operator is not ready to run ceph command, cannot reconcile yet.")
|
||||
return cephCluster.Spec, false, cephClusterExists, WaitForRequeueIfCephClusterNotReady
|
||||
}
|
||||
// We should not arrive there
|
||||
logger.Errorf("ceph command error %v", err)
|
||||
return cephCluster.Spec, false, cephClusterExists, ImmediateRetryResult
|
||||
// If the cluster is healthy
|
||||
// Test a Ceph command to verify the Operator is ready
|
||||
// This is done to silence errors when the operator just started and cannot reconcile yet
|
||||
status, err := cephclient.Status(clustercontext, namespacedName.Namespace)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "error calling conf_read_file") {
|
||||
logger.Infof("%q: operator is not ready to run ceph command, cannot reconcile yet.", controllerName)
|
||||
return cephCluster.Spec, false, cephClusterExists, WaitForRequeueIfCephClusterNotReady
|
||||
}
|
||||
logger.Debugf("operator is ready to run ceph command, reconciling")
|
||||
// We should not arrive there
|
||||
logger.Errorf("%q: ceph command error %v", controllerName, err)
|
||||
return cephCluster.Spec, false, cephClusterExists, ImmediateRetryResult
|
||||
}
|
||||
|
||||
// If Ceph status is ok we can reconcile
|
||||
if status.Health.Status == "HEALTH_OK" || status.Health.Status == "HEALTH_WARN" {
|
||||
logger.Debugf("%q: ceph status is %q, operator is ready to run ceph command, reconciling", controllerName, status.Health.Status)
|
||||
return cephCluster.Spec, true, cephClusterExists, reconcile.Result{}
|
||||
}
|
||||
|
||||
logger.Debugf("CephCluster resource %q found in namespace %q but not ready yet", namespacedName.Name, namespacedName.Namespace)
|
||||
return cephCluster.Spec, false, cephClusterExists, ImmediateRetryResult
|
||||
logger.Debugf("%q: CephCluster resource %q found in namespace %q but cluster state is not appropriate %q", controllerName, namespacedName.Name, namespacedName.Namespace, status.Health.Status)
|
||||
return cephCluster.Spec, false, cephClusterExists, WaitForRequeueIfCephClusterNotReady
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
@@ -54,8 +55,7 @@ var logger = capnslog.NewPackageLogger("github.com/rook/rook", controllerName)
|
||||
// List of object resources to watch by the controller
|
||||
var objectsToWatch = []runtime.Object{
|
||||
&corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: corev1.SchemeGroupVersion.String()}},
|
||||
// Stop watching for Deployment object until https://github.com/rook/rook/issues/5047 is fully resolved
|
||||
// &appsv1.Deployment{TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: appsv1.SchemeGroupVersion.String()}},
|
||||
&appsv1.Deployment{TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: appsv1.SchemeGroupVersion.String()}},
|
||||
}
|
||||
|
||||
var cephFilesystemKind = reflect.TypeOf(cephv1.CephFilesystem{}).Name()
|
||||
@@ -159,7 +159,7 @@ func (r *ReconcileCephFilesystem) reconcile(request reconcile.Request) (reconcil
|
||||
}
|
||||
|
||||
// Make sure a CephCluster is present otherwise do nothing
|
||||
cephClusterSpec, isReadyToReconcile, cephClusterExists, reconcileResponse := opcontroller.IsReadyToReconcile(r.client, r.context, request.NamespacedName)
|
||||
cephClusterSpec, isReadyToReconcile, cephClusterExists, reconcileResponse := opcontroller.IsReadyToReconcile(r.client, r.context, request.NamespacedName, controllerName)
|
||||
if !isReadyToReconcile {
|
||||
// This handles the case where the Ceph Cluster is gone and we want to delete that CR
|
||||
// We skip the deleteFilesystem() function since everything is gone already
|
||||
@@ -177,8 +177,6 @@ func (r *ReconcileCephFilesystem) reconcile(request reconcile.Request) (reconcil
|
||||
// Return and do not requeue. Successful deletion.
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
logger.Debugf("CephCluster resource not ready in namespace %q, retrying in %q.", request.NamespacedName.Namespace, opcontroller.WaitForRequeueIfCephClusterNotReadyAfter.String())
|
||||
return reconcileResponse, nil
|
||||
}
|
||||
r.cephClusterSpec = &cephClusterSpec
|
||||
|
||||
@@ -179,13 +179,7 @@ func TestCephObjectStoreController(t *testing.T) {
|
||||
executor := &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(command, outfile string, args ...string) (string, error) {
|
||||
if args[0] == "status" {
|
||||
return `{"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
if args[0] == "fs" && args[1] == "get" {
|
||||
return fsGet, nil
|
||||
}
|
||||
if args[0] == "auth" && args[1] == "get-or-create-key" {
|
||||
return mdsCephAuthGetOrCreateKey, nil
|
||||
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_ERR"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
if args[0] == "versions" {
|
||||
return dummyVersionsRaw, nil
|
||||
@@ -193,6 +187,7 @@ func TestCephObjectStoreController(t *testing.T) {
|
||||
return "", nil
|
||||
},
|
||||
}
|
||||
|
||||
clientset := test.New(t, 3)
|
||||
c := &clusterd.Context{
|
||||
Executor: executor,
|
||||
@@ -279,6 +274,25 @@ func TestCephObjectStoreController(t *testing.T) {
|
||||
// Create a fake client to mock API calls.
|
||||
cl = fake.NewFakeClientWithScheme(s, object...)
|
||||
|
||||
executor = &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(command, outfile string, args ...string) (string, error) {
|
||||
if args[0] == "status" {
|
||||
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_OK"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
if args[0] == "fs" && args[1] == "get" {
|
||||
return fsGet, nil
|
||||
}
|
||||
if args[0] == "auth" && args[1] == "get-or-create-key" {
|
||||
return mdsCephAuthGetOrCreateKey, nil
|
||||
}
|
||||
if args[0] == "versions" {
|
||||
return dummyVersionsRaw, nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
}
|
||||
c.Executor = executor
|
||||
|
||||
// Create a ReconcileCephFilesystem object with the scheme and fake client.
|
||||
r = &ReconcileCephFilesystem{client: cl, scheme: s, context: c}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
opconfig "github.com/rook/rook/pkg/operator/ceph/config"
|
||||
opcontroller "github.com/rook/rook/pkg/operator/ceph/controller"
|
||||
"github.com/rook/rook/pkg/operator/k8sutil"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -53,8 +54,7 @@ var logger = capnslog.NewPackageLogger("github.com/rook/rook", controllerName)
|
||||
var objectsToWatch = []runtime.Object{
|
||||
&v1.Service{TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: v1.SchemeGroupVersion.String()}},
|
||||
&v1.ConfigMap{TypeMeta: metav1.TypeMeta{Kind: "ConfigMap", APIVersion: v1.SchemeGroupVersion.String()}},
|
||||
// Stop watching Deployments until this is resolved: https://github.com/rook/rook/issues/5047
|
||||
// &appsv1.Deployment{TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: appsv1.SchemeGroupVersion.String()}},
|
||||
&appsv1.Deployment{TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: appsv1.SchemeGroupVersion.String()}},
|
||||
}
|
||||
|
||||
var cephNFSKind = reflect.TypeOf(cephv1.CephNFS{}).Name()
|
||||
@@ -158,7 +158,7 @@ func (r *ReconcileCephNFS) reconcile(request reconcile.Request) (reconcile.Resul
|
||||
}
|
||||
|
||||
// Make sure a CephCluster is present otherwise do nothing
|
||||
cephClusterSpec, isReadyToReconcile, cephClusterExists, reconcileResponse := opcontroller.IsReadyToReconcile(r.client, r.context, request.NamespacedName)
|
||||
cephClusterSpec, isReadyToReconcile, cephClusterExists, reconcileResponse := opcontroller.IsReadyToReconcile(r.client, r.context, request.NamespacedName, controllerName)
|
||||
if !isReadyToReconcile {
|
||||
// This handles the case where the Ceph Cluster is gone and we want to delete that CR
|
||||
// We skip the deleteStore() function since everything is gone already
|
||||
@@ -176,8 +176,6 @@ func (r *ReconcileCephNFS) reconcile(request reconcile.Request) (reconcile.Resul
|
||||
// Return and do not requeue. Successful deletion.
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
logger.Debugf("CephCluster resource not ready in namespace %q, retrying in %q.", request.NamespacedName.Namespace, opcontroller.WaitForRequeueIfCephClusterNotReadyAfter.String())
|
||||
return reconcileResponse, nil
|
||||
}
|
||||
r.cephClusterSpec = &cephClusterSpec
|
||||
|
||||
@@ -107,32 +107,12 @@ func TestCephNFSController(t *testing.T) {
|
||||
executor := &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(command, outfile string, args ...string) (string, error) {
|
||||
if args[0] == "status" {
|
||||
return `{"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_ERR"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
if args[0] == "versions" {
|
||||
return dummyVersionsRaw, nil
|
||||
}
|
||||
if args[0] == "osd" && args[1] == "pool" && args[2] == "get" {
|
||||
return poolDetails, nil
|
||||
}
|
||||
return "", errors.New("unknown command")
|
||||
},
|
||||
MockExecuteCommand: func(command string, args ...string) error {
|
||||
if command == "rados" {
|
||||
logger.Infof("mock execute. %s. %s", command, args)
|
||||
assert.Equal(t, "stat", args[6])
|
||||
return nil
|
||||
}
|
||||
return errors.New("unknown command")
|
||||
},
|
||||
MockExecuteCommandWithEnv: func(env []string, command string, args ...string) error {
|
||||
if command == "ganesha-rados-grace" {
|
||||
logger.Infof("mock execute. %s. %s", command, args)
|
||||
assert.Equal(t, "add", args[4])
|
||||
assert.Len(t, env, 1)
|
||||
return nil
|
||||
}
|
||||
return errors.New("unknown command")
|
||||
return "", nil
|
||||
},
|
||||
}
|
||||
clientset := test.New(t, 3)
|
||||
@@ -221,6 +201,39 @@ func TestCephNFSController(t *testing.T) {
|
||||
// Create a fake client to mock API calls.
|
||||
cl = fake.NewFakeClientWithScheme(s, object...)
|
||||
|
||||
executor = &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(command, outfile string, args ...string) (string, error) {
|
||||
if args[0] == "status" {
|
||||
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_OK"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
if args[0] == "versions" {
|
||||
return dummyVersionsRaw, nil
|
||||
}
|
||||
if args[0] == "osd" && args[1] == "pool" && args[2] == "get" {
|
||||
return poolDetails, nil
|
||||
}
|
||||
return "", errors.New("unknown command")
|
||||
},
|
||||
MockExecuteCommand: func(command string, args ...string) error {
|
||||
if command == "rados" {
|
||||
logger.Infof("mock execute. %s. %s", command, args)
|
||||
assert.Equal(t, "stat", args[6])
|
||||
return nil
|
||||
}
|
||||
return errors.New("unknown command")
|
||||
},
|
||||
MockExecuteCommandWithEnv: func(env []string, command string, args ...string) error {
|
||||
if command == "ganesha-rados-grace" {
|
||||
logger.Infof("mock execute. %s. %s", command, args)
|
||||
assert.Equal(t, "add", args[4])
|
||||
assert.Len(t, env, 1)
|
||||
return nil
|
||||
}
|
||||
return errors.New("unknown command")
|
||||
},
|
||||
}
|
||||
c.Executor = executor
|
||||
|
||||
// Create a ReconcileCephNFS object with the scheme and fake client.
|
||||
r = &ReconcileCephNFS{client: cl, scheme: s, context: c}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
opconfig "github.com/rook/rook/pkg/operator/ceph/config"
|
||||
opcontroller "github.com/rook/rook/pkg/operator/ceph/controller"
|
||||
"github.com/rook/rook/pkg/operator/k8sutil"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -54,8 +55,7 @@ var logger = capnslog.NewPackageLogger("github.com/rook/rook", controllerName)
|
||||
var objectsToWatch = []runtime.Object{
|
||||
&corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: corev1.SchemeGroupVersion.String()}},
|
||||
&v1.Service{TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: v1.SchemeGroupVersion.String()}},
|
||||
// Stop watching for Deployment object until https://github.com/rook/rook/issues/5047 is fully resolved
|
||||
// &appsv1.Deployment{TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: appsv1.SchemeGroupVersion.String()}},
|
||||
&appsv1.Deployment{TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: appsv1.SchemeGroupVersion.String()}},
|
||||
}
|
||||
|
||||
var cephObjectStoreKind = reflect.TypeOf(cephv1.CephObjectStore{}).Name()
|
||||
@@ -159,7 +159,7 @@ func (r *ReconcileCephObjectStore) reconcile(request reconcile.Request) (reconci
|
||||
}
|
||||
|
||||
// Make sure a CephCluster is present otherwise do nothing
|
||||
cephClusterSpec, isReadyToReconcile, cephClusterExists, reconcileResponse := opcontroller.IsReadyToReconcile(r.client, r.context, request.NamespacedName)
|
||||
cephClusterSpec, isReadyToReconcile, cephClusterExists, reconcileResponse := opcontroller.IsReadyToReconcile(r.client, r.context, request.NamespacedName, controllerName)
|
||||
if !isReadyToReconcile {
|
||||
// This handles the case where the Ceph Cluster is gone and we want to delete that CR
|
||||
// We skip the deleteStore() function since everything is gone already
|
||||
@@ -178,7 +178,6 @@ func (r *ReconcileCephObjectStore) reconcile(request reconcile.Request) (reconci
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
logger.Debugf("CephCluster resource not ready in namespace %q, retrying in %q.", request.NamespacedName.Namespace, opcontroller.WaitForRequeueIfCephClusterNotReadyAfter.String())
|
||||
return reconcileResponse, nil
|
||||
}
|
||||
r.cephClusterSpec = &cephClusterSpec
|
||||
|
||||
@@ -174,31 +174,13 @@ func TestCephObjectStoreController(t *testing.T) {
|
||||
executor := &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(command, outfile string, args ...string) (string, error) {
|
||||
if args[0] == "status" {
|
||||
return `{"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
if args[0] == "auth" && args[1] == "get-or-create-key" {
|
||||
return rgwCephAuthGetOrCreateKey, nil
|
||||
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_ERR"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
if args[0] == "versions" {
|
||||
return dummyVersionsRaw, nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
|
||||
if args[0] == "realm" && args[1] == "list" {
|
||||
return realmListJSON, nil
|
||||
}
|
||||
if args[0] == "realm" && args[1] == "get" {
|
||||
return realmGetJSON, nil
|
||||
}
|
||||
if args[0] == "zonegroup" && args[1] == "get" {
|
||||
return zoneGroupGetJSON, nil
|
||||
}
|
||||
if args[0] == "zone" && args[1] == "get" {
|
||||
return zoneGetJSON, nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
}
|
||||
clientset := test.New(t, 3)
|
||||
c := &clusterd.Context{
|
||||
@@ -280,12 +262,41 @@ func TestCephObjectStoreController(t *testing.T) {
|
||||
_, err = c.Clientset.CoreV1().Secrets(namespace).Create(secret)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Add ready status to the CephCluster
|
||||
cephCluster.Status.Phase = k8sutil.ReadyStatus
|
||||
|
||||
// Create a fake client to mock API calls.
|
||||
cl = fake.NewFakeClientWithScheme(s, object...)
|
||||
|
||||
// Override executor with the new ceph status and more content
|
||||
executor = &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(command, outfile string, args ...string) (string, error) {
|
||||
if args[0] == "status" {
|
||||
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_OK"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
if args[0] == "auth" && args[1] == "get-or-create-key" {
|
||||
return rgwCephAuthGetOrCreateKey, nil
|
||||
}
|
||||
if args[0] == "versions" {
|
||||
return dummyVersionsRaw, nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
|
||||
if args[0] == "realm" && args[1] == "list" {
|
||||
return realmListJSON, nil
|
||||
}
|
||||
if args[0] == "realm" && args[1] == "get" {
|
||||
return realmGetJSON, nil
|
||||
}
|
||||
if args[0] == "zonegroup" && args[1] == "get" {
|
||||
return zoneGroupGetJSON, nil
|
||||
}
|
||||
if args[0] == "zone" && args[1] == "get" {
|
||||
return zoneGetJSON, nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
}
|
||||
c.Executor = executor
|
||||
|
||||
// Create a ReconcileCephObjectStore object with the scheme and fake client.
|
||||
r = &ReconcileCephObjectStore{client: cl, scheme: s, context: c}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ func (r *ReconcileObjectStoreUser) reconcile(request reconcile.Request) (reconci
|
||||
}
|
||||
|
||||
// Make sure a CephCluster is present otherwise do nothing
|
||||
_, isReadyToReconcile, cephClusterExists, reconcileResponse := opcontroller.IsReadyToReconcile(r.client, r.context, request.NamespacedName)
|
||||
_, isReadyToReconcile, cephClusterExists, reconcileResponse := opcontroller.IsReadyToReconcile(r.client, r.context, request.NamespacedName, controllerName)
|
||||
if !isReadyToReconcile {
|
||||
// This handles the case where the Ceph Cluster is gone and we want to delete that CR
|
||||
// We skip the deleteUser() function since everything is gone already
|
||||
@@ -169,8 +169,6 @@ func (r *ReconcileObjectStoreUser) reconcile(request reconcile.Request) (reconci
|
||||
// Return and do not requeue. Successful deletion.
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
logger.Debugf("CephCluster resource not ready in namespace %q, retrying in %q.", request.NamespacedName.Namespace, opcontroller.WaitForRequeueIfCephClusterNotReadyAfter.String())
|
||||
return reconcileResponse, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -118,13 +118,7 @@ func TestCephObjectStoreUserController(t *testing.T) {
|
||||
executor := &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(command, outfile string, args ...string) (string, error) {
|
||||
if args[0] == "status" {
|
||||
return `{"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
|
||||
if args[0] == "user" {
|
||||
return userCreateJSON, nil
|
||||
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_ERR"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
@@ -190,6 +184,23 @@ func TestCephObjectStoreUserController(t *testing.T) {
|
||||
cephCluster.Status.Phase = k8sutil.ReadyStatus
|
||||
// Create a fake client to mock API calls.
|
||||
cl = fake.NewFakeClientWithScheme(s, object...)
|
||||
|
||||
executor = &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(command, outfile string, args ...string) (string, error) {
|
||||
if args[0] == "status" {
|
||||
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_OK"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
|
||||
if args[0] == "user" {
|
||||
return userCreateJSON, nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
}
|
||||
c.Executor = executor
|
||||
|
||||
// Create a ReconcileObjectStoreUser object with the scheme and fake client.
|
||||
r = &ReconcileObjectStoreUser{client: cl, scheme: s, context: c}
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ func (r *ReconcileCephBlockPool) reconcile(request reconcile.Request) (reconcile
|
||||
}
|
||||
|
||||
// Make sure a CephCluster is present otherwise do nothing
|
||||
_, isReadyToReconcile, cephClusterExists, reconcileResponse := opcontroller.IsReadyToReconcile(r.client, r.context, request.NamespacedName)
|
||||
_, isReadyToReconcile, cephClusterExists, reconcileResponse := opcontroller.IsReadyToReconcile(r.client, r.context, request.NamespacedName, controllerName)
|
||||
if !isReadyToReconcile {
|
||||
// This handles the case where the Ceph Cluster is gone and we want to delete that CR
|
||||
// We skip the deletePool() function since everything is gone already
|
||||
@@ -159,8 +159,6 @@ func (r *ReconcileCephBlockPool) reconcile(request reconcile.Request) (reconcile
|
||||
// Return and do not requeue. Successful deletion.
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
logger.Debugf("CephCluster resource not ready in namespace %q, retrying in %q.", request.NamespacedName.Namespace, opcontroller.WaitForRequeueIfCephClusterNotReadyAfter.String())
|
||||
return reconcileResponse, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ func TestCephBlockPoolController(t *testing.T) {
|
||||
executor := &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(command, outfile string, args ...string) (string, error) {
|
||||
if args[0] == "status" {
|
||||
return `{"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_ERR"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
|
||||
return "", nil
|
||||
@@ -313,6 +313,18 @@ func TestCephBlockPoolController(t *testing.T) {
|
||||
}
|
||||
// Create a fake client to mock API calls.
|
||||
cl = fake.NewFakeClient(objects...)
|
||||
|
||||
executor = &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(command, outfile string, args ...string) (string, error) {
|
||||
if args[0] == "status" {
|
||||
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_OK"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
|
||||
}
|
||||
|
||||
return "", nil
|
||||
},
|
||||
}
|
||||
c.Executor = executor
|
||||
|
||||
// Create a ReconcileCephBlockPool object with the scheme and fake client.
|
||||
r = &ReconcileCephBlockPool{client: cl, scheme: s, context: c}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ var rawContext = `{
|
||||
|
||||
func TestLoadMinikubeContext(t *testing.T) {
|
||||
executor := &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutput: func(command string, subcommand string, args ...string) (string, error) {
|
||||
MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
|
||||
return fmt.Sprintf(rawContext, "minikube"), nil
|
||||
}}
|
||||
config, err := getKubeConfig(executor)
|
||||
@@ -111,7 +111,7 @@ func TestLoadMinikubeContext(t *testing.T) {
|
||||
|
||||
func TestLoadDindContext(t *testing.T) {
|
||||
executor := &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutput: func(command string, subcommand string, args ...string) (string, error) {
|
||||
MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
|
||||
return fmt.Sprintf(rawContext, "dind"), nil
|
||||
}}
|
||||
config, err := getKubeConfig(executor)
|
||||
@@ -126,7 +126,7 @@ func TestLoadDindContext(t *testing.T) {
|
||||
|
||||
func TestLoadVagrantContext(t *testing.T) {
|
||||
executor := &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutput: func(command string, subcommand string, args ...string) (string, error) {
|
||||
MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
|
||||
return fmt.Sprintf(rawContext, "vagrant-single"), nil
|
||||
}}
|
||||
config, err := getKubeConfig(executor)
|
||||
|
||||
Reference in new issue
Block a user