diff --git a/go.mod b/go.mod index bcd5a0c..08c459b 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,8 @@ require ( github.com/KimMachineGun/automemlimit v0.6.1 github.com/argoproj/argo-rollouts v1.6.4 github.com/aws/aws-sdk-go v1.47.7 + github.com/aws/karpenter v0.32.0 + github.com/aws/karpenter-core v0.32.0 github.com/fsnotify/fsnotify v1.6.0 github.com/go-resty/resty/v2 v2.7.0 github.com/golang/mock v1.6.0 @@ -58,6 +60,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -72,7 +75,7 @@ require ( github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.4.0 // indirect - go.uber.org/zap v1.26.0 // indirect + go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/oauth2 v0.13.0 // indirect golang.org/x/sys v0.18.0 // indirect @@ -87,6 +90,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.120.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + knative.dev/pkg v0.0.0-20231010144348-ca8c009405dd // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.3.0 // indirect diff --git a/go.sum b/go.sum index 189b546..04c04fc 100644 --- a/go.sum +++ b/go.sum @@ -46,11 +46,25 @@ github.com/DataDog/extendeddaemonset v0.9.0-rc.3 h1:jlf40dnVG069YsjU4SfV3UUvgFdF github.com/DataDog/extendeddaemonset v0.9.0-rc.3/go.mod h1:ZuADIM2ye3GSLokHyPi/BGhyhvHSCjvDHU3BPXHr8Ow= github.com/KimMachineGun/automemlimit v0.6.1 h1:ILa9j1onAAMadBsyyUJv5cack8Y1WT26yLj/V+ulKp8= github.com/KimMachineGun/automemlimit v0.6.1/go.mod h1:T7xYht7B8r6AG/AqFcUdc7fzd2bIdBKmepfP2S1svPY= +github.com/Pallinder/go-randomdata v1.2.0 h1:DZ41wBchNRb/0GfsePLiSwb0PHZmT67XY00lCDlaYPg= +github.com/Pallinder/go-randomdata v1.2.0/go.mod h1:yHmJgulpD2Nfrm0cR9tI/+oAgRqCQQixsA8HyRZfV9Y= github.com/argoproj/argo-rollouts v1.6.4 h1:mPa08VDNNk1/1Tq7I4QvWe5p+eDaBzVFVo1TmBpHk1I= github.com/argoproj/argo-rollouts v1.6.4/go.mod h1:X2kTiBaYCSounmw1kmONdIZTwJNzNQYC0SrXUgSw9UI= +github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= +github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-sdk-go v1.47.7 h1:Y1J7g48WAzO4dYGQELbWJ57rASV8G7rd4u9hDB+AevU= github.com/aws/aws-sdk-go v1.47.7/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/karpenter v0.32.0 h1:rR3lyTcZwU1hwjOIZcB8NWfSTyi63Kh20IX2M1SUwHw= +github.com/aws/karpenter v0.32.0/go.mod h1:+1Bnj2ml6In03y/nA62SWRuNetEGNRqetfH8YxGv6D8= +github.com/aws/karpenter-core v0.32.0 h1:a0zR9TSpgpUeOUxGEkSNhMYsMOQOHWVRAkmG3tQR86E= +github.com/aws/karpenter-core v0.32.0/go.mod h1:RNih2g6qCiah8rFaZ7HkmClIK66Hjj38z3DbWnWGM2w= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= +github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -81,6 +95,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= +github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -174,8 +190,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ= +github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= @@ -220,6 +236,10 @@ github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamh github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= +github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -230,12 +250,14 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= @@ -247,7 +269,15 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= 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/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= @@ -346,6 +376,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -527,6 +559,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -646,10 +680,18 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.28.9 h1:E7VEXXCAlSrp+08zq4zgd+ko6Ttu0Mw+XoXlIkDTVW0= k8s.io/api v0.28.9/go.mod h1:AnCsDYf3SHjfa8mPG5LGYf+iF4mie+3peLQR51MMCgw= +k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08= +k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc= k8s.io/apimachinery v0.28.9 h1:aXz4Zxsw+Pk4KhBerAtKRxNN1uSMWKfciL/iOdBfXvA= k8s.io/apimachinery v0.28.9/go.mod h1:zUG757HaKs6Dc3iGtKjzIpBfqTM4yiRsEe3/E7NX15o= k8s.io/client-go v0.28.9 h1:mmMvejwc/KDjMLmDpyaxkWNzlWRCJ6ht7Qsbsnwn39Y= k8s.io/client-go v0.28.9/go.mod h1:GFDy3rUNId++WGrr0hRaBrs+y1eZz5JtVZODEalhRMo= +k8s.io/cloud-provider v0.28.3 h1:9u+JjA3zIn0nqLOOa8tWnprFkffguSAhfBvo8p7LhBQ= +k8s.io/cloud-provider v0.28.3/go.mod h1:shAJxdrKu+SwwGUhkodxByPjaH8KBFZqXo6jU1F0ehI= +k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI= +k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8= +k8s.io/csi-translation-lib v0.28.3 h1:7deV+HZjV418AGikSDPW8dyzTpm4K3tNbQUp3KmR7cs= +k8s.io/csi-translation-lib v0.28.3/go.mod h1:zlrYwakCz2yji9/8EaJk+afIKPrYXPNXXLDO8DVuuTk= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= @@ -658,6 +700,8 @@ k8s.io/metrics v0.28.9 h1:3TAJhF1GzYK89bE1RLqDinTXAlCnI8UgciwfpKHzKfg= k8s.io/metrics v0.28.9/go.mod h1:7Hn16jtdxc2Q6Vm73QK7nF7HiLJvomLgN7lEQs8SONs= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +knative.dev/pkg v0.0.0-20231010144348-ca8c009405dd h1:KJXBX9dOmRTUWduHg1gnWtPGIEl+GMh8UHdrBEZgOXE= +knative.dev/pkg v0.0.0-20231010144348-ca8c009405dd/go.mod h1:36cYnaOVHkzmhgybmYX6zDaTl3PakFeJQJl7wi6/RLE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/internal/services/controller/controller.go b/internal/services/controller/controller.go index 4ceff75..0f4939a 100644 --- a/internal/services/controller/controller.go +++ b/internal/services/controller/controller.go @@ -13,6 +13,10 @@ import ( datadoghqv1alpha1 "github.com/DataDog/extendeddaemonset/api/v1alpha1" argorollouts "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" + karpenterCoreAlpha "github.com/aws/karpenter-core/pkg/apis/v1alpha5" + karpenterCore "github.com/aws/karpenter-core/pkg/apis/v1beta1" + karpenterAlpha "github.com/aws/karpenter/pkg/apis/v1alpha1" + karpenter "github.com/aws/karpenter/pkg/apis/v1beta1" "github.com/samber/lo" "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" @@ -26,7 +30,6 @@ import ( rbacv1 "k8s.io/api/rbac/v1" storagev1 "k8s.io/api/storage/v1" 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" @@ -51,7 +54,6 @@ import ( "castai-agent/internal/services/controller/handlers/transformers" "castai-agent/internal/services/controller/handlers/transformers/annotations" custominformers "castai-agent/internal/services/controller/informers" - "castai-agent/internal/services/controller/knowngv" "castai-agent/internal/services/memorypressure" "castai-agent/internal/services/providers/types" "castai-agent/internal/services/version" @@ -93,9 +95,7 @@ type Controller struct { type conditionalInformer struct { // if empty it means all namespaces namespace string - groupVersion schema.GroupVersion - resource string - kind string + resource schema.GroupVersionResource apiType reflect.Type informerFactory func() cache.SharedIndexInformer permissionVerbs []string @@ -104,11 +104,10 @@ type conditionalInformer struct { } func (i *conditionalInformer) Name() string { - resourceString := i.groupVersion.WithResource(i.resource).String() if i.namespace != "" { - return fmt.Sprintf("Namespace:%s %s", i.namespace, resourceString) + return fmt.Sprintf("Namespace:%s %s", i.namespace, i.resource.String()) } - return resourceString + return i.resource.String() } func CollectSingleSnapshot(ctx context.Context, @@ -398,7 +397,7 @@ func startConditionalInformers(ctx context.Context, log.Warnf("Error when getting server resources: %v", err.Error()) resourcesInError := extractGroupVersionsFromApiResourceError(log, err) for i, informer := range conditionalInformers { - conditionalInformers[i].isResourceInError = resourcesInError[informer.groupVersion] + conditionalInformers[i].isResourceInError = resourcesInError[informer.resource.GroupVersion()] } } log.Infof("Cluster API server is available, trying to start conditional informers") @@ -409,8 +408,8 @@ func startConditionalInformers(ctx context.Context, conditionalInformers[i].isResourceInError = false continue } - apiResourceListForGroupVersion := getAPIResourceListByGroupVersion(informer.groupVersion.String(), apiResourceLists) - if !isResourceAvailable(informer.kind, apiResourceListForGroupVersion) { + apiResourceListForGroupVersion := getAPIResourceListByGroupVersion(informer.resource.GroupVersion().String(), apiResourceLists) + if !isResourceAvailable(informer.apiType, apiResourceListForGroupVersion) { log.Infof("Skipping conditional informer name: %v, because API resource is not available", informer.Name(), ) @@ -427,9 +426,8 @@ func startConditionalInformers(ctx context.Context, log.Infof("Starting conditional informer for %v", informer.Name()) conditionalInformers[i].isApplied = true - name := fmt.Sprintf("%s::%s", informer.groupVersion.String(), informer.kind) handledInformer := custominformers.NewHandledInformer(log, queue, informer.informerFactory(), informer.apiType, nil, additionalTransformers...) - handledInformers[name] = handledInformer + handledInformers[informer.apiType.String()] = handledInformer go handledInformer.Run(ctx.Done()) } @@ -579,12 +577,12 @@ func (c *Controller) debugQueueContent(maxItems int) string { func informerHasAccess(ctx context.Context, informer conditionalInformer, selfSubjectAccessReview authorizationtypev1.SelfSubjectAccessReviewInterface, log logrus.FieldLogger) bool { // Check if allowed to access all resources with the wildcard "*" verb - if access := informerIsAllowedToAccessResource(ctx, informer.namespace, "*", informer, informer.groupVersion.Group, selfSubjectAccessReview, log); access.Status.Allowed { + if access := informerIsAllowedToAccessResource(ctx, informer.namespace, "*", informer, informer.resource.Group, selfSubjectAccessReview, log); access.Status.Allowed { return true } for _, verb := range informer.permissionVerbs { - access := informerIsAllowedToAccessResource(ctx, informer.namespace, verb, informer, informer.groupVersion.Group, selfSubjectAccessReview, log) + access := informerIsAllowedToAccessResource(ctx, informer.namespace, verb, informer, informer.resource.Group, selfSubjectAccessReview, log) if !access.Status.Allowed { return false } @@ -599,7 +597,7 @@ func informerIsAllowedToAccessResource(ctx context.Context, namespace, verb stri Namespace: namespace, Verb: verb, Group: groupName, - Resource: informer.resource, + Resource: informer.resource.Resource, }, }, }, metav1.CreateOptions{}) @@ -692,9 +690,7 @@ func extractGroupVersionsFromApiResourceError(log logrus.FieldLogger, err error) func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Controller, f informers.SharedInformerFactory, df dynamicinformer.DynamicSharedInformerFactory, metricsClient versioned.Interface, logger logrus.FieldLogger) []conditionalInformer { conditionalInformers := []conditionalInformer{ { - groupVersion: policyv1.SchemeGroupVersion, - resource: "poddisruptionbudgets", - kind: "PodDisruptionBudget", + resource: policyv1.SchemeGroupVersion.WithResource("poddisruptionbudgets"), apiType: reflect.TypeOf(&policyv1.PodDisruptionBudget{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -702,9 +698,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: storagev1.SchemeGroupVersion, - resource: "csinodes", - kind: "CSINode", + resource: storagev1.SchemeGroupVersion.WithResource("csinodes"), apiType: reflect.TypeOf(&storagev1.CSINode{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -712,9 +706,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: autoscalingv1.SchemeGroupVersion, - resource: "horizontalpodautoscalers", - kind: "HorizontalPodAutoscaler", + resource: autoscalingv1.SchemeGroupVersion.WithResource("horizontalpodautoscalers"), apiType: reflect.TypeOf(&autoscalingv1.HorizontalPodAutoscaler{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -722,69 +714,55 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: knowngv.KarpenterCoreV1Alpha5, - resource: "provisioners", - kind: "Provisioner", - apiType: reflect.TypeOf(&unstructured.Unstructured{}), + resource: karpenterCoreAlpha.SchemeGroupVersion.WithResource("provisioners"), + apiType: reflect.TypeOf(&karpenterCoreAlpha.Provisioner{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { - return df.ForResource(knowngv.KarpenterCoreV1Alpha5.WithResource("provisioners")).Informer() + return df.ForResource(karpenterCoreAlpha.SchemeGroupVersion.WithResource("provisioners")).Informer() }, }, { - groupVersion: knowngv.KarpenterCoreV1Alpha5, - resource: "machines", - kind: "Machine", - apiType: reflect.TypeOf(&unstructured.Unstructured{}), + resource: karpenterCoreAlpha.SchemeGroupVersion.WithResource("machines"), + apiType: reflect.TypeOf(&karpenterCoreAlpha.Machine{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { - return df.ForResource(knowngv.KarpenterCoreV1Alpha5.WithResource("machines")).Informer() + return df.ForResource(karpenterCoreAlpha.SchemeGroupVersion.WithResource("machines")).Informer() }, }, { - groupVersion: knowngv.KarpenterV1Alpha1, - resource: "awsnodetemplates", - kind: "AWSNodeTemplate", - apiType: reflect.TypeOf(&unstructured.Unstructured{}), + resource: karpenterAlpha.SchemeGroupVersion.WithResource("awsnodetemplates"), + apiType: reflect.TypeOf(&karpenterAlpha.AWSNodeTemplate{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { - return df.ForResource(knowngv.KarpenterV1Alpha1.WithResource("awsnodetemplates")).Informer() + return df.ForResource(karpenterAlpha.SchemeGroupVersion.WithResource("awsnodetemplates")).Informer() }, }, { - groupVersion: knowngv.KarpenterCoreV1Beta1, - resource: "nodepools", - kind: "NodePool", - apiType: reflect.TypeOf(&unstructured.Unstructured{}), + resource: karpenterCore.SchemeGroupVersion.WithResource("nodepools"), + apiType: reflect.TypeOf(&karpenterCore.NodePool{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { - return df.ForResource(knowngv.KarpenterCoreV1Beta1.WithResource("nodepools")).Informer() + return df.ForResource(karpenterCore.SchemeGroupVersion.WithResource("nodepools")).Informer() }, }, { - groupVersion: knowngv.KarpenterCoreV1Beta1, - resource: "nodeclaims", - kind: "NodeClaim", - apiType: reflect.TypeOf(&unstructured.Unstructured{}), + resource: karpenterCore.SchemeGroupVersion.WithResource("nodeclaims"), + apiType: reflect.TypeOf(&karpenterCore.NodeClaim{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { - return df.ForResource(knowngv.KarpenterCoreV1Beta1.WithResource("nodeclaims")).Informer() + return df.ForResource(karpenterCore.SchemeGroupVersion.WithResource("nodeclaims")).Informer() }, }, { - groupVersion: knowngv.KarpenterV1Beta1, - resource: "ec2nodeclasses", - kind: "EC2NodeClass", - apiType: reflect.TypeOf(&unstructured.Unstructured{}), + resource: karpenter.SchemeGroupVersion.WithResource("ec2nodeclasses"), + apiType: reflect.TypeOf(&karpenter.EC2NodeClass{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { - return df.ForResource(knowngv.KarpenterV1Beta1.WithResource("ec2nodeclasses")).Informer() + return df.ForResource(karpenter.SchemeGroupVersion.WithResource("ec2nodeclasses")).Informer() }, }, { - groupVersion: datadoghqv1alpha1.GroupVersion, - resource: "extendeddaemonsetreplicasets", - kind: "ExtendedDaemonSetReplicaSet", + resource: datadoghqv1alpha1.GroupVersion.WithResource("extendeddaemonsetreplicasets"), apiType: reflect.TypeOf(&datadoghqv1alpha1.ExtendedDaemonSetReplicaSet{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -792,9 +770,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: v1beta1.SchemeGroupVersion, - resource: "pods", - kind: "Pod", + resource: v1beta1.SchemeGroupVersion.WithResource("pods"), apiType: reflect.TypeOf(&v1beta1.PodMetrics{}), permissionVerbs: []string{"get", "list"}, informerFactory: func() cache.SharedIndexInformer { @@ -802,9 +778,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: argorollouts.RolloutGVR.GroupVersion(), - resource: argorollouts.RolloutGVR.Resource, - kind: "Rollout", + resource: argorollouts.RolloutGVR, apiType: reflect.TypeOf(&argorollouts.Rollout{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -812,9 +786,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: crd.RecommendationGVR.GroupVersion(), - resource: crd.RecommendationGVR.Resource, - kind: "Recommendation", + resource: crd.RecommendationGVR, apiType: reflect.TypeOf(&crd.Recommendation{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -822,9 +794,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: networkingv1.SchemeGroupVersion, - resource: "ingresses", - kind: "Ingress", + resource: networkingv1.SchemeGroupVersion.WithResource("ingresses"), apiType: reflect.TypeOf(&networkingv1.Ingress{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -832,9 +802,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: networkingv1.SchemeGroupVersion, - resource: "networkpolicies", - kind: "NetworkPolicy", + resource: networkingv1.SchemeGroupVersion.WithResource("networkpolicies"), apiType: reflect.TypeOf(&networkingv1.NetworkPolicy{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -842,9 +810,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: rbacv1.SchemeGroupVersion, - resource: "roles", - kind: "Role", + resource: rbacv1.SchemeGroupVersion.WithResource("roles"), apiType: reflect.TypeOf(&rbacv1.Role{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -852,9 +818,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: rbacv1.SchemeGroupVersion, - resource: "rolebindings", - kind: "RoleBinding", + resource: rbacv1.SchemeGroupVersion.WithResource("rolebindings"), apiType: reflect.TypeOf(&rbacv1.RoleBinding{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -862,9 +826,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: rbacv1.SchemeGroupVersion, - resource: "clusterroles", - kind: "ClusterRole", + resource: rbacv1.SchemeGroupVersion.WithResource("clusterroles"), apiType: reflect.TypeOf(&rbacv1.ClusterRole{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -872,9 +834,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control }, }, { - groupVersion: rbacv1.SchemeGroupVersion, - resource: "clusterrolebindings", - kind: "ClusterRoleBinding", + resource: rbacv1.SchemeGroupVersion.WithResource("clusterrolebindings"), apiType: reflect.TypeOf(&rbacv1.ClusterRoleBinding{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -886,9 +846,7 @@ func getConditionalInformers(clientset kubernetes.Interface, cfg *config.Control for _, cmNamespace := range cfg.ConfigMapNamespaces { conditionalInformers = append(conditionalInformers, conditionalInformer{ namespace: cmNamespace, - groupVersion: corev1.SchemeGroupVersion, - resource: "configmaps", - kind: "ConfigMap", + resource: corev1.SchemeGroupVersion.WithResource("configmaps"), apiType: reflect.TypeOf(&corev1.ConfigMap{}), permissionVerbs: []string{"get", "list", "watch"}, informerFactory: func() cache.SharedIndexInformer { @@ -967,12 +925,14 @@ func getAPIResourceListByGroupVersion(groupVersion string, apiResourceLists []*m return apiResourceList } } + // return empty list if not found return &metav1.APIResourceList{} } -func isResourceAvailable(kind string, apiResourceList *metav1.APIResourceList) bool { +func isResourceAvailable(kind reflect.Type, apiResourceList *metav1.APIResourceList) bool { for _, apiResource := range apiResourceList.APIResources { - if kind == apiResource.Kind { + // apiResource.Kind is, ex.: "PodMetrics", while kind.String() is, ex.: "*v1.PodMetrics" + if strings.Contains(kind.String(), apiResource.Kind) { return true } } diff --git a/internal/services/controller/controller_test.go b/internal/services/controller/controller_test.go index 3594efe..da8b28b 100644 --- a/internal/services/controller/controller_test.go +++ b/internal/services/controller/controller_test.go @@ -13,6 +13,10 @@ import ( datadoghqv1alpha1 "github.com/DataDog/extendeddaemonset/api/v1alpha1" argorollouts "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" + karpenterCoreAlpha "github.com/aws/karpenter-core/pkg/apis/v1alpha5" + karpenterCore "github.com/aws/karpenter-core/pkg/apis/v1beta1" + karpenterAlpha "github.com/aws/karpenter/pkg/apis/v1alpha1" + karpenter "github.com/aws/karpenter/pkg/apis/v1beta1" "github.com/golang/mock/gomock" "github.com/google/uuid" "github.com/samber/lo" @@ -45,7 +49,6 @@ import ( "castai-agent/internal/config" "castai-agent/internal/services/controller/crd" "castai-agent/internal/services/controller/delta" - "castai-agent/internal/services/controller/knowngv" mock_discovery "castai-agent/internal/services/controller/mock/discovery" mock_types "castai-agent/internal/services/providers/types/mock" mock_version "castai-agent/internal/services/version/mock" @@ -64,7 +67,7 @@ type sampleObject struct { GV schema.GroupVersion Kind string Resource string - Data []byte + Data *json.RawMessage } func TestMain(m *testing.M) { @@ -99,6 +102,10 @@ func TestController_ShouldReceiveDeltasBasedOnAvailableResources(t *testing.T) { for name, tt := range tests { t.Run(name, func(t *testing.T) { scheme := runtime.NewScheme() + utilruntime.Must(karpenterCoreAlpha.SchemeBuilder.AddToScheme(scheme)) + utilruntime.Must(karpenterAlpha.SchemeBuilder.AddToScheme(scheme)) + utilruntime.Must(karpenterCore.SchemeBuilder.AddToScheme(scheme)) + utilruntime.Must(karpenter.SchemeBuilder.AddToScheme(scheme)) utilruntime.Must(datadoghqv1alpha1.SchemeBuilder.AddToScheme(scheme)) utilruntime.Must(argorollouts.SchemeBuilder.AddToScheme(scheme)) utilruntime.Must(crd.SchemeBuilder.AddToScheme(scheme)) @@ -177,7 +184,7 @@ func TestController_ShouldReceiveDeltasBasedOnAvailableResources(t *testing.T) { }) require.True(t, found) require.NotNil(t, actual.Data) - require.JSONEq(t, string(expected.Data), string(*actual.Data)) + require.JSONEq(t, string(*expected.Data), string(*actual.Data)) } return nil @@ -547,12 +554,12 @@ func TestController_ShouldKeepDeltaAfterDelete(t *testing.T) { } func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObject, *fake.Clientset, *dynamic_fake.FakeDynamicClient) { - provisionersGvr := knowngv.KarpenterCoreV1Alpha5.WithResource("provisioners") - machinesGvr := knowngv.KarpenterCoreV1Alpha5.WithResource("machines") - awsNodeTemplatesGvr := knowngv.KarpenterV1Alpha1.WithResource("awsnodetemplates") - nodePoolsGvr := knowngv.KarpenterCoreV1Beta1.WithResource("nodepools") - nodeClaimsGvr := knowngv.KarpenterCoreV1Beta1.WithResource("nodeclaims") - ec2NodeClassesGvr := knowngv.KarpenterV1Beta1.WithResource("ec2nodeclasses") + provisionersGvr := karpenterCoreAlpha.SchemeGroupVersion.WithResource("provisioners") + machinesGvr := karpenterCoreAlpha.SchemeGroupVersion.WithResource("machines") + awsNodeTemplatesGvr := karpenterAlpha.SchemeGroupVersion.WithResource("awsnodetemplates") + nodePoolsGvr := karpenterCore.SchemeGroupVersion.WithResource("nodepools") + nodeClaimsGvr := karpenterCore.SchemeGroupVersion.WithResource("nodeclaims") + ec2NodeClassesGvr := karpenter.SchemeGroupVersion.WithResource("ec2nodeclasses") datadogExtendedDSReplicaSetsGvr := datadoghqv1alpha1.GroupVersion.WithResource("extendeddaemonsetreplicasets") node := &v1.Node{ @@ -566,7 +573,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj } expectedNode := node.DeepCopy() expectedNode.Labels[labels.CastaiFakeSpot] = "true" - nodeData := asJson(t, expectedNode) + nodeData, err := delta.Encode(expectedNode) + require.NoError(t, err) pod := &v1.Pod{ TypeMeta: metav1.TypeMeta{ @@ -577,7 +585,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Namespace: v1.NamespaceDefault, Name: "pod1", }, } - podData := asJson(t, pod) + podData, err := delta.Encode(pod) + require.NoError(t, err) cfgMap := &v1.ConfigMap{ TypeMeta: metav1.TypeMeta{ @@ -592,7 +601,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj "field1": "value1", }, } - cfgMapData := asJson(t, cfgMap) + cfgMapData, err := delta.Encode(cfgMap) + require.NoError(t, err) pdb := &policyv1.PodDisruptionBudget{ TypeMeta: metav1.TypeMeta{ @@ -604,7 +614,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Namespace: v1.NamespaceDefault, }, } - pdbData := asJson(t, pdb) + pdbData, err := delta.Encode(pdb) + require.NoError(t, err) hpa := &autoscalingv1.HorizontalPodAutoscaler{ TypeMeta: metav1.TypeMeta{ @@ -616,7 +627,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Namespace: v1.NamespaceDefault, }, } - hpaData := asJson(t, hpa) + hpaData, err := delta.Encode(hpa) + require.NoError(t, err) csi := &storagev1.CSINode{ TypeMeta: metav1.TypeMeta{ @@ -628,61 +640,92 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Namespace: v1.NamespaceDefault, }, } - csiData := asJson(t, csi) - - provisionersData := []byte(`{ - "kind": "Provisioner", - "apiVersion": "karpenter.sh/v1alpha5", - "metadata": { - "name": "provisioner", - "namespace": "default" - } - }`) - - machinesData := []byte(`{ - "kind": "Machine", - "apiVersion": "karpenter.sh/v1alpha5", - "metadata": { - "name": "machine", - "namespace": "default" - } - }`) - - awsNodeTemplatesData := []byte(`{ - "kind": "AWSNodeTemplate", - "apiVersion": "karpenter.k8s.aws/v1alpha1", - "metadata": { - "name": "awsnodetemplate", - "namespace": "default" - } - }`) - - nodePoolsData := []byte(`{ - "kind": "NodePool", - "apiVersion": "karpenter.sh/v1beta1", - "metadata": { - "name": "nodepool", - "namespace": "default" - } - }`) - - nodeClaimsData := []byte(`{ - "kind": "NodeClaim", - "apiVersion": "karpenter.sh/v1beta1", - "metadata": { - "name": "nodeclaim", - "namespace": "default" - } - }`) - - ec2NodeClassesData := []byte(`{ - "kind": "EC2NodeClass", - "apiVersion": "karpenter.k8s.aws/v1beta1", - "metadata": { - "name": "ec2nodeclass", - "namespace": "default" - } - }`) + csiData, err := delta.Encode(csi) + require.NoError(t, err) + + provisioners := &karpenterCoreAlpha.Provisioner{ + TypeMeta: metav1.TypeMeta{ + Kind: "Provisioner", + APIVersion: provisionersGvr.GroupVersion().String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: provisionersGvr.Resource, + Namespace: v1.NamespaceDefault, + }, + } + + provisionersData, err := delta.Encode(provisioners) + require.NoError(t, err) + + machines := &karpenterCoreAlpha.Machine{ + TypeMeta: metav1.TypeMeta{ + Kind: "Machine", + APIVersion: machinesGvr.GroupVersion().String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: machinesGvr.Resource, + Namespace: v1.NamespaceDefault, + }, + } + + machinesData, err := delta.Encode(machines) + require.NoError(t, err) + + awsNodeTemplates := &karpenterAlpha.AWSNodeTemplate{ + TypeMeta: metav1.TypeMeta{ + Kind: "AWSNodeTemplate", + APIVersion: awsNodeTemplatesGvr.GroupVersion().String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: awsNodeTemplatesGvr.Resource, + Namespace: v1.NamespaceDefault, + }, + } + + awsNodeTemplatesData, err := delta.Encode(awsNodeTemplates) + require.NoError(t, err) + + nodePools := &karpenterCore.NodePool{ + TypeMeta: metav1.TypeMeta{ + Kind: "NodePool", + APIVersion: nodePoolsGvr.GroupVersion().String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: nodePoolsGvr.Resource, + Namespace: v1.NamespaceDefault, + }, + } + + nodePoolsData, err := delta.Encode(nodePools) + require.NoError(t, err) + + nodeClaims := &karpenterCore.NodeClaim{ + TypeMeta: metav1.TypeMeta{ + Kind: "NodeClaim", + APIVersion: nodeClaimsGvr.GroupVersion().String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: nodeClaimsGvr.Resource, + Namespace: v1.NamespaceDefault, + }, + } + + nodeClaimsData, err := delta.Encode(nodeClaims) + require.NoError(t, err) + + ec2NodeClasses := &karpenter.EC2NodeClass{ + TypeMeta: metav1.TypeMeta{ + Kind: "EC2NodeClass", + APIVersion: ec2NodeClassesGvr.GroupVersion().String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: ec2NodeClassesGvr.Resource, + Namespace: v1.NamespaceDefault, + }, + } + + ec2NodeClassesData, err := delta.Encode(ec2NodeClasses) + require.NoError(t, err) datadogExtendedDSReplicaSet := &datadoghqv1alpha1.ExtendedDaemonSetReplicaSet{ TypeMeta: metav1.TypeMeta{ @@ -695,7 +738,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj }, } - datadogExtendedDSReplicaSetData := asJson(t, datadogExtendedDSReplicaSet) + datadogExtendedDSReplicaSetData, err := delta.Encode(datadogExtendedDSReplicaSet) + require.NoError(t, err) rollout := &argorollouts.Rollout{ TypeMeta: metav1.TypeMeta{ @@ -708,7 +752,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj }, } - rolloutData := asJson(t, rollout) + rolloutData, err := delta.Encode(rollout) + require.NoError(t, err) recommendation := &crd.Recommendation{ TypeMeta: metav1.TypeMeta{ @@ -721,7 +766,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj }, } - recommendationData := asJson(t, recommendation) + recommendationData, err := delta.Encode(recommendation) + require.NoError(t, err) ingress := &networkingv1.Ingress{ TypeMeta: metav1.TypeMeta{ @@ -733,7 +779,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Name: "ingress", }, } - ingressData := asJson(t, ingress) + ingressData, err := delta.Encode(ingress) + require.NoError(t, err) netpolicy := &networkingv1.NetworkPolicy{ TypeMeta: metav1.TypeMeta{ @@ -745,7 +792,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Name: "netpolicy", }, } - netpolicyData := asJson(t, netpolicy) + netpolicyData, err := delta.Encode(netpolicy) + require.NoError(t, err) role := &rbacv1.Role{ TypeMeta: metav1.TypeMeta{ @@ -757,7 +805,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Name: "role", }, } - roleData := asJson(t, role) + roleData, err := delta.Encode(role) + require.NoError(t, err) roleBinding := &rbacv1.RoleBinding{ TypeMeta: metav1.TypeMeta{ @@ -769,7 +818,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Name: "rolebinding", }, } - roleBindingData := asJson(t, roleBinding) + roleBindingData, err := delta.Encode(roleBinding) + require.NoError(t, err) clusterRole := &rbacv1.ClusterRole{ TypeMeta: metav1.TypeMeta{ @@ -781,7 +831,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Name: "clusterrole", }, } - clusterRoleData := asJson(t, clusterRole) + clusterRoleData, err := delta.Encode(clusterRole) + require.NoError(t, err) clusterRoleBinding := &rbacv1.ClusterRoleBinding{ TypeMeta: metav1.TypeMeta{ @@ -793,7 +844,8 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Name: "clusterrolebinding", }, } - clusterRoleBindingData := asJson(t, clusterRoleBinding) + clusterRoleBindingData, err := delta.Encode(clusterRoleBinding) + require.NoError(t, err) clientset := fake.NewSimpleClientset( node, @@ -809,18 +861,7 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj clusterRole, clusterRoleBinding, ) - runtimeObjects := []runtime.Object{ - unstructuredFromJson(t, provisionersData), - unstructuredFromJson(t, machinesData), - unstructuredFromJson(t, awsNodeTemplatesData), - unstructuredFromJson(t, nodePoolsData), - unstructuredFromJson(t, nodeClaimsData), - unstructuredFromJson(t, ec2NodeClassesData), - datadogExtendedDSReplicaSet, - rollout, - recommendation, - } - dynamicClient := dynamic_fake.NewSimpleDynamicClient(scheme, runtimeObjects...) + dynamicClient := dynamic_fake.NewSimpleDynamicClient(scheme, provisioners, machines, awsNodeTemplates, nodePools, nodeClaims, ec2NodeClasses, datadogExtendedDSReplicaSet, rollout, recommendation) clientset.Fake.Resources = []*metav1.APIResourceList{ { GroupVersion: autoscalingv1.SchemeGroupVersion.String(), @@ -873,14 +914,17 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Group: provisionersGvr.Group, Name: provisionersGvr.Resource, Version: provisionersGvr.Version, - Kind: "Provisioner", Verbs: []string{"get", "list", "watch"}, }, + }, + }, + { + GroupVersion: machinesGvr.GroupVersion().String(), + APIResources: []metav1.APIResource{ { Group: machinesGvr.Group, Name: machinesGvr.Resource, Version: machinesGvr.Version, - Kind: "Machine", Verbs: []string{"get", "list", "watch"}, }, }, @@ -892,7 +936,6 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Group: awsNodeTemplatesGvr.Group, Name: awsNodeTemplatesGvr.Resource, Version: awsNodeTemplatesGvr.Version, - Kind: "AWSNodeTemplate", Verbs: []string{"get", "list", "watch"}, }, }, @@ -904,14 +947,17 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Group: nodePoolsGvr.Group, Name: nodePoolsGvr.Resource, Version: nodePoolsGvr.Version, - Kind: "NodePool", Verbs: []string{"get", "list", "watch"}, }, + }, + }, + { + GroupVersion: nodeClaimsGvr.GroupVersion().String(), + APIResources: []metav1.APIResource{ { Group: nodeClaimsGvr.Group, Name: nodeClaimsGvr.Resource, Version: nodeClaimsGvr.Version, - Kind: "NodeClaim", Verbs: []string{"get", "list", "watch"}, }, }, @@ -923,7 +969,6 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Group: ec2NodeClassesGvr.Group, Name: ec2NodeClassesGvr.Resource, Version: ec2NodeClassesGvr.Version, - Kind: "EC2NodeClass", Verbs: []string{"get", "list", "watch"}, }, }, @@ -935,7 +980,6 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Group: datadogExtendedDSReplicaSetsGvr.Group, Name: datadogExtendedDSReplicaSetsGvr.Resource, Version: datadogExtendedDSReplicaSetsGvr.Version, - Kind: "ExtendedDaemonSetReplicaSet", Verbs: []string{"get", "list", "watch"}, }, }, @@ -947,7 +991,6 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Group: argorollouts.RolloutGVR.Group, Name: argorollouts.RolloutGVR.Resource, Version: argorollouts.RolloutGVR.Version, - Kind: "Rollout", Verbs: []string{"get", "list", "watch"}, }, }, @@ -959,7 +1002,6 @@ func loadInitialHappyPathData(t *testing.T, scheme *runtime.Scheme) ([]sampleObj Group: crd.RecommendationGVR.Group, Name: crd.RecommendationGVR.Resource, Version: crd.RecommendationGVR.Version, - Kind: "Recommendation", Verbs: []string{"get", "list", "watch"}, }, }, @@ -1260,25 +1302,12 @@ func TestCollectSingleSnapshot(t *testing.T) { r.ElementsMatch(objs, pods) } -func unstructuredFromJson(t *testing.T, data []byte) *unstructured.Unstructured { - var out unstructured.Unstructured - err := json.Unmarshal(data, &out) - require.NoError(t, err) - return &out -} - -func asJson(t *testing.T, obj interface{}) []byte { - data, err := json.Marshal(obj) - require.NoError(t, err) - return data -} - func verifySampleObjectsAreValid(t *testing.T, objects []sampleObject) { for _, obj := range objects { require.NotNil(t, obj.Data) var data unstructured.Unstructured - err := json.Unmarshal(obj.Data, &data) + err := json.Unmarshal(*obj.Data, &data) require.NoError(t, err) gvk := data.GroupVersionKind() diff --git a/internal/services/controller/knowngv/constants.go b/internal/services/controller/knowngv/constants.go deleted file mode 100644 index 8e9b1a7..0000000 --- a/internal/services/controller/knowngv/constants.go +++ /dev/null @@ -1,11 +0,0 @@ -package knowngv - -import "k8s.io/apimachinery/pkg/runtime/schema" - -// We hard-code these values to avoid unnecessary third-party dependencies. -var ( - KarpenterCoreV1Alpha5 = schema.GroupVersion{Group: "karpenter.sh", Version: "v1alpha5"} - KarpenterCoreV1Beta1 = schema.GroupVersion{Group: "karpenter.sh", Version: "v1beta1"} - KarpenterV1Alpha1 = schema.GroupVersion{Group: "karpenter.k8s.aws", Version: "v1alpha1"} - KarpenterV1Beta1 = schema.GroupVersion{Group: "karpenter.k8s.aws", Version: "v1beta1"} -) diff --git a/internal/services/controller/scheme/register.go b/internal/services/controller/scheme/register.go index 2c64a8e..937a2fa 100644 --- a/internal/services/controller/scheme/register.go +++ b/internal/services/controller/scheme/register.go @@ -3,6 +3,10 @@ package scheme import ( datadoghqv1alpha1 "github.com/DataDog/extendeddaemonset/api/v1alpha1" argorollouts "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" + karpenterCoreAlpha "github.com/aws/karpenter-core/pkg/apis/v1alpha5" + karpenterCore "github.com/aws/karpenter-core/pkg/apis/v1beta1" + karpenterAlpha "github.com/aws/karpenter/pkg/apis/v1alpha1" + karpenter "github.com/aws/karpenter/pkg/apis/v1beta1" appsv1 "k8s.io/api/apps/v1" autoscalingv1 "k8s.io/api/autoscaling/v1" batchv1 "k8s.io/api/batch/v1" @@ -27,6 +31,10 @@ var builder = runtime.SchemeBuilder{ autoscalingv1.AddToScheme, v1beta1.AddToScheme, policyv1.AddToScheme, + karpenterCoreAlpha.SchemeBuilder.AddToScheme, + karpenterAlpha.SchemeBuilder.AddToScheme, + karpenterCore.SchemeBuilder.AddToScheme, + karpenter.SchemeBuilder.AddToScheme, datadoghqv1alpha1.SchemeBuilder.AddToScheme, argorollouts.SchemeBuilder.AddToScheme, crd.AddToScheme,