updated to latest k8s version

This commit is contained in:
ston1th 2021-09-19 17:20:43 +02:00
commit bbbd20b5f2
12 changed files with 668 additions and 525 deletions

View file

@ -1,17 +0,0 @@
FROM golang:alpine as builder
RUN adduser -D -g 65532 -u 65532 appuser
RUN mkdir /build
WORKDIR /build
COPY go.mod go.mod
COPY go.sum go.sum
COPY cmd/pve-cloud-controller-manager/main.go main.go
COPY pvecloud/ pvecloud/
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -trimpath -gcflags 'all=-e' -ldflags "-s -w" -o manager main.go
RUN apk add --no-cache ca-certificates
FROM scratch
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/ssl/cert.pem /etc/ssl/cert.pem
COPY --from=builder /build/manager /manager
# appuser
USER 65532
ENTRYPOINT ["/manager"]

View file

@ -4,6 +4,7 @@ CONTROLLER_NAME ?= pve-cloud-controller-manager
APPROVER_NAME ?= pve-csr-approver-manager APPROVER_NAME ?= pve-csr-approver-manager
CONTROLLER_IMG ?= $(REGISTRY)/$(CONTROLLER_NAME) CONTROLLER_IMG ?= $(REGISTRY)/$(CONTROLLER_NAME)
APPROVER_IMG ?= $(REGISTRY)/$(APPROVER_NAME) APPROVER_IMG ?= $(REGISTRY)/$(APPROVER_NAME)
LDFLAGS ?= -s -w
TAG ?= dev TAG ?= dev
ARCH ?= amd64 ARCH ?= amd64

View file

@ -1,19 +1,3 @@
/*
Copyright 2016 The Kubernetes 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.
*/
// The external controller manager is responsible for running controller loops that
// are cloud provider dependent. It uses the API to listen to new events on resources.
package main package main
import ( import (
@ -21,22 +5,66 @@ import (
"os" "os"
"time" "time"
_ "git.giftfish.de/ston1th/cloud-controller-manager-pve/pkg/pvecloud" "git.giftfish.de/ston1th/cloud-controller-manager-pve/pkg/pvecloud"
"k8s.io/apimachinery/pkg/util/wait"
cloudprovider "k8s.io/cloud-provider"
"k8s.io/cloud-provider/app"
"k8s.io/cloud-provider/app/config"
"k8s.io/cloud-provider/options"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/component-base/logs" "k8s.io/component-base/logs"
"k8s.io/kubernetes/cmd/cloud-controller-manager/app" "k8s.io/klog/v2"
//_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
//_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
) )
func main() { func main() {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UTC().UnixNano())
command := app.NewCloudControllerManagerCommand()
logs.InitLogs() logs.InitLogs()
defer logs.FlushLogs() defer logs.FlushLogs()
opts, err := options.NewCloudControllerManagerOptions()
if err != nil {
klog.Fatalf("unable to initialize command options: %v", err)
}
controllerInitializers := app.DefaultInitFuncConstructors
fss := cliflag.NamedFlagSets{}
command := app.NewCloudControllerManagerCommand(opts, cloudInitializer, controllerInitializers, fss, wait.NeverStop)
if err := command.Execute(); err != nil { if err := command.Execute(); err != nil {
os.Exit(1) os.Exit(1)
} }
} }
func cloudInitializer(config *config.CompletedConfig) cloudprovider.Interface {
cloudConfig := config.ComponentConfig.KubeCloudShared.CloudProvider
providerName := cloudConfig.Name
if providerName == "" {
providerName = pvecloud.ProviderName
}
if providerName != pvecloud.ProviderName {
klog.Fatalf("unknown cloud provider %s, only 'pvecloud' is supported", providerName)
}
// initialize cloud provider with the cloud provider name and config file provided
cloud, err := cloudprovider.InitCloudProvider(providerName, cloudConfig.CloudConfigFile)
if err != nil {
klog.Fatalf("Cloud provider could not be initialized: %v", err)
}
if cloud == nil {
klog.Fatalf("Cloud provider is nil")
}
if !cloud.HasClusterID() {
if config.ComponentConfig.KubeCloudShared.AllowUntaggedCloud {
klog.Warning("detected a cluster without a ClusterID. A ClusterID will be required in the future. Please tag your cluster to avoid any future issues")
} else {
klog.Fatalf("no ClusterID found. A ClusterID is required for the cloud provider to function properly. This check can be bypassed by setting the allow-untagged-cloud option")
}
}
return cloud
}

