mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
ad41fb8c96
Fixes an issue where CRDs were being created without schema, allowing resources with invalid content to be created, later stalling the controller ListWatch event channel when the invalid resources could not be deserialized. This also requires moving Addon GVK tracking from a status field to an annotation, as the GroupVersionKind type has special handling internal to Kubernetes that prevents it from being serialized to the CRD when schema validation is enabled. Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
92 lines
3.0 KiB
Go
92 lines
3.0 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
|
|
helmcrd "github.com/k3s-io/helm-controller/pkg/crd"
|
|
"github.com/k3s-io/helm-controller/pkg/generated/controllers/helm.cattle.io"
|
|
addoncrd "github.com/k3s-io/k3s/pkg/crd"
|
|
"github.com/k3s-io/k3s/pkg/deploy"
|
|
"github.com/k3s-io/k3s/pkg/generated/controllers/k3s.cattle.io"
|
|
"github.com/k3s-io/k3s/pkg/version"
|
|
"github.com/pkg/errors"
|
|
"github.com/rancher/wrangler/pkg/apply"
|
|
"github.com/rancher/wrangler/pkg/crd"
|
|
"github.com/rancher/wrangler/pkg/generated/controllers/apps"
|
|
"github.com/rancher/wrangler/pkg/generated/controllers/batch"
|
|
"github.com/rancher/wrangler/pkg/generated/controllers/core"
|
|
"github.com/rancher/wrangler/pkg/generated/controllers/rbac"
|
|
"github.com/rancher/wrangler/pkg/start"
|
|
"github.com/sirupsen/logrus"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
|
"k8s.io/client-go/kubernetes"
|
|
"k8s.io/client-go/rest"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
)
|
|
|
|
type Context struct {
|
|
K3s *k3s.Factory
|
|
Helm *helm.Factory
|
|
Batch *batch.Factory
|
|
Apps *apps.Factory
|
|
Auth *rbac.Factory
|
|
Core *core.Factory
|
|
K8s kubernetes.Interface
|
|
Apply apply.Apply
|
|
}
|
|
|
|
func (c *Context) Start(ctx context.Context) error {
|
|
return start.All(ctx, 5, c.K3s, c.Helm, c.Apps, c.Auth, c.Batch, c.Core)
|
|
}
|
|
|
|
func NewContext(ctx context.Context, cfg string) (*Context, error) {
|
|
restConfig, err := clientcmd.BuildConfigFromFlags("", cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Construct a custom user-agent string for the apply client used by the deploy controller
|
|
// so that we can track which node's deploy controller most recently modified a resource.
|
|
nodeName := os.Getenv("NODE_NAME")
|
|
managerName := deploy.ControllerName + "@" + nodeName
|
|
if nodeName == "" || len(managerName) > validation.FieldManagerMaxLength {
|
|
logrus.Warn("Deploy controller node name is empty or too long, and will not be tracked via server side apply field management")
|
|
managerName = deploy.ControllerName
|
|
}
|
|
restConfig.UserAgent = fmt.Sprintf("%s/%s (%s/%s) %s/%s", managerName, version.Version, runtime.GOOS, runtime.GOARCH, version.Program, version.GitCommit)
|
|
|
|
if err := crds(ctx, restConfig); err != nil {
|
|
return nil, errors.Wrap(err, "failed to register CRDs")
|
|
}
|
|
|
|
k8s, err := kubernetes.NewForConfig(restConfig)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Context{
|
|
K3s: k3s.NewFactoryFromConfigOrDie(restConfig),
|
|
Helm: helm.NewFactoryFromConfigOrDie(restConfig),
|
|
K8s: k8s,
|
|
Auth: rbac.NewFactoryFromConfigOrDie(restConfig),
|
|
Apps: apps.NewFactoryFromConfigOrDie(restConfig),
|
|
Batch: batch.NewFactoryFromConfigOrDie(restConfig),
|
|
Core: core.NewFactoryFromConfigOrDie(restConfig),
|
|
Apply: apply.New(k8s, apply.NewClientFactory(restConfig)).WithDynamicLookup(),
|
|
}, nil
|
|
}
|
|
|
|
func crds(ctx context.Context, config *rest.Config) error {
|
|
factory, err := crd.NewFactoryFromClient(config)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
types := append(helmcrd.List(), addoncrd.List()...)
|
|
factory.BatchCreateCRDs(ctx, types...)
|
|
|
|
return factory.BatchWait()
|
|
}
|