Skip to content

Commit

Permalink
Feat: Conditional CSR controller spawning (#84)
Browse files Browse the repository at this point in the history
* [generated] go mod vendor

Signed-off-by: yue9944882 <291271447@qq.com>

* conditional CSR controller enabling

Signed-off-by: yue9944882 <291271447@qq.com>
  • Loading branch information
yue9944882 committed Mar 15, 2022
1 parent 9c08db9 commit f2fc48e
Show file tree
Hide file tree
Showing 5 changed files with 361 additions and 20 deletions.
58 changes: 38 additions & 20 deletions pkg/addonmanager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io/ioutil"
"time"

"github.com/openshift/library-go/pkg/controller/factory"
"github.com/openshift/library-go/pkg/operator/events"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeinformers "k8s.io/client-go/informers"
Expand All @@ -20,6 +21,7 @@ import (
"open-cluster-management.io/addon-framework/pkg/addonmanager/controllers/clustermanagement"
"open-cluster-management.io/addon-framework/pkg/addonmanager/controllers/registration"
"open-cluster-management.io/addon-framework/pkg/agent"
"open-cluster-management.io/addon-framework/pkg/utils"
addonv1alpha1client "open-cluster-management.io/api/client/addon/clientset/versioned"
addoninformers "open-cluster-management.io/api/client/addon/informers/externalversions"
clusterv1client "open-cluster-management.io/api/client/cluster/clientset/versioned"
Expand Down Expand Up @@ -76,6 +78,11 @@ func (a *addonManager) Start(ctx context.Context) error {
return err
}

v1CSRSupported, _, err := utils.IsCSRSupported(kubeClient)
if err != nil {
return err
}

namespace, err := a.getComponentNamespace()
if err != nil {
klog.Warningf("unable to identify the current namespace for events: %v", err)
Expand Down Expand Up @@ -150,24 +157,6 @@ func (a *addonManager) Start(ctx context.Context) error {
eventRecorder,
)

csrApproveController := certificate.NewCSRApprovingController(
kubeClient,
clusterInformers.Cluster().V1().ManagedClusters(),
kubeInfomers.Certificates().V1().CertificateSigningRequests(),
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
a.addonAgents,
eventRecorder,
)

csrSignController := certificate.NewCSRSignController(
kubeClient,
clusterInformers.Cluster().V1().ManagedClusters(),
kubeInfomers.Certificates().V1().CertificateSigningRequests(),
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
a.addonAgents,
eventRecorder,
)

clusterManagementController := clustermanagement.NewClusterManagementController(
addonClient,
clusterInformers.Cluster().V1().ManagedClusters(),
Expand All @@ -192,6 +181,31 @@ func (a *addonManager) Start(ctx context.Context) error {
a.addonAgents,
eventRecorder)

var csrApproveController factory.Controller
var csrSignController factory.Controller
// Spawn the following controllers only if v1 CSR api is supported in the
// hub cluster. Under v1beta1 CSR api, all the CSR objects will be signed
// by the kube-controller-manager so custom CSR controller should be
// disabled to avoid conflict.
if v1CSRSupported {
csrApproveController = certificate.NewCSRApprovingController(
kubeClient,
clusterInformers.Cluster().V1().ManagedClusters(),
kubeInfomers.Certificates().V1().CertificateSigningRequests(),
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
a.addonAgents,
eventRecorder,
)
csrSignController = certificate.NewCSRSignController(
kubeClient,
clusterInformers.Cluster().V1().ManagedClusters(),
kubeInfomers.Certificates().V1().CertificateSigningRequests(),
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
a.addonAgents,
eventRecorder,
)
}

go addonInformers.Start(ctx.Done())
go workInformers.Start(ctx.Done())
go clusterInformers.Start(ctx.Done())
Expand All @@ -200,11 +214,15 @@ func (a *addonManager) Start(ctx context.Context) error {
go deployController.Run(ctx, 1)
go hookDeployController.Run(ctx, 1)
go registrationController.Run(ctx, 1)
go csrApproveController.Run(ctx, 1)
go csrSignController.Run(ctx, 1)
go clusterManagementController.Run(ctx, 1)
go addonInstallController.Run(ctx, 1)
go addonHealthCheckController.Run(ctx, 1)
if csrApproveController != nil {
go csrApproveController.Run(ctx, 1)
}
if csrSignController != nil {
go csrSignController.Run(ctx, 1)
}
return nil
}

Expand Down
60 changes: 60 additions & 0 deletions pkg/utils/csr_helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import (
"time"

"github.com/openshift/library-go/pkg/crypto"
"github.com/stretchr/testify/assert"
certificatesv1 "k8s.io/api/certificates/v1"
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
certutil "k8s.io/client-go/util/cert"
"k8s.io/client-go/util/keyutil"
"open-cluster-management.io/addon-framework/pkg/agent"
Expand Down Expand Up @@ -173,3 +176,60 @@ func TestUnionApprover(t *testing.T) {
})
}
}

func TestIsCSRSupported(t *testing.T) {
cases := []struct {
apiResources []*metav1.APIResourceList
expectedV1 bool
expectedV1beta1 bool
expectedError error
}{
{
apiResources: []*metav1.APIResourceList{
{
GroupVersion: certificatesv1.SchemeGroupVersion.String(),
APIResources: []metav1.APIResource{
{
Name: "certificatesigningrequests",
Kind: "CertificateSigningRequest",
},
},
},
{
GroupVersion: certificatesv1beta1.SchemeGroupVersion.String(),
APIResources: []metav1.APIResource{
{
Name: "certificatesigningrequests",
Kind: "CertificateSigningRequest",
},
},
},
},
expectedV1: true,
expectedV1beta1: true,
},
{
apiResources: []*metav1.APIResourceList{
{
GroupVersion: certificatesv1beta1.SchemeGroupVersion.String(),
APIResources: []metav1.APIResource{
{
Name: "certificatesigningrequests",
Kind: "CertificateSigningRequest",
},
},
},
},
expectedV1: false,
expectedV1beta1: true,
},
}
for _, c := range cases {
fakeClient := fake.NewSimpleClientset()
fakeClient.Resources = c.apiResources
v1Supported, v1beta1Supported, err := IsCSRSupported(fakeClient)
assert.Equal(t, c.expectedV1, v1Supported)
assert.Equal(t, c.expectedV1beta1, v1beta1Supported)
assert.Equal(t, c.expectedError, err)
}
}
29 changes: 29 additions & 0 deletions pkg/utils/csr_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import (
"time"

certificatesv1 "k8s.io/api/certificates/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/discovery/cached/memory"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/restmapper"
"k8s.io/klog/v2"
"open-cluster-management.io/addon-framework/pkg/agent"
addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
Expand Down Expand Up @@ -178,3 +182,28 @@ func UnionCSRApprover(approvers ...agent.CSRApproveFunc) agent.CSRApproveFunc {
return true
}
}

// IsCSRSupported checks whether the cluster supports v1 or v1beta1 csr api.
func IsCSRSupported(nativeClient kubernetes.Interface) (bool, bool, error) {
mapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(nativeClient.Discovery()))
mappings, err := mapper.RESTMappings(schema.GroupKind{
Group: certificatesv1.GroupName,
Kind: "CertificateSigningRequest",
})
if err != nil {
return false, false, err
}
v1CSRSupported := false
for _, mapping := range mappings {
if mapping.GroupVersionKind.Version == "v1" {
v1CSRSupported = true
}
}
v1beta1CSRSupported := false
for _, mapping := range mappings {
if mapping.GroupVersionKind.Version == "v1beta1" {
v1beta1CSRSupported = true
}
}
return v1CSRSupported, v1beta1CSRSupported, nil
}
Loading

0 comments on commit f2fc48e

Please sign in to comment.