View file

@ -11,9 +11,9 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme" clientgoscheme "k8s.io/client-go/kubernetes/scheme"
typedcertificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" typedcertificatesv1 "k8s.io/client-go/kubernetes/typed/certificates/v1"
"k8s.io/klog/klogr"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/klog/v2/klogr"
ctrl "sigs.k8s.io/controller-runtime" ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/healthz"
@ -123,7 +123,7 @@ func main() {
Log: ctrl.Log.WithName("approver"), Log: ctrl.Log.WithName("approver"),
Scheme: mgr.GetScheme(), Scheme: mgr.GetScheme(),
PVEClient: pveClient, PVEClient: pveClient,
CSRClient: typedcertificatesv1beta1.NewForConfigOrDie(rcfg), CSRClient: typedcertificatesv1.NewForConfigOrDie(rcfg),
}).SetupWithManager(mgr, controller.Options{MaxConcurrentReconciles: csrConcurrency}); err != nil { }).SetupWithManager(mgr, controller.Options{MaxConcurrentReconciles: csrConcurrency}); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "approver") setupLog.Error(err, "unable to create controller", "controller", "approver")
os.Exit(1) os.Exit(1)

130
go.mod
View file

@ -1,48 +1,104 @@
module git.giftfish.de/ston1th/cloud-controller-manager-pve module git.giftfish.de/ston1th/cloud-controller-manager-pve
go 1.13 go 1.17
require ( require (
git.giftfish.de/ston1th/haproxy-lb v0.0.0-20210410004255-5de98614da2a git.giftfish.de/ston1th/haproxy-lb v0.0.0-20210410004255-5de98614da2a
git.giftfish.de/ston1th/pve-go v0.0.0-20210417175627-04bbde74ad96 git.giftfish.de/ston1th/pve-go v0.0.0-20210417175627-04bbde74ad96
github.com/go-logr/logr v0.4.0 github.com/go-logr/logr v0.4.0
github.com/google/uuid v1.1.2 // indirect github.com/google/uuid v1.1.2 // indirect
github.com/stretchr/testify v1.5.1 // indirect google.golang.org/protobuf v1.26.0 // indirect
google.golang.org/protobuf v1.25.0 // indirect k8s.io/api v0.22.1
k8s.io/api v0.19.3 k8s.io/apimachinery v0.22.1
k8s.io/apimachinery v0.19.3 k8s.io/client-go v0.22.1
k8s.io/client-go v0.19.3 k8s.io/cloud-provider v0.22.1
k8s.io/cloud-provider v0.19.3 k8s.io/component-base v0.22.1
k8s.io/component-base v0.19.3 k8s.io/klog/v2 v2.9.0
k8s.io/klog v1.0.0 sigs.k8s.io/controller-runtime v0.9.6
k8s.io/klog/v2 v2.6.0
k8s.io/kubernetes v1.19.3
sigs.k8s.io/controller-runtime v0.6.3
) )
replace ( require (
google.golang.org/grpc => google.golang.org/grpc v1.29.1 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
k8s.io/api => k8s.io/api v0.19.3 github.com/NYTimes/gziphandler v1.1.1 // indirect
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.19.3 github.com/PuerkitoBio/purell v1.1.1 // indirect
k8s.io/apimachinery => k8s.io/apimachinery v0.19.3 github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
k8s.io/apiserver => k8s.io/apiserver v0.19.3 github.com/beorn7/perks v1.0.1 // indirect
k8s.io/cli-runtime => k8s.io/cli-runtime v0.19.3 github.com/blang/semver v3.5.1+incompatible // indirect
k8s.io/client-go => k8s.io/client-go v0.19.3 github.com/cespare/xxhash/v2 v2.1.1 // indirect
k8s.io/cloud-provider => k8s.io/cloud-provider v0.19.3 github.com/coreos/go-semver v0.3.0 // indirect
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.19.3 github.com/coreos/go-systemd/v22 v22.3.2 // indirect
k8s.io/code-generator => k8s.io/code-generator v0.19.3 github.com/davecgh/go-spew v1.1.1 // indirect
k8s.io/component-base => k8s.io/component-base v0.19.3 github.com/emicklei/go-restful v2.9.5+incompatible // indirect
k8s.io/cri-api => k8s.io/cri-api v0.19.3 github.com/evanphx/json-patch v4.11.0+incompatible // indirect
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.19.3 github.com/felixge/httpsnoop v1.0.1 // indirect
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.19.3 github.com/fsnotify/fsnotify v1.4.9 // indirect
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.19.3 github.com/go-openapi/jsonpointer v0.19.5 // indirect
k8s.io/kube-proxy => k8s.io/kube-proxy v0.19.3 github.com/go-openapi/jsonreference v0.19.5 // indirect
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.19.3 github.com/go-openapi/swag v0.19.14 // indirect
k8s.io/kubectl => k8s.io/kubectl v0.19.3 github.com/gogo/protobuf v1.3.2 // indirect
k8s.io/kubelet => k8s.io/kubelet v0.19.3 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.19.3 github.com/golang/protobuf v1.5.2 // indirect
k8s.io/metrics => k8s.io/metrics v0.19.3 github.com/google/go-cmp v0.5.5 // indirect
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.19.3 github.com/google/gofuzz v1.1.0 // indirect
k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.19.3 github.com/googleapis/gnostic v0.5.5 // indirect
k8s.io/sample-controller => k8s.io/sample-controller v0.19.3 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.11 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.11.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/spf13/cobra v1.1.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.etcd.io/etcd/api/v3 v3.5.0 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.0 // indirect
go.etcd.io/etcd/client/v3 v3.5.0 // indirect
go.opentelemetry.io/contrib v0.20.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 // indirect
go.opentelemetry.io/otel v0.20.0 // indirect
go.opentelemetry.io/otel/exporters/otlp v0.20.0 // indirect
go.opentelemetry.io/otel/metric v0.20.0 // indirect
go.opentelemetry.io/otel/sdk v0.20.0 // indirect
go.opentelemetry.io/otel/sdk/export/metric v0.20.0 // indirect
go.opentelemetry.io/otel/sdk/metric v0.20.0 // indirect
go.opentelemetry.io/otel/trace v0.20.0 // indirect
go.opentelemetry.io/proto/otlp v0.7.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.18.1 // indirect
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
golang.org/x/text v0.3.6 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect
google.golang.org/grpc v1.38.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/apiextensions-apiserver v0.21.3 // indirect
k8s.io/apiserver v0.22.1 // indirect
k8s.io/controller-manager v0.22.1 // indirect
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e // indirect
k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
) )

