csr rewrite

This commit is contained in:
ston1th 2020-11-01 00:01:57 +01:00
commit 954b5c0d61
8 changed files with 430 additions and 280 deletions

View file

@ -8,17 +8,98 @@ import (
pve "git.giftfish.de/ston1th/pve-go"
//"k8s.io/client-go/kubernetes/typed/certificates/v1"
"github.com/go-logr/logr"
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
typedcertificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
"k8s.io/client-go/tools/record"
"k8s.io/kubernetes/pkg/apis/certificates"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
)
var ErrNoKubeletServingCSR = errors.New("CSR is no kubelet serving certificate")
type CSRReconciler struct {
client.Client
Recorder record.EventRecorder
Log logr.Logger
Scheme *runtime.Scheme
PVEClient *pve.Client
CSRClient *typedcertificatesv1beta1.CertificatesV1beta1Client
}
func (r *CSRReconciler) SetupWithManager(mgr ctrl.Manager, options controller.Options) error {
return ctrl.NewControllerManagedBy(mgr).
WithOptions(options).
For(&certificatesv1beta1.CertificateSigningRequest{}).
Complete(r)
}
func (r *CSRReconciler) Reconcile(req ctrl.Request) (res ctrl.Result, err error) {
ctx := context.Background()
log := r.Log
csr := &certificatesv1beta1.CertificateSigningRequest{}
if err = r.Get(ctx, req.NamespacedName, csr); err != nil {
if apierrors.IsNotFound(err) {
err = nil
return
}
return
}
if !csr.DeletionTimestamp.IsZero() {
return
}
err = r.approve(ctx, log, csr)
return
}
var conditionv1beta1 = certificatesv1beta1.CertificateSigningRequestCondition{
Type: certificatesv1beta1.CertificateApproved,
Reason: "AutoApproved",
Message: "Auto approving kubelet client certificate in PVE Cluster",
}
func (r *CSRReconciler) approve(ctx context.Context, log logr.Logger, request *certificatesv1beta1.CertificateSigningRequest) error {
if len(request.Status.Conditions) > 0 {
return nil
}
client := r.CSRClient.CertificateSigningRequests()
err := checkCSR(ctx, r.PVEClient, request)
if err == ErrNoKubeletServingCSR {
return nil
}
if err != nil {
return err
}
for {
if len(request.Status.Conditions) > 0 {
return nil
}
request.Status.Conditions = append(request.Status.Conditions, conditionv1beta1)
// Submit the updated CSR.
if _, err := client.UpdateApproval(ctx, request, metav1.UpdateOptions{}); err != nil {
if strings.Contains(err.Error(), "the object has been modified") {
// The CSR might have been updated by a third-party, retry until we
// succeed.
request, err = client.Get(ctx, request.ObjectMeta.Name, metav1.GetOptions{})
if err != nil {
return err
}
continue
}
return err
}
log.Info("csr approval successful", "name", request.ObjectMeta.Name)
return nil
}
}
func checkCSR(ctx context.Context, pveClient *pve.Client, request *certificatesv1beta1.CertificateSigningRequest) error {
req, err := certificates.ParseCSR(request.Spec.Request)
if err != nil {
@ -85,76 +166,3 @@ func checkCSR(ctx context.Context, pveClient *pve.Client, request *certificatesv
}
return nil
}
var conditionv1beta1 = certificatesv1beta1.CertificateSigningRequestCondition{
Type: certificatesv1beta1.CertificateApproved,
Reason: "AutoApproved",
Message: "Auto approving kubelet client certificate in PVE Cluster",
}
func ApproveV1beta1(log logr.Logger, pveClient *pve.Client, client v1beta1.CertificateSigningRequestInterface, request *certificatesv1beta1.CertificateSigningRequest) error {
if len(request.Status.Conditions) > 0 {
return nil
}
ctx := context.Background()
err := checkCSR(ctx, pveClient, request)
if err == ErrNoKubeletServingCSR {
return nil
}
if err != nil {
return err
}
for {
if len(request.Status.Conditions) > 0 {
return nil
}
request.Status.Conditions = append(request.Status.Conditions, conditionv1beta1)
// Submit the updated CSR.
if _, err := client.UpdateApproval(ctx, request, metav1.UpdateOptions{}); err != nil {
if strings.Contains(err.Error(), "the object has been modified") {
// The CSR might have been updated by a third-party, retry until we
// succeed.
request, err = client.Get(ctx, request.ObjectMeta.Name, metav1.GetOptions{})
if err != nil {
return err
}
continue
}
return err
}
log.Info("csr approval successful", "name", request.ObjectMeta.Name)
return nil
}
}
//func ApproveV1(pveClient *pve.Client, client v1.CertificateSigningRequestInterface, request *certificates.CertificateSigningRequest) error {
// if len(request.Status.Conditions) > 0 {
// return nil
// }
// err := checkCSR(pveClient, request)
// if err != nil {
// return err
// }
//
// for {
// if len(request.Status.Conditions) > 0 {
// return nil
// }
// request.Status.Conditions = append(request.Status.Conditions, condition)
// // Submit the updated CSR.
// if _, err := client.UpdateApproval(request); err != nil {
// if strings.Contains(err.Error(), "the object has been modified") {
// // The CSR might have been updated by a third-party, retry until we
// // succeed.
// request, err = client.Get(request.ObjectMeta.Name)
// if err != nil {
// return err
// }
// continue
// }
// return err
// }
// return nil
// }
//}

View file

@ -13,7 +13,10 @@ limitations under the License.
package pvecloud
import (
"encoding/json"
"errors"
"io"
"io/ioutil"
pve "git.giftfish.de/ston1th/pve-go"
cloudprovider "k8s.io/cloud-provider"
@ -21,34 +24,49 @@ import (
const (
providerName = pve.PVEScheme
scheme = providerName + "://"
scheme = pve.PVESchemeURL
)
type cloud struct {
client *pve.Client
instances cloudprovider.Instances
instancesV2 cloudprovider.InstancesV2
//zones cloudprovider.Zones
//routes cloudprovider.Routes
//network string
}
func newCloud(_ io.Reader) (cloudprovider.Interface, error) {
opts, err := pve.ClientOptionsFromEnv()
if err != nil {
return nil, err
func newCloud(config io.Reader) (c cloudprovider.Interface, err error) {
var opts []pve.ClientOption
buf, _ := ioutil.ReadAll(config)
if len(buf) != 0 {
var cfg pve.Config
err = json.Unmarshal(buf, &cfg)
if err != nil {
return
}
opts, err = pve.ClientOptionsFromConfig(cfg)
if err != nil {
return
}
} else {
opts, err = pve.ClientOptionsFromEnv()
if err != nil {
return
}
}
if len(opts) == 0 {
err = errors.New("missing pve config")
return
}
client := pve.NewClient(opts...)
return &cloud{
c = &cloud{
client: client,
instances: newInstances(client),
instancesV2: newInstancesV2(client),
//zones: newZones(client, nodeName),
//routes: nil,
//network: network,
}, nil
}
return
}
func (c *cloud) Initialize(clientBuilder cloudprovider.ControllerClientBuilder, stop <-chan struct{}) {
@ -63,7 +81,6 @@ func (c *cloud) InstancesV2() (cloudprovider.InstancesV2, bool) {
}
func (c *cloud) Zones() (cloudprovider.Zones, bool) {
//return c.zones, true
return nil, false
}
@ -77,17 +94,6 @@ func (c *cloud) Clusters() (cloudprovider.Clusters, bool) {
func (c *cloud) Routes() (cloudprovider.Routes, bool) {
return nil, false
/*
if len(c.network) > 0 {
r, err := newRoutes(c.client, c.network)
if err != nil {
return nil, false
}
return r, true
}
return nil, false // If no network is configured, disable the routes part
*/
}
func (c *cloud) ProviderName() string {