diff --git a/cmd/agent.go b/cmd/agent.go index b5487e6a..54e69742 100644 --- a/cmd/agent.go +++ b/cmd/agent.go @@ -34,7 +34,7 @@ func runAgent(opt *options, config *rest.Config, ctx context.Context, k8sClient os.Exit(1) } - sr, err := service.NewServiceReconciler(mgr.GetClient(), config, r, opt.restoreNamespace) + sr, err := service.NewServiceReconciler(ctx, mgr.GetClient(), config, r, opt.restoreNamespace) if err != nil { setupLog.Error(err, "unable to create service reconciler") os.Exit(1) diff --git a/go.mod b/go.mod index 7b153f79..7c94fc63 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/pluralsh/console-client-go v0.5.6 github.com/pluralsh/controller-reconcile-helper v0.0.4 github.com/pluralsh/gophoenix v0.1.3-0.20231201014135-dff1b4309e34 - github.com/pluralsh/polly v0.1.8 + github.com/pluralsh/polly v0.1.9 github.com/samber/lo v1.39.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 diff --git a/go.sum b/go.sum index 88f1d883..bd76feca 100644 --- a/go.sum +++ b/go.sum @@ -532,8 +532,8 @@ github.com/pluralsh/controller-reconcile-helper v0.0.4 h1:1o+7qYSyoeqKFjx+WgQTxD github.com/pluralsh/controller-reconcile-helper v0.0.4/go.mod h1:AfY0gtteD6veBjmB6jiRx/aR4yevEf6K0M13/pGan/s= github.com/pluralsh/gophoenix v0.1.3-0.20231201014135-dff1b4309e34 h1:ab2PN+6if/Aq3/sJM0AVdy1SYuMAnq4g20VaKhTm/Bw= github.com/pluralsh/gophoenix v0.1.3-0.20231201014135-dff1b4309e34/go.mod h1:IagWXKFYu6NTHzcJx2dJyrIlZ1Sv2PH3fhOtplA9qOs= -github.com/pluralsh/polly v0.1.8 h1:fkF5fLNofN4CyOs89lQfKeZaSXgRe8MnXz9VK5MzvRU= -github.com/pluralsh/polly v0.1.8/go.mod h1:W9IBX3e3xEjJuRjAQRfFJpH+UkNjddVY5YjMhyisQqQ= +github.com/pluralsh/polly v0.1.9 h1:x968ohGfOtX/YwNbZBPCvRPFhQglvYZ33KLf4Yt/5q0= +github.com/pluralsh/polly v0.1.9/go.mod h1:W9IBX3e3xEjJuRjAQRfFJpH+UkNjddVY5YjMhyisQqQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= diff --git a/pkg/controller/service/reconciler.go b/pkg/controller/service/reconciler.go index 8e9cb532..feba3bf6 100644 --- a/pkg/controller/service/reconciler.go +++ b/pkg/controller/service/reconciler.go @@ -8,11 +8,22 @@ import ( console "github.com/pluralsh/console-client-go" clienterrors "github.com/pluralsh/deployment-operator/internal/errors" + "github.com/pluralsh/deployment-operator/internal/utils" + "github.com/pluralsh/deployment-operator/pkg/applier" + "github.com/pluralsh/deployment-operator/pkg/client" "github.com/pluralsh/deployment-operator/pkg/controller" + plrlerrors "github.com/pluralsh/deployment-operator/pkg/errors" + "github.com/pluralsh/deployment-operator/pkg/manifests" + manis "github.com/pluralsh/deployment-operator/pkg/manifests" + "github.com/pluralsh/deployment-operator/pkg/manifests/template" + "github.com/pluralsh/deployment-operator/pkg/ping" + "github.com/pluralsh/deployment-operator/pkg/websocket" "github.com/pluralsh/polly/algorithms" "github.com/samber/lo" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/discovery" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -23,15 +34,6 @@ import ( "sigs.k8s.io/cli-utils/pkg/inventory" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" - - "github.com/pluralsh/deployment-operator/internal/utils" - "github.com/pluralsh/deployment-operator/pkg/applier" - "github.com/pluralsh/deployment-operator/pkg/client" - plrlerrors "github.com/pluralsh/deployment-operator/pkg/errors" - "github.com/pluralsh/deployment-operator/pkg/manifests" - manis "github.com/pluralsh/deployment-operator/pkg/manifests" - "github.com/pluralsh/deployment-operator/pkg/ping" - "github.com/pluralsh/deployment-operator/pkg/websocket" ) func init() { @@ -67,7 +69,8 @@ type ServiceReconciler struct { pinger *ping.Pinger } -func NewServiceReconciler(consoleClient client.Client, config *rest.Config, refresh time.Duration, restoreNamespace string) (*ServiceReconciler, error) { +func NewServiceReconciler(ctx context.Context, consoleClient client.Client, config *rest.Config, refresh time.Duration, restoreNamespace string) (*ServiceReconciler, error) { + logger := log.FromContext(ctx) utils.DisableClientLimits(config) _, deployToken := consoleClient.GetCredentials() @@ -103,6 +106,19 @@ func NewServiceReconciler(consoleClient client.Client, config *rest.Config, refr if err != nil { return nil, err } + if err := CapabilitiesAPIVersions(discoveryClient); err != nil { + return nil, err + } + + go func() { + //nolint:all + _ = wait.PollImmediateInfinite(time.Minute*5, func() (done bool, err error) { + if err := CapabilitiesAPIVersions(discoveryClient); err != nil { + logger.Error(err, "can't fetch API versions") + } + return false, nil + }) + }() return &ServiceReconciler{ ConsoleClient: consoleClient, @@ -120,6 +136,29 @@ func NewServiceReconciler(consoleClient client.Client, config *rest.Config, refr }, nil } +func CapabilitiesAPIVersions(discoveryClient *discovery.DiscoveryClient) error { + lists, err := discoveryClient.ServerPreferredResources() + if err != nil { + return err + } + for _, list := range lists { + if len(list.APIResources) == 0 { + continue + } + gv, err := schema.ParseGroupVersion(list.GroupVersion) + if err != nil { + continue + } + for _, resource := range list.APIResources { + if len(resource.Verbs) == 0 { + continue + } + template.APIVersions.Set(fmt.Sprintf("%s/%s", gv.String(), resource.Kind), true) + } + } + return nil +} + func (s *ServiceReconciler) GetPublisher() (string, websocket.Publisher) { return "service.event", &socketPublisher{ svcQueue: s.SvcQueue, diff --git a/pkg/manifests/template/helm.go b/pkg/manifests/template/helm.go index 15348792..ee12f466 100644 --- a/pkg/manifests/template/helm.go +++ b/pkg/manifests/template/helm.go @@ -13,10 +13,12 @@ import ( "time" "github.com/gofrs/flock" + cmap "github.com/orcaman/concurrent-map/v2" "github.com/pkg/errors" console "github.com/pluralsh/console-client-go" "github.com/pluralsh/polly/algorithms" "github.com/pluralsh/polly/fs" + "github.com/samber/lo" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart/loader" @@ -30,8 +32,6 @@ import ( "k8s.io/client-go/util/homedir" "k8s.io/kubectl/pkg/cmd/util" "sigs.k8s.io/yaml" - - "github.com/samber/lo" ) const ( @@ -55,11 +55,13 @@ func init() { settings.RepositoryCache = dir settings.RepositoryConfig = path.Join(dir, "repositories.yaml") settings.KubeInsecureSkipTLSVerify = true + APIVersions = cmap.New[bool]() } var settings = cli.New() var EnableHelmDependencyUpdate bool var DisableHelmTemplateDryRunServer bool +var APIVersions cmap.ConcurrentMap[string, bool] func debug(format string, v ...interface{}) { format = fmt.Sprintf("INFO: %s\n", format) @@ -228,6 +230,7 @@ func (h *helm) templateHelm(conf *action.Configuration, release, namespace strin return nil, err } client.KubeVersion = vsn + client.APIVersions = algorithms.MapKeys[string, bool](APIVersions.Items()) return client.Run(chart, values) }