804
go.sum

File diff suppressed because it is too large Load diff

View file

@ -1,14 +1,16 @@
FROM golang:alpine as builder FROM golang:1.17.1-alpine3.14 as builder
RUN adduser -D -g 65532 -u 65532 appuser ARG ARCH
RUN mkdir /build ARG LDFLAGS
RUN adduser -D -g 65532 -u 65532 appuser \
&& mkdir /build \
&& apk add --no-cache ca-certificates
WORKDIR /build WORKDIR /build
COPY go.mod go.mod COPY go.mod go.mod
COPY go.sum go.sum COPY go.sum go.sum
RUN go mod download RUN go mod download
COPY cmd/pve-cloud-controller-manager/main.go main.go COPY cmd/pve-cloud-controller-manager/main.go main.go
COPY pkg/pvecloud/ pkg/pvecloud/ COPY pkg/pvecloud/ pkg/pvecloud/
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -trimpath -gcflags 'all=-e' -ldflags "-s -w" -o pve-cloud-controller main.go RUN CGO_ENABLED=0 GOOS=linux GOARCH=$ARCH GO111MODULE=on go build -trimpath -gcflags 'all=-e' -ldflags "$LDFLAGS" -o pve-cloud-controller main.go
RUN apk add --no-cache ca-certificates
FROM scratch FROM scratch
COPY --from=builder /etc/passwd /etc/passwd COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/ssl/cert.pem /etc/ssl/cert.pem COPY --from=builder /etc/ssl/cert.pem /etc/ssl/cert.pem

View file

@ -1,14 +1,16 @@
FROM golang:alpine as builder FROM golang:1.17.1-alpine3.14 as builder
RUN adduser -D -g 65532 -u 65532 appuser ARG ARCH
RUN mkdir /build ARG LDFLAGS
RUN adduser -D -g 65532 -u 65532 appuser \
&& mkdir /build \
&& apk add --no-cache ca-certificates
WORKDIR /build WORKDIR /build
COPY go.mod go.mod COPY go.mod go.mod
COPY go.sum go.sum COPY go.sum go.sum
RUN go mod download RUN go mod download
COPY cmd/pve-csr-approver-manager/main.go main.go COPY cmd/pve-csr-approver-manager/main.go main.go
COPY pkg/approver/ pkg/approver COPY pkg/approver/ pkg/approver
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -trimpath -gcflags 'all=-e' -ldflags "-s -w" -o pve-csr-approver main.go RUN CGO_ENABLED=0 GOOS=linux GOARCH=$ARCH GO111MODULE=on go build -trimpath -gcflags 'all=-e' -ldflags "$LDFLAGS" -o pve-csr-approver main.go
RUN apk add --no-cache ca-certificates
FROM scratch FROM scratch
COPY --from=builder /etc/passwd /etc/passwd COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/ssl/cert.pem /etc/ssl/cert.pem COPY --from=builder /etc/ssl/cert.pem /etc/ssl/cert.pem

View file

@ -9,13 +9,12 @@ import (
pve "git.giftfish.de/ston1th/pve-go" pve "git.giftfish.de/ston1th/pve-go"
"github.com/go-logr/logr" "github.com/go-logr/logr"
certificatesv1beta1 "k8s.io/api/certificates/v1beta1" certificatesv1 "k8s.io/api/certificates/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
typedcertificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" typedcertificatesv1 "k8s.io/client-go/kubernetes/typed/certificates/v1"
"k8s.io/kubernetes/pkg/apis/certificates"
ctrl "sigs.k8s.io/controller-runtime" ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/controller"
@ -28,20 +27,19 @@ type CSRReconciler struct {
Log logr.Logger Log logr.Logger
Scheme *runtime.Scheme Scheme *runtime.Scheme
PVEClient *pve.Client PVEClient *pve.Client
CSRClient *typedcertificatesv1beta1.CertificatesV1beta1Client CSRClient *typedcertificatesv1.CertificatesV1Client
} }
func (r *CSRReconciler) SetupWithManager(mgr ctrl.Manager, options controller.Options) error { func (r *CSRReconciler) SetupWithManager(mgr ctrl.Manager, options controller.Options) error {
return ctrl.NewControllerManagedBy(mgr). return ctrl.NewControllerManagedBy(mgr).
WithOptions(options). WithOptions(options).
For(&certificatesv1beta1.CertificateSigningRequest{}). For(&certificatesv1.CertificateSigningRequest{}).
Complete(r) Complete(r)
} }
func (r *CSRReconciler) Reconcile(req ctrl.Request) (res ctrl.Result, err error) { func (r *CSRReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, err error) {
ctx := context.Background()
log := r.Log log := r.Log
csr := &certificatesv1beta1.CertificateSigningRequest{} csr := &certificatesv1.CertificateSigningRequest{}
if err = r.Get(ctx, req.NamespacedName, csr); err != nil { if err = r.Get(ctx, req.NamespacedName, csr); err != nil {
if apierrors.IsNotFound(err) { if apierrors.IsNotFound(err) {
err = nil err = nil
@ -56,13 +54,13 @@ func (r *CSRReconciler) Reconcile(req ctrl.Request) (res ctrl.Result, err error)
return return
} }
var conditionv1beta1 = certificatesv1beta1.CertificateSigningRequestCondition{ var conditionv1 = certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1beta1.CertificateApproved, Type: certificatesv1.CertificateApproved,
Reason: "AutoApproved", Reason: "AutoApproved",
Message: "Auto approving kubelet client certificate in PVE Cluster", Message: "Auto approving kubelet client certificate in PVE Cluster",
} }
func (r *CSRReconciler) approve(ctx context.Context, log logr.Logger, request *certificatesv1beta1.CertificateSigningRequest) error { func (r *CSRReconciler) approve(ctx context.Context, log logr.Logger, request *certificatesv1.CertificateSigningRequest) error {
if len(request.Status.Conditions) > 0 { if len(request.Status.Conditions) > 0 {
return nil return nil
} }
@ -79,9 +77,9 @@ func (r *CSRReconciler) approve(ctx context.Context, log logr.Logger, request *c
if len(request.Status.Conditions) > 0 { if len(request.Status.Conditions) > 0 {
return nil return nil
} }
request.Status.Conditions = append(request.Status.Conditions, conditionv1beta1) request.Status.Conditions = append(request.Status.Conditions, conditionv1)
// Submit the updated CSR. // Submit the updated CSR.
if _, err := client.UpdateApproval(ctx, request, metav1.UpdateOptions{}); err != nil { if _, err := client.UpdateApproval(ctx, request.Name, request, metav1.UpdateOptions{}); err != nil {
if strings.Contains(err.Error(), "the object has been modified") { if strings.Contains(err.Error(), "the object has been modified") {
// The CSR might have been updated by a third-party, retry until we // The CSR might have been updated by a third-party, retry until we
// succeed. // succeed.
@ -98,8 +96,8 @@ func (r *CSRReconciler) approve(ctx context.Context, log logr.Logger, request *c
} }
} }
func checkCSR(ctx context.Context, pveClient *pve.Client, request *certificatesv1beta1.CertificateSigningRequest) error { func checkCSR(ctx context.Context, pveClient *pve.Client, request *certificatesv1.CertificateSigningRequest) error {
req, err := certificates.ParseCSR(request.Spec.Request) req, err := ParseCSR(request.Spec.Request)
if err != nil { if err != nil {
return err return err
} }
@ -107,7 +105,7 @@ func checkCSR(ctx context.Context, pveClient *pve.Client, request *certificatesv
for i, v := range request.Spec.Usages { for i, v := range request.Spec.Usages {
usages[i] = string(v) usages[i] = string(v)
} }
if !certificates.IsKubeletServingCSR(req, sets.NewString(usages...)) { if !IsKubeletServingCSR(req, sets.NewString(usages...)) {
return ErrNoKubeletServingCSR return ErrNoKubeletServingCSR
} }
hostname := strings.TrimPrefix(req.Subject.CommonName, "system:node:") hostname := strings.TrimPrefix(req.Subject.CommonName, "system:node:")

81
pkg/approver/helper.go Normal file
View file

@ -0,0 +1,81 @@
// Copied from https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/certificates/helpers.go
// to avoid importing k8s.io/kubernetes
package approver
import (
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"reflect"
"strings"
"k8s.io/apimachinery/pkg/util/sets"
)
// ParseCSR extracts the CSR from the bytes and decodes it.
func ParseCSR(pemBytes []byte) (*x509.CertificateRequest, error) {
block, _ := pem.Decode(pemBytes)
if block == nil || block.Type != "CERTIFICATE REQUEST" {
return nil, errors.New("PEM block type must be CERTIFICATE REQUEST")
}
csr, err := x509.ParseCertificateRequest(block.Bytes)
if err != nil {
return nil, err
}
return csr, nil
}
var (
organizationNotSystemNodesErr = fmt.Errorf("subject organization is not system:nodes")
commonNameNotSystemNode = fmt.Errorf("subject common name does not begin with system:node:")
dnsOrIPSANRequiredErr = fmt.Errorf("DNS or IP subjectAltName is required")
emailSANNotAllowedErr = fmt.Errorf("Email subjectAltNames are not allowed")
uriSANNotAllowedErr = fmt.Errorf("URI subjectAltNames are not allowed")
)
type KeyUsage string
const (
UsageDigitalSignature KeyUsage = "digital signature"
UsageKeyEncipherment KeyUsage = "key encipherment"
UsageServerAuth KeyUsage = "server auth"
)
var kubeletServingRequiredUsages = sets.NewString(
string(UsageDigitalSignature),
string(UsageKeyEncipherment),
string(UsageServerAuth),
)
func IsKubeletServingCSR(req *x509.CertificateRequest, usages sets.String) bool {
return ValidateKubeletServingCSR(req, usages) == nil
}
func ValidateKubeletServingCSR(req *x509.CertificateRequest, usages sets.String) error {
if !reflect.DeepEqual([]string{"system:nodes"}, req.Subject.Organization) {
return organizationNotSystemNodesErr
}
// at least one of dnsNames or ipAddresses must be specified
if len(req.DNSNames) == 0 && len(req.IPAddresses) == 0 {
return dnsOrIPSANRequiredErr
}
if len(req.EmailAddresses) > 0 {
return emailSANNotAllowedErr
}
if len(req.URIs) > 0 {
return uriSANNotAllowedErr
}
if !kubeletServingRequiredUsages.Equal(usages) {
return fmt.Errorf("usages did not match %v", kubeletServingRequiredUsages.List())
}
if !strings.HasPrefix(req.Subject.CommonName, "system:node:") {
return commonNameNotSystemNode
}
return nil
}

View file

@ -25,7 +25,7 @@ import (
) )
const ( const (
providerName = pve.PVEScheme ProviderName = pve.PVEScheme
scheme = pve.PVESchemeURL scheme = pve.PVESchemeURL
) )
@ -125,7 +125,7 @@ func (c *cloud) Routes() (cloudprovider.Routes, bool) {
} }
func (c *cloud) ProviderName() string { func (c *cloud) ProviderName() string {
return providerName return ProviderName
} }
func (c *cloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) { func (c *cloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
@ -137,7 +137,7 @@ func (c *cloud) HasClusterID() bool {
} }
func init() { func init() {
cloudprovider.RegisterCloudProvider(providerName, func(config io.Reader) (cloudprovider.Interface, error) { cloudprovider.RegisterCloudProvider(ProviderName, func(config io.Reader) (cloudprovider.Interface, error) {
return newCloud(config) return newCloud(config)
}) })
} }

View file

@ -1,20 +0,0 @@
#!/bin/sh
set -euo pipefail
VERSION=${1#"v"}
if [ -z "$VERSION" ]; then
echo "Must specify version!"
exit 1
fi
MODS=($(
curl -sS https://raw.githubusercontent.com/kubernetes/kubernetes/v${VERSION}/go.mod |
sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p'
))
for MOD in "${MODS[@]}"; do
V=$(
go mod download -json "${MOD}@kubernetes-${VERSION}" |
sed -n 's|.*"Version": "\(.*\)".*|\1|p'
)
go mod edit "-replace=${MOD}=${MOD}@${V}"
done
go get "k8s.io/kubernetes@v${VERSION}"