From 184974e645fadf754770e88f522fd2e095f3ccbe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:14:54 +0000 Subject: [PATCH 1/8] Bump k8s.io/metrics from 0.31.1 to 0.32.0 Bumps [k8s.io/metrics](https://github.com/kubernetes/metrics) from 0.31.1 to 0.32.0. - [Commits](https://github.com/kubernetes/metrics/compare/v0.31.1...v0.32.0) --- updated-dependencies: - dependency-name: k8s.io/metrics dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6894cd1b..32c7e23f 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( k8s.io/apimachinery v0.32.0 k8s.io/cli-runtime v0.31.1 k8s.io/client-go v0.32.0 - k8s.io/metrics v0.31.1 + k8s.io/metrics v0.32.0 sigs.k8s.io/gateway-api v1.2.0 sigs.k8s.io/yaml v1.4.0 ) diff --git a/go.sum b/go.sum index cdf1feef..af7e1f19 100644 --- a/go.sum +++ b/go.sum @@ -423,8 +423,8 @@ k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= -k8s.io/metrics v0.31.1 h1:h4I4dakgh/zKflWYAOQhwf0EXaqy8LxAIyE/GBvxqRc= -k8s.io/metrics v0.31.1/go.mod h1:JuH1S9tJiH9q1VCY0yzSCawi7kzNLsDzlWDJN4xR+iA= +k8s.io/metrics v0.32.0 h1:70qJ3ZS/9DrtH0UA0NVBI6gW2ip2GAn9e7NtoKERpns= +k8s.io/metrics v0.32.0/go.mod h1:skdg9pDjVjCPIQqmc5rBzDL4noY64ORhKu9KCPv1+QI= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/gateway-api v1.2.0 h1:LrToiFwtqKTKZcZtoQPTuo3FxhrrhTgzQG0Te+YGSo8= From 29873252d4715b50b0c08f7d9499f6c2f67e1730 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:14:54 +0000 Subject: [PATCH 2/8] Bump k8s.io/cli-runtime from 0.31.1 to 0.32.0 Bumps [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) from 0.31.1 to 0.32.0. - [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.31.1...v0.32.0) --- updated-dependencies: - dependency-name: k8s.io/cli-runtime dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 7 +++--- go.sum | 76 +++++----------------------------------------------------- 2 files changed, 9 insertions(+), 74 deletions(-) diff --git a/go.mod b/go.mod index 32c7e23f..bcdb2daa 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.32.0 k8s.io/apimachinery v0.32.0 - k8s.io/cli-runtime v0.31.1 + k8s.io/cli-runtime v0.32.0 k8s.io/client-go v0.32.0 k8s.io/metrics v0.32.0 sigs.k8s.io/gateway-api v1.2.0 @@ -114,7 +114,6 @@ require ( go.opentelemetry.io/otel v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect - go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/multierr v1.11.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect @@ -133,7 +132,7 @@ require ( k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect - sigs.k8s.io/kustomize/api v0.17.2 // indirect - sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect + sigs.k8s.io/kustomize/api v0.18.0 // indirect + sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect ) diff --git a/go.sum b/go.sum index af7e1f19..7ed3ba6b 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,9 @@ cel.dev/expr v0.16.1 h1:NR0+oFYzR1CqLFhTAqg3ql59G9VfN8fKq1TCHJ6gq1g= cel.dev/expr v0.16.1/go.mod h1:AsGA5zb3WruAEQeQng1RZdGEXmBj0jvMWh6l5SnNuC8= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= @@ -14,14 +12,10 @@ 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/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -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= github.com/cilium/cilium v1.16.5 h1:ecjhh98fl6Ki641+8Cdb0oynsy3toQ+oPLCSI3d+KLE= github.com/cilium/cilium v1.16.5/go.mod h1:EqOosPzJuv28Hz3Ulz6cCXfYKbll7vbIwMGZU5houOw= github.com/cilium/ebpf v0.15.0 h1:7NxJhNiBT3NG8pZJ3c+yfrVdHY8ScgKD27sScgjLMMk= @@ -30,7 +24,6 @@ github.com/cilium/hive v0.0.0-20240529072208-d997f86e4219 h1:iX4v9lg63iTv8x8MWUM github.com/cilium/hive v0.0.0-20240529072208-d997f86e4219/go.mod h1:6tW1eCwSq8Wz8IVtpZE0MemoCWSrEOUa8aLKotmBRCo= github.com/cilium/proxy v0.0.0-20241210133824-eaae5aca0fb9 h1:EuilS9EXYTKh2B8HXieDVMGaEf4Hleg5uA+07bt1l8c= github.com/cilium/proxy v0.0.0-20241210133824-eaae5aca0fb9/go.mod h1:58Ngk9Jkge6TzFPVEsdcUQvIhtsE5fim3NMRgfrstqo= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -44,8 +37,6 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -90,30 +81,14 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -212,7 +187,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= @@ -290,8 +264,6 @@ go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucg go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -303,41 +275,28 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/W golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -347,7 +306,6 @@ golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -357,10 +315,6 @@ golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -371,27 +325,11 @@ 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= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= google.golang.org/genproto/googleapis/api v0.0.0-20241206012308-a4fef0638583 h1:v+j+5gpj0FopU0KKLDGfDo9ZRRpKdi5UBrCP0f76kuY= google.golang.org/genproto/googleapis/api v0.0.0-20241206012308-a4fef0638583/go.mod h1:jehYqy3+AhJU9ve55aNOaSml7wUXjF9x6z2LcCfpAhY= google.golang.org/genproto/googleapis/rpc v0.0.0-20241206012308-a4fef0638583 h1:IfdSdTcLFy4lqUQrQJLkLt1PB+AsqVz6lwkWPzWEz10= google.golang.org/genproto/googleapis/rpc v0.0.0-20241206012308-a4fef0638583/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -409,14 +347,12 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= -k8s.io/cli-runtime v0.31.1 h1:/ZmKhmZ6hNqDM+yf9s3Y4KEYakNXUn5sod2LWGGwCuk= -k8s.io/cli-runtime v0.31.1/go.mod h1:pKv1cDIaq7ehWGuXQ+A//1OIF+7DI+xudXtExMCbe9U= +k8s.io/cli-runtime v0.32.0 h1:dP+OZqs7zHPpGQMCGAhectbHU2SNCuZtIimRKTv2T1c= +k8s.io/cli-runtime v0.32.0/go.mod h1:Mai8ht2+esoDRK5hr861KRy6z0zHsSTYttNVJXgP3YQ= k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= @@ -431,10 +367,10 @@ sigs.k8s.io/gateway-api v1.2.0 h1:LrToiFwtqKTKZcZtoQPTuo3FxhrrhTgzQG0Te+YGSo8= sigs.k8s.io/gateway-api v1.2.0/go.mod h1:EpNfEXNjiYfUJypf0eZ0P5iXA9ekSGWaS1WgPaM42X0= sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= -sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= -sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= -sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= +sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo= +sigs.k8s.io/kustomize/api v0.18.0/go.mod h1:f8isXnX+8b+SGLHQ6yO4JG1rdkZlvhaCf/uZbLVMb0U= +sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt4E= +sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo= sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= From c390068e14c143dafa5f20dc10631caa69f4f198 Mon Sep 17 00:00:00 2001 From: derailed Date: Sun, 17 Nov 2024 07:37:00 -0700 Subject: [PATCH 3/8] update deps --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index bcdb2daa..872e5ad9 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/stretchr/testify v1.10.0 github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/net v0.31.0 + golang.org/x/text v0.21.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.32.0 @@ -122,7 +123,6 @@ require ( golang.org/x/sync v0.10.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/term v0.27.0 // indirect - golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.7.0 // indirect google.golang.org/protobuf v1.35.2 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect From b4ac887b0b9816790de036131428ac156e74075b Mon Sep 17 00:00:00 2001 From: derailed Date: Sun, 17 Nov 2024 07:37:43 -0700 Subject: [PATCH 4/8] clean up cilium netpols --- internal/cilium/cache/cep.go | 2 +- internal/cilium/lint/ccnp.go | 30 ++++++++++++++++++------------ internal/cilium/lint/cid.go | 3 +-- internal/cilium/lint/cnp.go | 6 ++++++ 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/internal/cilium/cache/cep.go b/internal/cilium/cache/cep.go index 92b046af..72f75e19 100644 --- a/internal/cilium/cache/cep.go +++ b/internal/cilium/cache/cep.go @@ -27,7 +27,7 @@ func NewCiliumEndpoint(dba *db.DB) *CiliumEndpoint { return &CiliumEndpoint{db: dba} } -// CiliumEndpointRefs computes all CiliumEndpoints external references. +// CEPRefs computes all CiliumEndpoints external references. func (p *CiliumEndpoint) CEPRefs(refs *sync.Map) error { txn, it := p.db.MustITFor(internal.Glossary[cilium.CEP]) defer txn.Abort() diff --git a/internal/cilium/lint/ccnp.go b/internal/cilium/lint/ccnp.go index 993ede6b..cd3e5cf5 100644 --- a/internal/cilium/lint/ccnp.go +++ b/internal/cilium/lint/ccnp.go @@ -57,20 +57,18 @@ func (s *CiliumClusterwideNetworkPolicy) Lint(ctx context.Context) error { } func (s *CiliumClusterwideNetworkPolicy) checkRule(ctx context.Context, r *api.Rule) error { - if r.EndpointSelector.Size() > 0 { - if ok, err := s.checkEPSel(r.EndpointSelector); err != nil { - return err - } else if !ok { - s.AddCode(ctx, 1700, "endpoint") - } + if ok, err := s.checkEPSel(r.EndpointSelector); err != nil { + return err + } else if !ok { + s.AddCode(ctx, 1700, "endpoint") } - if r.NodeSelector.Size() > 0 { - if ok, err := s.checkNodeSel(r.NodeSelector); err != nil { - return err - } else if !ok { - s.AddCode(ctx, 1701) - } + + if ok, err := s.checkNodeSel(r.NodeSelector); err != nil { + return err + } else if !ok { + s.AddCode(ctx, 1701) } + for _, ing := range r.Ingress { for _, sel := range ing.FromEndpoints { if ok, err := s.checkEPSel(sel); err != nil { @@ -94,6 +92,10 @@ func (s *CiliumClusterwideNetworkPolicy) checkRule(ctx context.Context, r *api.R } func (s *CiliumClusterwideNetworkPolicy) checkEPSel(sel api.EndpointSelector) (bool, error) { + if sel.Size() == 0 { + return true, nil + } + mm, err := s.matchCEPsBySel(sel) if err != nil { return false, err @@ -103,6 +105,10 @@ func (s *CiliumClusterwideNetworkPolicy) checkEPSel(sel api.EndpointSelector) (b } func (s *CiliumClusterwideNetworkPolicy) checkNodeSel(sel api.EndpointSelector) (bool, error) { + if sel.Size() == 0 { + return true, nil + } + mm, err := s.matchNodesBySel(sel) if err != nil { return false, err diff --git a/internal/cilium/lint/cid.go b/internal/cilium/lint/cid.go index 04a4055e..50f178bf 100644 --- a/internal/cilium/lint/cid.go +++ b/internal/cilium/lint/cid.go @@ -61,8 +61,7 @@ func (s *CiliumIdentity) Lint(ctx context.Context) error { } func (s *CiliumIdentity) checkStale(ctx context.Context, fqn string, refs *sync.Map) error { - _, ok := refs.Load(icache.ResFqn(cache.CIDKey, fqn)) - if !ok { + if _, ok := refs.Load(icache.ResFqn(cache.CIDKey, fqn)); !ok { s.AddCode(ctx, 1600) } diff --git a/internal/cilium/lint/cnp.go b/internal/cilium/lint/cnp.go index 9a99a0c1..09a98fc2 100644 --- a/internal/cilium/lint/cnp.go +++ b/internal/cilium/lint/cnp.go @@ -88,6 +88,10 @@ func (s *CiliumNetworkPolicy) checkRule(ctx context.Context, ns string, r *api.R } func (s *CiliumNetworkPolicy) checkEPSel(ns string, sel api.EndpointSelector) (bool, error) { + if sel.Size() == 0 { + return true, nil + } + mm, err := s.matchCEPsBySel(ns, sel) if err != nil { return false, err @@ -171,6 +175,8 @@ func matchSel(labels map[string]string, e slimv1.LabelSelectorRequirement) bool func matchLabels(labels, sel map[string]string) bool { var count int + fmt.Println("LABELS", labels) + fmt.Println("SEL", sel) for k, v := range sel { k = strings.TrimPrefix(k, "any.") if v1, ok := labels[k]; ok && v == v1 { From a1a321c23b7eac07571c7d71661d78f33484c8f5 Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 30 Dec 2024 12:48:35 -0700 Subject: [PATCH 5/8] clean up --- internal/cilium/lint/cep.go | 18 +++++++++--------- internal/cilium/lint/cnp.go | 2 -- internal/client/config.go | 2 +- internal/dao/generic.go | 6 +++++- internal/dao/resource.go | 2 +- internal/scrub/cjob.go | 2 +- internal/scrub/cm.go | 2 +- internal/scrub/cr.go | 2 +- internal/scrub/crb.go | 2 +- internal/scrub/dp.go | 2 +- internal/scrub/ds.go | 2 +- internal/scrub/gw-route.go | 2 +- internal/scrub/gw.go | 2 +- internal/scrub/gwc.go | 2 +- internal/scrub/hpa.go | 2 +- internal/scrub/ing.go | 2 +- internal/scrub/job.go | 2 +- internal/scrub/no.go | 2 +- internal/scrub/np.go | 2 +- internal/scrub/ns.go | 2 +- internal/scrub/pdb.go | 2 +- internal/scrub/pod.go | 2 +- internal/scrub/pv.go | 2 +- internal/scrub/pvc.go | 2 +- internal/scrub/rb.go | 2 +- internal/scrub/ro.go | 2 +- internal/scrub/rs.go | 2 +- internal/scrub/sa.go | 2 +- internal/scrub/sec.go | 2 +- internal/scrub/sts.go | 2 +- internal/scrub/svc.go | 2 +- 31 files changed, 42 insertions(+), 40 deletions(-) diff --git a/internal/cilium/lint/cep.go b/internal/cilium/lint/cep.go index 7a276340..c27ac9f0 100644 --- a/internal/cilium/lint/cep.go +++ b/internal/cilium/lint/cep.go @@ -100,9 +100,9 @@ func (s *CiliumEndpoint) checkNode(ctx context.Context, cep *v2.CiliumEndpoint) if err != nil { return err } + nodeIP := cep.Status.Networking.NodeIP for _, n := range nn { - ip, _ := getIPs(n.Status.Addresses) - if ip != "" && ip == cep.Status.Networking.NodeIP { + if matchIP(n.Status.Addresses, nodeIP) { return nil } } @@ -113,15 +113,15 @@ func (s *CiliumEndpoint) checkNode(ctx context.Context, cep *v2.CiliumEndpoint) // Helpers... -func getIPs(addrs []v1.NodeAddress) (iIP, eIP string) { +func matchIP(addrs []v1.NodeAddress, ip string) bool { for _, a := range addrs { - switch a.Type { - case v1.NodeExternalIP: - eIP = a.Address - case v1.NodeInternalIP: - iIP = a.Address + if a.Type != v1.NodeInternalIP { + continue + } + if a.Address == ip { + return true } } - return + return false } diff --git a/internal/cilium/lint/cnp.go b/internal/cilium/lint/cnp.go index 09a98fc2..12d3ca43 100644 --- a/internal/cilium/lint/cnp.go +++ b/internal/cilium/lint/cnp.go @@ -175,8 +175,6 @@ func matchSel(labels map[string]string, e slimv1.LabelSelectorRequirement) bool func matchLabels(labels, sel map[string]string) bool { var count int - fmt.Println("LABELS", labels) - fmt.Println("SEL", sel) for k, v := range sel { k = strings.TrimPrefix(k, "any.") if v1, ok := labels[k]; ok && v == v1 { diff --git a/internal/client/config.go b/internal/client/config.go index a4c2f40d..57325f73 100644 --- a/internal/client/config.go +++ b/internal/client/config.go @@ -249,7 +249,7 @@ func (c *Config) CurrentNamespaceName() (string, error) { return ct.Namespace, nil } - return DefaultNamespace, nil + return DefaultNamespace, fmt.Errorf("invalid context specified: %q", cfg.CurrentContext) } // NamespaceNames fetch all available namespaces on current cluster. diff --git a/internal/dao/generic.go b/internal/dao/generic.go index ed214779..67512158 100644 --- a/internal/dao/generic.go +++ b/internal/dao/generic.go @@ -5,6 +5,7 @@ package dao import ( "context" + "fmt" "github.com/derailed/popeye/internal" "github.com/derailed/popeye/internal/client" @@ -22,7 +23,10 @@ type Generic struct { // List returns a collection of resources. func (g *Generic) List(ctx context.Context) ([]runtime.Object, error) { labelSel, _ := ctx.Value(internal.KeyLabels).(string) - ns, _ := ctx.Value(internal.KeyNamespace).(string) + ns, ok := ctx.Value(internal.KeyNamespace).(string) + if !ok { + return nil, fmt.Errorf("BOOM!! no namespace found in context %s", g.gvr) + } if client.IsAllNamespace(ns) { ns = client.AllNamespaces } diff --git a/internal/dao/resource.go b/internal/dao/resource.go index 9e6394da..0963b4ab 100644 --- a/internal/dao/resource.go +++ b/internal/dao/resource.go @@ -29,7 +29,7 @@ func (r *Resource) List(ctx context.Context) ([]runtime.Object, error) { } ns, ok := ctx.Value(internal.KeyNamespace).(string) if !ok { - panic(fmt.Sprintf("BOOM no namespace in context %s", r.gvr)) + return nil, fmt.Errorf("BOOM!! no namespace found in context %s", r.gvr) } if r.gvr == internal.Glossary[internal.NS] { ns = client.AllNamespaces diff --git a/internal/scrub/cjob.go b/internal/scrub/cjob.go index 453d957c..37ab1436 100644 --- a/internal/scrub/cjob.go +++ b/internal/scrub/cjob.go @@ -22,7 +22,7 @@ type CronJob struct { } // NewCronJob return a new instance. -func NewCronJob(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewCronJob(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &CronJob{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/cm.go b/internal/scrub/cm.go index fca6edec..e08f192f 100644 --- a/internal/scrub/cm.go +++ b/internal/scrub/cm.go @@ -20,7 +20,7 @@ type ConfigMap struct { } // NewConfigMap returns a new instance. -func NewConfigMap(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewConfigMap(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &ConfigMap{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/cr.go b/internal/scrub/cr.go index 7b2de24e..dba2179e 100644 --- a/internal/scrub/cr.go +++ b/internal/scrub/cr.go @@ -21,7 +21,7 @@ type ClusterRole struct { } // NewClusterRole returns a new instance. -func NewClusterRole(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewClusterRole(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &ClusterRole{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/crb.go b/internal/scrub/crb.go index c0453463..af07f26c 100644 --- a/internal/scrub/crb.go +++ b/internal/scrub/crb.go @@ -21,7 +21,7 @@ type ClusterRoleBinding struct { } // NewClusterRoleBinding returns a new instance. -func NewClusterRoleBinding(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewClusterRoleBinding(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &ClusterRoleBinding{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/dp.go b/internal/scrub/dp.go index f31d2094..ce8ea36a 100644 --- a/internal/scrub/dp.go +++ b/internal/scrub/dp.go @@ -22,7 +22,7 @@ type Deployment struct { } // NewDeployment returns a new instance. -func NewDeployment(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewDeployment(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &Deployment{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/ds.go b/internal/scrub/ds.go index 1237ee26..e00a4ebd 100644 --- a/internal/scrub/ds.go +++ b/internal/scrub/ds.go @@ -22,7 +22,7 @@ type DaemonSet struct { } // NewDaemonSet return a new instance. -func NewDaemonSet(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewDaemonSet(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &DaemonSet{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/gw-route.go b/internal/scrub/gw-route.go index b2d82cb6..910bd807 100644 --- a/internal/scrub/gw-route.go +++ b/internal/scrub/gw-route.go @@ -20,7 +20,7 @@ type HTTPRoute struct { } // NewHTTPRoute return a new instance. -func NewHTTPRoute(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewHTTPRoute(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &HTTPRoute{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/gw.go b/internal/scrub/gw.go index 12882cab..d1a81f31 100644 --- a/internal/scrub/gw.go +++ b/internal/scrub/gw.go @@ -20,7 +20,7 @@ type Gateway struct { } // NewGateway return a new instance. -func NewGateway(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewGateway(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &Gateway{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/gwc.go b/internal/scrub/gwc.go index f1773695..3a187f8f 100644 --- a/internal/scrub/gwc.go +++ b/internal/scrub/gwc.go @@ -20,7 +20,7 @@ type GatewayClass struct { } // NewGatewayClass return a new instance. -func NewGatewayClass(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewGatewayClass(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &GatewayClass{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/hpa.go b/internal/scrub/hpa.go index f37242be..c289c588 100644 --- a/internal/scrub/hpa.go +++ b/internal/scrub/hpa.go @@ -23,7 +23,7 @@ type HorizontalPodAutoscaler struct { } // NewHorizontalPodAutoscaler returns a new instance. -func NewHorizontalPodAutoscaler(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewHorizontalPodAutoscaler(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &HorizontalPodAutoscaler{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/ing.go b/internal/scrub/ing.go index 599b0d46..922f2114 100644 --- a/internal/scrub/ing.go +++ b/internal/scrub/ing.go @@ -21,7 +21,7 @@ type Ingress struct { } // NewIngress return a new instance. -func NewIngress(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewIngress(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &Ingress{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/job.go b/internal/scrub/job.go index 880b9937..c841484e 100644 --- a/internal/scrub/job.go +++ b/internal/scrub/job.go @@ -22,7 +22,7 @@ type Job struct { } // NewJob return a new instance. -func NewJob(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewJob(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &Job{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/no.go b/internal/scrub/no.go index 9bd9d8c6..bd12a78a 100644 --- a/internal/scrub/no.go +++ b/internal/scrub/no.go @@ -21,7 +21,7 @@ type Node struct { } // NewNode return a new instance. -func NewNode(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewNode(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &Node{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/np.go b/internal/scrub/np.go index 53191a8d..9ac08106 100644 --- a/internal/scrub/np.go +++ b/internal/scrub/np.go @@ -21,7 +21,7 @@ type NetworkPolicy struct { } // NewNetworkPolicy return a new instance. -func NewNetworkPolicy(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewNetworkPolicy(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &NetworkPolicy{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/ns.go b/internal/scrub/ns.go index 60a7650f..68ea1bd6 100644 --- a/internal/scrub/ns.go +++ b/internal/scrub/ns.go @@ -20,7 +20,7 @@ type Namespace struct { } // NewNamespace returns a new instance. -func NewNamespace(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewNamespace(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &Namespace{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/pdb.go b/internal/scrub/pdb.go index c94a3835..08ca82d5 100644 --- a/internal/scrub/pdb.go +++ b/internal/scrub/pdb.go @@ -21,7 +21,7 @@ type PodDisruptionBudget struct { } // NewPodDisruptionBudget return a new PodDisruptionBudget scruber. -func NewPodDisruptionBudget(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewPodDisruptionBudget(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &PodDisruptionBudget{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/pod.go b/internal/scrub/pod.go index 03586930..1f4685d9 100644 --- a/internal/scrub/pod.go +++ b/internal/scrub/pod.go @@ -23,7 +23,7 @@ type Pod struct { } // NewPod return a new instance. -func NewPod(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewPod(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &Pod{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/pv.go b/internal/scrub/pv.go index 047eabe7..17c90dd6 100644 --- a/internal/scrub/pv.go +++ b/internal/scrub/pv.go @@ -20,7 +20,7 @@ type PersistentVolume struct { } // NewPersistentVolume return a new instance. -func NewPersistentVolume(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewPersistentVolume(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &PersistentVolume{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/pvc.go b/internal/scrub/pvc.go index 5b39362d..86fc6151 100644 --- a/internal/scrub/pvc.go +++ b/internal/scrub/pvc.go @@ -20,7 +20,7 @@ type PersistentVolumeClaim struct { } // NewPersistentVolumeClaim returns a new instance. -func NewPersistentVolumeClaim(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewPersistentVolumeClaim(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &PersistentVolumeClaim{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/rb.go b/internal/scrub/rb.go index acf8cfa2..681d5506 100644 --- a/internal/scrub/rb.go +++ b/internal/scrub/rb.go @@ -21,7 +21,7 @@ type RoleBinding struct { } // NewRoleBinding returns a new instance. -func NewRoleBinding(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewRoleBinding(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &RoleBinding{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/ro.go b/internal/scrub/ro.go index 103bd571..727fc7b9 100644 --- a/internal/scrub/ro.go +++ b/internal/scrub/ro.go @@ -20,7 +20,7 @@ type Role struct { } // NewRole returns a new instance. -func NewRole(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewRole(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &Role{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/rs.go b/internal/scrub/rs.go index 495113b4..fe9d4d15 100644 --- a/internal/scrub/rs.go +++ b/internal/scrub/rs.go @@ -21,7 +21,7 @@ type ReplicaSet struct { } // NewReplicaSet returns a new instance. -func NewReplicaSet(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewReplicaSet(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &ReplicaSet{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/sa.go b/internal/scrub/sa.go index 6b0daf7f..069a0bd0 100644 --- a/internal/scrub/sa.go +++ b/internal/scrub/sa.go @@ -22,7 +22,7 @@ type ServiceAccount struct { } // NewServiceAccount returns a new instance. -func NewServiceAccount(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewServiceAccount(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &ServiceAccount{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/sec.go b/internal/scrub/sec.go index dab300fb..18b49482 100644 --- a/internal/scrub/sec.go +++ b/internal/scrub/sec.go @@ -21,7 +21,7 @@ type Secret struct { } // NewSecret return a new Secret scruber. -func NewSecret(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewSecret(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &Secret{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/sts.go b/internal/scrub/sts.go index 7b90b13f..da8a3941 100644 --- a/internal/scrub/sts.go +++ b/internal/scrub/sts.go @@ -22,7 +22,7 @@ type StatefulSet struct { } // NewStatefulSet return a new StatefulSet scruber. -func NewStatefulSet(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewStatefulSet(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &StatefulSet{ Collector: issues.NewCollector(codes, c.Config), Cache: c, diff --git a/internal/scrub/svc.go b/internal/scrub/svc.go index fde05b49..e0b92c85 100644 --- a/internal/scrub/svc.go +++ b/internal/scrub/svc.go @@ -20,7 +20,7 @@ type Service struct { } // NewService return a new instance. -func NewService(ctx context.Context, c *Cache, codes *issues.Codes) Linter { +func NewService(_ context.Context, c *Cache, codes *issues.Codes) Linter { return &Service{ Collector: issues.NewCollector(codes, c.Config), Cache: c, From 360e01144aef0559f72dd5d2da59c168368d9d70 Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 30 Dec 2024 12:52:05 -0700 Subject: [PATCH 6/8] fix #370,#356,#337,#301 --- cmd/root.go | 57 +++++++++++++++++++++++++++++-- internal/issues/assets/codes.yaml | 3 ++ internal/issues/codes_test.go | 2 +- main.go | 16 --------- pkg/config/flags.go | 8 +++-- pkg/popeye.go | 26 +++++--------- 6 files changed, 73 insertions(+), 39 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 57fd9b74..d4179289 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -52,13 +52,14 @@ func Execute() { // Doit runs the scans and lints pass over the specified cluster. func doIt(cmd *cobra.Command, args []string) { + bomb(initLogs()) + defer func() { if err := recover(); err != nil { pkg.BailOut(err.(error)) } }() - zerolog.SetGlobalLevel(zerolog.DebugLevel) clearScreen() bomb(flags.Validate()) flags.StandAlone = true @@ -84,7 +85,7 @@ func bomb(err error) { if err == nil { return } - panic(fmt.Errorf("💥 %s\n", report.Colorize(err.Error(), report.ColorRed))) + panic(fmt.Errorf("💥 %s", report.Colorize(err.Error(), report.ColorRed))) } func initPopeyeFlags() { @@ -166,6 +167,15 @@ func initPopeyeFlags() { []string{}, "Specify which resources to include in the scan ie -s po,svc", ) + + rootCmd.Flags().IntVarP(flags.LogLevel, "log-level", "v", + 1, + "Specify log level. Use 0|1|2|3|4 for disable|info|warn|error|debug", + ) + rootCmd.Flags().StringVarP(flags.LogFile, "logs", "", + pkg.LogFile, + "Specify log file location. Use `none` for stdout", + ) } func initKubeConfigFlags() { @@ -212,6 +222,49 @@ func initKubeConfigFlags() { ) } +func initLogs() error { + var logs string + if *flags.LogFile != "none" { + logs = *flags.LogFile + } + + var file = os.Stdout + if logs != "" { + mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY + var err error + file, err = os.OpenFile(logs, mod, 0644) + if err != nil { + return fmt.Errorf("unable to create Popeye log file: %w", err) + } + } + log.Logger = log.Output(zerolog.ConsoleWriter{Out: file}) + + if flags.LogLevel == nil { + zerolog.SetGlobalLevel(zerolog.InfoLevel) + } else { + zerolog.SetGlobalLevel(toLogLevel(*flags.LogLevel)) + } + + return nil +} + +func toLogLevel(level int) zerolog.Level { + switch level { + case -1: + return zerolog.TraceLevel + case 0: + return zerolog.Disabled + case 1: + return zerolog.InfoLevel + case 2: + return zerolog.WarnLevel + case 3: + return zerolog.ErrorLevel + default: + return zerolog.DebugLevel + } +} + func initFlags() { initPopeyeFlags() initKubeConfigFlags() diff --git a/internal/issues/assets/codes.yaml b/internal/issues/assets/codes.yaml index 80c9729a..42a52b82 100644 --- a/internal/issues/assets/codes.yaml +++ b/internal/issues/assets/codes.yaml @@ -100,6 +100,9 @@ codes: 307: message: "%s references a non existing ServiceAccount: %q" severity: 2 + 308: + message: Uses "default" bound ServiceAccount. Could be a security risk + severity: 3 # General 400: diff --git a/internal/issues/codes_test.go b/internal/issues/codes_test.go index 393cc48d..97d8a273 100644 --- a/internal/issues/codes_test.go +++ b/internal/issues/codes_test.go @@ -15,7 +15,7 @@ func TestCodesLoad(t *testing.T) { cc, err := issues.LoadCodes() assert.Nil(t, err) - assert.Equal(t, 116, len(cc.Glossary)) + assert.Equal(t, 117, len(cc.Glossary)) assert.Equal(t, "No liveness probe", cc.Glossary[103].Message) assert.Equal(t, rules.WarnLevel, cc.Glossary[103].Severity) } diff --git a/main.go b/main.go index 31fe7521..56646c6c 100644 --- a/main.go +++ b/main.go @@ -4,26 +4,10 @@ package main import ( - "fmt" - "os" - "github.com/derailed/popeye/cmd" - "github.com/derailed/popeye/pkg" - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" _ "k8s.io/client-go/plugin/pkg/client/auth" ) -func init() { - mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY - if file, err := os.OpenFile(pkg.LogFile, mod, 0644); err == nil { - log.Logger = log.Output(zerolog.ConsoleWriter{Out: file}) - } else { - fmt.Printf("Unable to create Popeye log file %v. Exiting...", err) - os.Exit(1) - } -} - func main() { cmd.Execute() } diff --git a/pkg/config/flags.go b/pkg/config/flags.go index 9212be11..7fbabfc5 100644 --- a/pkg/config/flags.go +++ b/pkg/config/flags.go @@ -42,6 +42,8 @@ type Flags struct { ActiveNamespace *string ForceExitZero *bool MinScore *int + LogLevel *int + LogFile *string } // NewFlags returns new configuration flags. @@ -62,15 +64,17 @@ func NewFlags() *Flags { PushGateway: newPushGateway(), ForceExitZero: boolPtr(false), MinScore: intPtr(0), + LogLevel: intPtr(0), + LogFile: strPtr(""), } } func (f *Flags) Validate() error { if !IsBoolSet(f.Save) && IsStrSet(f.OutputFile) { - return errors.New("'--save' must be used in conjunction with 'output-file'.") + return errors.New("'--save' must be used in conjunction with 'output-file'") } if IsBoolSet(f.Save) && IsStrSet(f.S3.Bucket) { - return errors.New("'--save' cannot be used in conjunction with 's3-bucket'.") + return errors.New("'--save' cannot be used in conjunction with 's3-bucket'") } if !in(outputs, f.Output) { diff --git a/pkg/popeye.go b/pkg/popeye.go index 2fec49ea..8d5e7307 100644 --- a/pkg/popeye.go +++ b/pkg/popeye.go @@ -202,11 +202,11 @@ func (p *Popeye) buildCtx(ctx context.Context) context.Context { } ns, err := p.client().Config().CurrentNamespaceName() if err != nil { + log.Warn().Msgf("Unable to determine current namespace: %v. Using `default` namespace", err) ns = client.DefaultNamespace } - ctx = context.WithValue(ctx, internal.KeyNamespace, ns) - return ctx + return context.WithValue(ctx, internal.KeyNamespace, ns) } func (p *Popeye) validateSpinach(ss scrub.Scrubs) error { @@ -226,10 +226,6 @@ func (p *Popeye) lint() (int, int, error) { log.Debug().Msgf("Lint %v", time.Since(t)) }(time.Now()) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - ctx = p.buildCtx(ctx) - codes, err := issues.LoadCodes() if err != nil { return 0, 0, err @@ -250,22 +246,18 @@ func (p *Popeye) lint() (int, int, error) { if err := p.validateSpinach(scrubers); err != nil { return 0, 0, err } + + ctx := p.buildCtx(context.Background()) + sections, ans := p.config.Sections(), p.client().ActiveNamespace() for k, fn := range scrubers { gvr, ok := internal.Glossary[k] if !ok || gvr == types.BlankGVR { continue } - - if p.aliases.Exclude(gvr, p.config.Sections()) { + if client.IsNamespaced(ans) && p.aliases.IsNamespaced(gvr) || p.aliases.Exclude(gvr, sections) { continue } - // Skip node linter if active namespace is set. - if gvr == internal.Glossary[internal.NO] && p.client().ActiveNamespace() != client.AllNamespaces { - continue - } - runners[gvr] = fn(ctx, cache, codes) - } total, errCount := len(runners), 0 @@ -304,12 +296,10 @@ func (p *Popeye) runLinter(ctx context.Context, gvr types.GVR, l scrub.Linter, c } }() - callCtx := ctx if !p.aliases.IsNamespaced(gvr) { - callCtx = context.WithValue(ctx, internal.KeyNamespace, client.ClusterScope) + ctx = context.WithValue(ctx, internal.KeyNamespace, client.ClusterScope) } - - if err := l.Lint(callCtx); err != nil { + if err := l.Lint(ctx); err != nil { p.builder.AddError(err) } o := l.Outcome().Filter(rules.Level(p.config.LintLevel)) From d23937ad4758534adba1bf6e90fe2602cb689c8e Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 30 Dec 2024 12:55:14 -0700 Subject: [PATCH 7/8] fix #267,#200,#168 --- internal/lint/cronjob.go | 2 +- internal/lint/dp.go | 2 +- internal/lint/ds.go | 2 +- internal/lint/helper.go | 21 ++++++++- internal/lint/job.go | 2 +- internal/lint/np.go | 28 +++++------ internal/lint/np_test.go | 36 +++++++-------- internal/lint/pod.go | 48 ++++++++++++------- internal/lint/pod_test.go | 64 ++++++++++++++++++++++---- internal/lint/rb.go | 28 +++++++++++ internal/lint/rb_test.go | 44 ++++++++++++++++++ internal/lint/rs.go | 2 +- internal/lint/sts.go | 2 +- internal/lint/testdata/auth/crb/2.yaml | 43 +++++++++++++++++ internal/lint/testdata/auth/rob/2.yaml | 45 ++++++++++++++++++ internal/lint/testdata/config/1.yaml | 12 +++++ internal/lint/testdata/core/pod/3.yaml | 4 +- internal/lint/testdata/net/np/1.yaml | 8 +++- internal/lint/testdata/net/np/2.yaml | 8 +++- internal/lint/testdata/net/np/3.yaml | 10 ++-- internal/lint/testdata/net/np/blee.yml | 34 ++++++++++++++ 21 files changed, 371 insertions(+), 74 deletions(-) create mode 100644 internal/lint/testdata/auth/crb/2.yaml create mode 100644 internal/lint/testdata/auth/rob/2.yaml create mode 100644 internal/lint/testdata/config/1.yaml create mode 100644 internal/lint/testdata/net/np/blee.yml diff --git a/internal/lint/cronjob.go b/internal/lint/cronjob.go index 802b57ed..8785b40f 100644 --- a/internal/lint/cronjob.go +++ b/internal/lint/cronjob.go @@ -40,7 +40,7 @@ func (s *CronJob) Lint(ctx context.Context) error { cj := o.(*batchv1.CronJob) fqn := client.FQN(cj.Namespace, cj.Name) s.InitOutcome(fqn) - ctx = internal.WithSpec(ctx, SpecFor(fqn, cj)) + ctx = internal.WithSpec(ctx, coSpecFor(fqn, cj, cj.Spec.JobTemplate.Spec.Template.Spec)) s.checkCronJob(ctx, fqn, cj) s.checkContainers(ctx, fqn, cj.Spec.JobTemplate.Spec.Template.Spec) s.checkUtilization(ctx, over, fqn) diff --git a/internal/lint/dp.go b/internal/lint/dp.go index c35d02c1..3e884cc5 100644 --- a/internal/lint/dp.go +++ b/internal/lint/dp.go @@ -39,7 +39,7 @@ func (s *Deployment) Lint(ctx context.Context) error { dp := o.(*appsv1.Deployment) fqn := client.FQN(dp.Namespace, dp.Name) s.InitOutcome(fqn) - ctx = internal.WithSpec(ctx, SpecFor(fqn, dp)) + ctx = internal.WithSpec(ctx, coSpecFor(fqn, dp, dp.Spec.Template.Spec)) s.checkDeployment(ctx, dp) s.checkContainers(ctx, fqn, dp.Spec.Template.Spec) s.checkUtilization(ctx, over, dp) diff --git a/internal/lint/ds.go b/internal/lint/ds.go index 523d9904..725fca07 100644 --- a/internal/lint/ds.go +++ b/internal/lint/ds.go @@ -38,7 +38,7 @@ func (s *DaemonSet) Lint(ctx context.Context) error { ds := o.(*appsv1.DaemonSet) fqn := client.FQN(ds.Namespace, ds.Name) s.InitOutcome(fqn) - ctx = internal.WithSpec(ctx, SpecFor(fqn, ds)) + ctx = internal.WithSpec(ctx, coSpecFor(fqn, ds, ds.Spec.Template.Spec)) s.checkDaemonSet(ctx, ds) s.checkContainers(ctx, fqn, ds.Spec.Template.Spec) diff --git a/internal/lint/helper.go b/internal/lint/helper.go index bd74f488..36a7a5ee 100644 --- a/internal/lint/helper.go +++ b/internal/lint/helper.go @@ -28,6 +28,25 @@ const ( type qos = int +func coSpecFor(fqn string, o metav1.ObjectMetaAccessor, spec v1.PodSpec) rules.Spec { + rule := SpecFor(fqn, o) + rule.Containers = fetchContainers(spec) + + return rule +} + +func fetchContainers(podTemplate v1.PodSpec) []string { + containers := make([]string, 0, len(podTemplate.InitContainers)+len(podTemplate.Containers)) + for _, co := range podTemplate.InitContainers { + containers = append(containers, co.Name) + } + for _, co := range podTemplate.Containers { + containers = append(containers, co.Name) + } + + return containers +} + // SpecFor construct a new run spec for a given resource. func SpecFor(fqn string, o metav1.ObjectMetaAccessor) rules.Spec { spec := rules.Spec{ @@ -146,7 +165,7 @@ func asMB(q resource.Quantity) string { return fmt.Sprintf("%vMi", toMB(q)) } -// PodResources computes pod resouces as sum of containers allocations. +// PodResources computes pod resources as sum of containers allocations. func podResources(spec v1.PodSpec) (cpu, mem resource.Quantity) { for _, co := range spec.InitContainers { c, m, _ := containerResources(co) diff --git a/internal/lint/job.go b/internal/lint/job.go index 84b25e2b..72e7dfa1 100644 --- a/internal/lint/job.go +++ b/internal/lint/job.go @@ -39,7 +39,7 @@ func (s *Job) Lint(ctx context.Context) error { j := o.(*batchv1.Job) fqn := client.FQN(j.Namespace, j.Name) s.InitOutcome(fqn) - ctx = internal.WithSpec(ctx, SpecFor(fqn, j)) + ctx = internal.WithSpec(ctx, coSpecFor(fqn, j, j.Spec.Template.Spec)) s.checkJob(ctx, fqn, j) s.checkContainers(ctx, fqn, j.Spec.Template.Spec) s.checkUtilization(ctx, over, fqn) diff --git a/internal/lint/np.go b/internal/lint/np.go index 7abbb6a2..090cebe0 100644 --- a/internal/lint/np.go +++ b/internal/lint/np.go @@ -23,11 +23,13 @@ type direction string const ( dirIn direction = "Ingress" dirOut direction = "Egress" - bothPols = "All" + bothPols = "all" noPols = "" + ingress = "ingress" + egress = "egress" ) -// NetworkPolicy tracks NetworkPolicy sanitizatios. +// NetworkPolicy tracks NetworkPolicy linting. type NetworkPolicy struct { *issues.Collector @@ -57,13 +59,13 @@ func (s *NetworkPolicy) Lint(ctx context.Context) error { s.checkSelector(ctx, fqn, np.Spec.PodSelector) s.checkIngresses(ctx, fqn, np.Spec.Ingress) s.checkEgresses(ctx, fqn, np.Spec.Egress) - s.checkRuleType(ctx, fqn, &np.Spec) + s.checkRuleType(ctx, &np.Spec) } return nil } -func (s *NetworkPolicy) checkRuleType(ctx context.Context, fqn string, spec *netv1.NetworkPolicySpec) { +func (s *NetworkPolicy) checkRuleType(ctx context.Context, spec *netv1.NetworkPolicySpec) { if spec.PodSelector.Size() > 0 { return } @@ -72,15 +74,15 @@ func (s *NetworkPolicy) checkRuleType(ctx context.Context, fqn string, spec *net case isAllowAll(spec): s.AddCode(ctx, 1203, "Allow", bothPols) case isAllowAllIngress(spec): - s.AddCode(ctx, 1203, "Allow All", dirIn) + s.AddCode(ctx, 1203, "Allow all", ingress) case isAllowAllEgress(spec): - s.AddCode(ctx, 1203, "Allow All", dirOut) + s.AddCode(ctx, 1203, "Allow all", egress) case isDenyAll(spec): s.AddCode(ctx, 1203, "Deny", bothPols) case isDenyAllIngress(spec): - s.AddCode(ctx, 1203, "Deny All", dirIn) + s.AddCode(ctx, 1203, "Deny all", ingress) case isDenyAllEgress(spec): - s.AddCode(ctx, 1203, "Deny All", dirOut) + s.AddCode(ctx, 1203, "Deny all", egress) } } @@ -157,7 +159,7 @@ func (s *NetworkPolicy) checkIPBlocks(ctx context.Context, fqn string, b *netv1. s.AddErr(ctx, err) } if !s.matchPips(ns, ipnet) { - s.AddCode(ctx, 1206, d, b.CIDR) + s.AddCode(ctx, 1206, strings.ToLower(string(d)), b.CIDR) } for _, ex := range b.Except { _, ipnet, err := net.ParseCIDR(ex) @@ -166,7 +168,7 @@ func (s *NetworkPolicy) checkIPBlocks(ctx context.Context, fqn string, b *netv1. continue } if !s.matchPips(ns, ipnet) { - s.AddCode(ctx, 1207, d, ex) + s.AddCode(ctx, 1207, strings.ToLower(string(d)), ex) } } } @@ -210,16 +212,16 @@ func (s *NetworkPolicy) checkPodSelector(ctx context.Context, nss []*v1.Namespac } if !found { if len(nn) > 0 { - s.AddCode(ctx, 1208, d, dumpSel(sel), strings.Join(nn, ",")) + s.AddCode(ctx, 1208, strings.ToLower(string(d)), dumpSel(sel), strings.Join(nn, ",")) } else { - s.AddCode(ctx, 1202, d, dumpSel(sel)) + s.AddCode(ctx, 1202, strings.ToLower(string(d)), dumpSel(sel)) } } } func (s *NetworkPolicy) checkNSSelector(ctx context.Context, sel *metav1.LabelSelector, nss []*v1.Namespace, d direction) bool { if len(nss) == 0 { - s.AddCode(ctx, 1201, d, dumpSel(sel)) + s.AddCode(ctx, 1201, strings.ToLower(string(d)), dumpSel(sel)) return false } diff --git a/internal/lint/np_test.go b/internal/lint/np_test.go index 67d99889..617f5bcd 100644 --- a/internal/lint/np_test.go +++ b/internal/lint/np_test.go @@ -31,46 +31,46 @@ func TestNPLintDenyAll(t *testing.T) { ii := np.Outcome()["default/deny-all"] assert.Equal(t, 1, len(ii)) - assert.Equal(t, `[POP-1203] Deny All policy in effect`, ii[0].Message) + assert.Equal(t, `[POP-1203] Deny all policy in effect`, ii[0].Message) assert.Equal(t, rules.InfoLevel, ii[0].Level) ii = np.Outcome()["default/deny-all-ing"] assert.Equal(t, 1, len(ii)) - assert.Equal(t, `[POP-1203] Deny All Ingress policy in effect`, ii[0].Message) + assert.Equal(t, `[POP-1203] Deny all ingress policy in effect`, ii[0].Message) assert.Equal(t, rules.InfoLevel, ii[0].Level) ii = np.Outcome()["default/deny-all-eg"] assert.Equal(t, 1, len(ii)) - assert.Equal(t, `[POP-1203] Deny All Egress policy in effect`, ii[0].Message) + assert.Equal(t, `[POP-1203] Deny all egress policy in effect`, ii[0].Message) assert.Equal(t, rules.InfoLevel, ii[0].Level) ii = np.Outcome()["default/allow-all"] assert.Equal(t, 1, len(ii)) - assert.Equal(t, `[POP-1203] Allow All policy in effect`, ii[0].Message) + assert.Equal(t, `[POP-1203] Allow all policy in effect`, ii[0].Message) assert.Equal(t, rules.InfoLevel, ii[0].Level) ii = np.Outcome()["default/allow-all-ing"] assert.Equal(t, 1, len(ii)) - assert.Equal(t, `[POP-1203] Allow All Ingress policy in effect`, ii[0].Message) + assert.Equal(t, `[POP-1203] Allow all ingress policy in effect`, ii[0].Message) assert.Equal(t, rules.InfoLevel, ii[0].Level) ii = np.Outcome()["default/allow-all-eg"] assert.Equal(t, 1, len(ii)) - assert.Equal(t, `[POP-1203] Allow All Egress policy in effect`, ii[0].Message) + assert.Equal(t, `[POP-1203] Allow all egress policy in effect`, ii[0].Message) assert.Equal(t, rules.InfoLevel, ii[0].Level) ii = np.Outcome()["default/ip-block-all-ing"] assert.Equal(t, 2, len(ii)) - assert.Equal(t, `[POP-1206] No pods matched Egress IPBlock 172.2.0.0/24`, ii[0].Message) + assert.Equal(t, `[POP-1206] No pods matched egress IPBlock 172.2.0.0/24`, ii[0].Message) assert.Equal(t, rules.WarnLevel, ii[0].Level) - assert.Equal(t, `[POP-1203] Deny All Ingress policy in effect`, ii[1].Message) + assert.Equal(t, `[POP-1203] Deny all ingress policy in effect`, ii[1].Message) assert.Equal(t, rules.InfoLevel, ii[1].Level) ii = np.Outcome()["default/ip-block-all-eg"] assert.Equal(t, 2, len(ii)) - assert.Equal(t, `[POP-1206] No pods matched Ingress IPBlock 172.2.0.0/24`, ii[0].Message) + assert.Equal(t, `[POP-1206] No pods matched ingress IPBlock 172.2.0.0/24`, ii[0].Message) assert.Equal(t, rules.WarnLevel, ii[0].Level) - assert.Equal(t, `[POP-1203] Deny All Egress policy in effect`, ii[1].Message) + assert.Equal(t, `[POP-1203] Deny all egress policy in effect`, ii[1].Message) assert.Equal(t, rules.InfoLevel, ii[1].Level) } @@ -93,26 +93,26 @@ func TestNPLint(t *testing.T) { ii = np.Outcome()["default/np2"] assert.Equal(t, 3, len(ii)) - assert.Equal(t, `[POP-1207] No pods matched except Ingress IPBlock 172.1.1.0/24`, ii[0].Message) + assert.Equal(t, `[POP-1207] No pods matched except ingress IPBlock 172.1.1.0/24`, ii[0].Message) assert.Equal(t, rules.WarnLevel, ii[0].Level) - assert.Equal(t, `[POP-1208] No pods match Ingress pod selector: app=p2 in namespace: ns2`, ii[1].Message) + assert.Equal(t, `[POP-1208] No pods match ingress pod selector: app=p2 in namespace: ns2`, ii[1].Message) assert.Equal(t, rules.WarnLevel, ii[1].Level) - assert.Equal(t, `[POP-1206] No pods matched Egress IPBlock 172.0.0.0/24`, ii[2].Message) + assert.Equal(t, `[POP-1206] No pods matched egress IPBlock 172.0.0.0/24`, ii[2].Message) assert.Equal(t, rules.WarnLevel, ii[2].Level) ii = np.Outcome()["default/np3"] assert.Equal(t, 6, len(ii)) assert.Equal(t, `[POP-1200] No pods match pod selector: app=p-bozo`, ii[0].Message) assert.Equal(t, rules.WarnLevel, ii[0].Level) - assert.Equal(t, `[POP-1206] No pods matched Ingress IPBlock 172.2.0.0/16`, ii[1].Message) + assert.Equal(t, `[POP-1206] No pods matched ingress IPBlock 172.2.0.0/16`, ii[1].Message) assert.Equal(t, rules.WarnLevel, ii[1].Level) - assert.Equal(t, `[POP-1207] No pods matched except Ingress IPBlock 172.2.1.0/24`, ii[2].Message) + assert.Equal(t, `[POP-1207] No pods matched except ingress IPBlock 172.2.1.0/24`, ii[2].Message) assert.Equal(t, rules.WarnLevel, ii[2].Level) - assert.Equal(t, `[POP-1201] No namespaces match Ingress namespace selector: app-In-ns-bozo`, ii[3].Message) + assert.Equal(t, `[POP-1201] No namespaces match ingress namespace selector: app-In-ns-bozo`, ii[3].Message) assert.Equal(t, rules.WarnLevel, ii[3].Level) - assert.Equal(t, `[POP-1202] No pods match Ingress pod selector: app=pod-bozo`, ii[4].Message) + assert.Equal(t, `[POP-1202] No pods match ingress pod selector: app=pod-bozo`, ii[4].Message) assert.Equal(t, rules.WarnLevel, ii[4].Level) - assert.Equal(t, `[POP-1208] No pods match Egress pod selector: app=p1-missing in namespace: default`, ii[5].Message) + assert.Equal(t, `[POP-1208] No pods match egress pod selector: app=p1-missing in namespace: default`, ii[5].Message) assert.Equal(t, rules.WarnLevel, ii[5].Level) } diff --git a/internal/lint/pod.go b/internal/lint/pod.go index 22cdbc9e..507e47ef 100644 --- a/internal/lint/pod.go +++ b/internal/lint/pod.go @@ -51,6 +51,7 @@ func NewPod(co *issues.Collector, db *db.DB) *Pod { // Lint cleanse the resource.. func (s *Pod) Lint(ctx context.Context) error { + boundSA := boundDefaultSA(s.db) txn, it := s.db.MustITFor(internal.Glossary[internal.PO]) defer txn.Abort() for o := it.Next(); o != nil; o = it.Next() { @@ -59,7 +60,7 @@ func (s *Pod) Lint(ctx context.Context) error { s.InitOutcome(fqn) defer s.CloseOutcome(ctx, fqn, nil) - ctx = internal.WithSpec(ctx, SpecFor(fqn, po)) + ctx = internal.WithSpec(ctx, coSpecFor(fqn, po, po.Spec)) s.checkStatus(ctx, po) s.checkContainerStatus(ctx, fqn, po) s.checkContainers(ctx, fqn, po) @@ -69,7 +70,7 @@ func (s *Pod) Lint(ctx context.Context) error { s.checkPdb(ctx, po.ObjectMeta.Labels) } s.checkForMultiplePdbMatches(ctx, po.Namespace, po.ObjectMeta.Labels) - s.checkSecure(ctx, fqn, po.Spec) + s.checkSecure(ctx, fqn, po.Spec, boundSA) pmx, err := s.db.FindPMX(fqn) if err != nil { @@ -96,6 +97,10 @@ func (s *Pod) checkNPs(ctx context.Context, pod *v1.Pod) { txn, it := s.db.MustITForNS(internal.Glossary[internal.NP], pod.Namespace) defer txn.Abort() + const ( + in = 0 + out = 1 + ) matches := [2]int{} for o := it.Next(); o != nil; o = it.Next() { np := o.(*netv1.NetworkPolicy) @@ -103,34 +108,41 @@ func (s *Pod) checkNPs(ctx context.Context, pod *v1.Pod) { return } if isDenyAllIngress(&np.Spec) || isAllowAllIngress(&np.Spec) { - matches[0]++ + matches[in]++ if s.checkEgresses(ctx, pod, np.Spec.Egress) { - matches[1]++ + matches[out]++ } continue } if isDenyAllEgress(&np.Spec) || isAllowAllEgress(&np.Spec) { - matches[1]++ + matches[out]++ if s.checkIngresses(ctx, pod, np.Spec.Ingress) { - matches[0]++ + matches[in]++ } continue } if labelsMatch(&np.Spec.PodSelector, pod.Labels) { + if polInclude(np.Spec.PolicyTypes, dirIn) { + matches[in]++ + } + if polInclude(np.Spec.PolicyTypes, dirOut) { + matches[out]++ + } + } else { if s.checkIngresses(ctx, pod, np.Spec.Ingress) { - matches[0]++ + matches[out]++ } if s.checkEgresses(ctx, pod, np.Spec.Egress) { - matches[1]++ + matches[in]++ } } } - if matches[0] == 0 { - s.AddCode(ctx, 1204, dirIn) + if matches[in] == 0 { + s.AddCode(ctx, 1204, ingress) } - if matches[1] == 0 { - s.AddCode(ctx, 1204, dirOut) + if matches[out] == 0 { + s.AddCode(ctx, 1204, egress) } } @@ -285,17 +297,21 @@ func (s *Pod) checkUtilization(ctx context.Context, fqn string, po *v1.Pod, cmx } } -func (s *Pod) checkSecure(ctx context.Context, fqn string, spec v1.PodSpec) { - if err := s.checkSA(ctx, fqn, spec); err != nil { +func (s *Pod) checkSecure(ctx context.Context, fqn string, spec v1.PodSpec, boundSA bool) { + if err := s.checkSA(ctx, fqn, spec, boundSA); err != nil { s.AddErr(ctx, err) } s.checkSecContext(ctx, fqn, spec) } -func (s *Pod) checkSA(ctx context.Context, fqn string, spec v1.PodSpec) error { +func (s *Pod) checkSA(ctx context.Context, fqn string, spec v1.PodSpec, boundSA bool) error { ns, _ := namespaced(fqn) if spec.ServiceAccountName == "default" { - s.AddCode(ctx, 300) + if boundSA { + s.AddCode(ctx, 308) + } else { + s.AddCode(ctx, 300) + } } txn := s.db.Txn(false) diff --git a/internal/lint/pod_test.go b/internal/lint/pod_test.go index 3c0d0d0f..c53f54ed 100644 --- a/internal/lint/pod_test.go +++ b/internal/lint/pod_test.go @@ -5,12 +5,18 @@ package lint import ( "context" + "os" + "path/filepath" "testing" "github.com/derailed/popeye/internal" "github.com/derailed/popeye/internal/db" + "github.com/derailed/popeye/internal/issues" "github.com/derailed/popeye/internal/test" + "github.com/derailed/popeye/pkg/config" + "github.com/derailed/popeye/pkg/config/json" "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v2" v1 "k8s.io/api/core/v1" netv1 "k8s.io/api/networking/v1" polv1 "k8s.io/api/policy/v1" @@ -37,7 +43,7 @@ func TestPodNPLint(t *testing.T) { ii := po.Outcome()["ns1/p1"] assert.Equal(t, 1, len(ii)) - assert.Equal(t, `[POP-1204] Pod Egress is not secured by a network policy`, ii[0].Message) + assert.Equal(t, `[POP-1204] Pod egress is not secured by a network policy`, ii[0].Message) ii = po.Outcome()["ns2/p2"] assert.Equal(t, 0, len(ii)) @@ -106,7 +112,7 @@ func TestPodCheckSecure(t *testing.T) { u := uu[k] t.Run(k, func(t *testing.T) { p := NewPod(test.MakeCollector(t), dba) - p.checkSecure(ctx, "default/p1", u.pod.Spec) + p.checkSecure(ctx, "default/p1", u.pod.Spec, true) assert.Equal(t, u.issues, len(p.Outcome()["default/p1"])) }) } @@ -136,8 +142,8 @@ func TestPodLint(t *testing.T) { assert.Equal(t, 6, len(ii)) assert.Equal(t, `[POP-207] Pod is in an unhappy phase ()`, ii[0].Message) assert.Equal(t, `[POP-208] Unmanaged pod detected. Best to use a controller`, ii[1].Message) - assert.Equal(t, `[POP-1204] Pod Ingress is not secured by a network policy`, ii[2].Message) - assert.Equal(t, `[POP-1204] Pod Egress is not secured by a network policy`, ii[3].Message) + assert.Equal(t, `[POP-1204] Pod ingress is not secured by a network policy`, ii[2].Message) + assert.Equal(t, `[POP-1204] Pod egress is not secured by a network policy`, ii[3].Message) assert.Equal(t, `[POP-206] Pod has no associated PodDisruptionBudget`, ii[4].Message) assert.Equal(t, `[POP-301] Connects to API Server? ServiceAccount token is mounted`, ii[5].Message) @@ -145,8 +151,8 @@ func TestPodLint(t *testing.T) { assert.Equal(t, 6, len(ii)) assert.Equal(t, `[POP-105] Liveness uses a port#, prefer a named port`, ii[0].Message) assert.Equal(t, `[POP-105] Readiness uses a port#, prefer a named port`, ii[1].Message) - assert.Equal(t, `[POP-1204] Pod Ingress is not secured by a network policy`, ii[2].Message) - assert.Equal(t, `[POP-1204] Pod Egress is not secured by a network policy`, ii[3].Message) + assert.Equal(t, `[POP-1204] Pod ingress is not secured by a network policy`, ii[2].Message) + assert.Equal(t, `[POP-1204] Pod egress is not secured by a network policy`, ii[3].Message) assert.Equal(t, `[POP-301] Connects to API Server? ServiceAccount token is mounted`, ii[4].Message) assert.Equal(t, `[POP-109] CPU Current/Request (2000m/1000m) reached user 80% threshold (200%)`, ii[5].Message) @@ -163,8 +169,8 @@ func TestPodLint(t *testing.T) { assert.Equal(t, `[POP-113] Container image "zorg:latest" is not hosted on an allowed docker registry`, ii[8].Message) assert.Equal(t, `[POP-107] No resource limits defined`, ii[9].Message) assert.Equal(t, `[POP-208] Unmanaged pod detected. Best to use a controller`, ii[10].Message) - assert.Equal(t, `[POP-1204] Pod Ingress is not secured by a network policy`, ii[11].Message) - assert.Equal(t, `[POP-1204] Pod Egress is not secured by a network policy`, ii[12].Message) + assert.Equal(t, `[POP-1204] Pod ingress is not secured by a network policy`, ii[11].Message) + assert.Equal(t, `[POP-1204] Pod egress is not secured by a network policy`, ii[12].Message) assert.Equal(t, `[POP-300] Uses "default" ServiceAccount`, ii[13].Message) assert.Equal(t, `[POP-301] Connects to API Server? ServiceAccount token is mounted`, ii[14].Message) @@ -173,12 +179,50 @@ func TestPodLint(t *testing.T) { assert.Equal(t, `[POP-113] Container image "blee:v1.2" is not hosted on an allowed docker registry`, ii[0].Message) assert.Equal(t, `[POP-106] No resources requests/limits defined`, ii[1].Message) assert.Equal(t, `[POP-102] No probes defined`, ii[2].Message) - assert.Equal(t, `[POP-1204] Pod Ingress is not secured by a network policy`, ii[3].Message) - assert.Equal(t, `[POP-1204] Pod Egress is not secured by a network policy`, ii[4].Message) + assert.Equal(t, `[POP-1204] Pod ingress is not secured by a network policy`, ii[3].Message) + assert.Equal(t, `[POP-1204] Pod egress is not secured by a network policy`, ii[4].Message) assert.Equal(t, `[POP-209] Pod is managed by multiple PodDisruptionBudgets (pdb4, pdb4-1)`, ii[5].Message) assert.Equal(t, `[POP-301] Connects to API Server? ServiceAccount token is mounted`, ii[6].Message) } +func TestPodLintExcludes(t *testing.T) { + dba, err := test.NewTestDB() + assert.NoError(t, err) + l := db.NewLoader(dba) + + ctx := test.MakeCtx(t) + assert.NoError(t, test.LoadDB[*v1.Pod](ctx, l.DB, "core/pod/2.yaml", internal.Glossary[internal.PO])) + assert.NoError(t, test.LoadDB[*v1.ServiceAccount](ctx, l.DB, "core/sa/1.yaml", internal.Glossary[internal.SA])) + assert.NoError(t, test.LoadDB[*polv1.PodDisruptionBudget](ctx, l.DB, "pol/pdb/1.yaml", internal.Glossary[internal.PDB])) + assert.NoError(t, test.LoadDB[*netv1.NetworkPolicy](ctx, l.DB, "net/np/1.yaml", internal.Glossary[internal.NP])) + assert.NoError(t, test.LoadDB[*mv1beta1.PodMetrics](ctx, l.DB, "mx/pod/1.yaml", internal.Glossary[internal.PMX])) + + bb, err := os.ReadFile(filepath.Join("testdata", "config", "1.yaml")) + assert.NoError(t, err) + assert.NoError(t, json.NewValidator().Validate(json.SpinachSchema, bb)) + var cfg config.Config + assert.NoError(t, yaml.Unmarshal(bb, &cfg)) + + codes, err := issues.LoadCodes() + assert.NoError(t, err) + cc := issues.NewCollector(codes, &cfg) + po := NewPod(cc, dba) + po.Collector.Config.Registries = []string{"dorker.io"} + assert.Nil(t, po.Lint(test.MakeContext("v1/pods", "pods"))) + assert.Equal(t, 5, len(po.Outcome())) + + ii := po.Outcome()["default/p4"] + + assert.Equal(t, 7, len(ii)) + assert.Equal(t, `[POP-101] Image tagged "latest" in use`, ii[0].Message) + assert.Equal(t, `[POP-107] No resource limits defined`, ii[1].Message) + assert.Equal(t, `[POP-208] Unmanaged pod detected. Best to use a controller`, ii[2].Message) + assert.Equal(t, `[POP-1204] Pod ingress is not secured by a network policy`, ii[3].Message) + assert.Equal(t, `[POP-1204] Pod egress is not secured by a network policy`, ii[4].Message) + assert.Equal(t, `[POP-300] Uses "default" ServiceAccount`, ii[5].Message) + assert.Equal(t, `[POP-301] Connects to API Server? ServiceAccount token is mounted`, ii[6].Message) +} + // ---------------------------------------------------------------------------- // Helpers... diff --git a/internal/lint/rb.go b/internal/lint/rb.go index 28492a34..b13d46ec 100644 --- a/internal/lint/rb.go +++ b/internal/lint/rb.go @@ -60,3 +60,31 @@ func (r *RoleBinding) checkInUse(ctx context.Context) { } } } + +func boundDefaultSA(db *db.DB) bool { + txn, it := db.MustITFor(internal.Glossary[internal.ROB]) + defer txn.Abort() + for o := it.Next(); o != nil; o = it.Next() { + rb := o.(*rbacv1.RoleBinding) + if rb.Namespace != client.DefaultNamespace || rb.RoleRef.Kind == "ClusterRole" { + continue + } + if rb.RoleRef.APIGroup == "" && rb.RoleRef.Kind == "ServiceAccount" && rb.RoleRef.Name == "default" { + return true + } + } + + txn, it = db.MustITFor(internal.Glossary[internal.CRB]) + defer txn.Abort() + for o := it.Next(); o != nil; o = it.Next() { + rb := o.(*rbacv1.ClusterRoleBinding) + if rb.RoleRef.Kind == "ClusterRole" { + continue + } + if rb.RoleRef.APIGroup == "" && rb.RoleRef.Kind == "ServiceAccount" && rb.RoleRef.Name == "default" { + return true + } + } + + return false +} diff --git a/internal/lint/rb_test.go b/internal/lint/rb_test.go index 086a405b..1bd43960 100644 --- a/internal/lint/rb_test.go +++ b/internal/lint/rb_test.go @@ -44,3 +44,47 @@ func TestRBLint(t *testing.T) { assert.Equal(t, `[POP-1300] References a ClusterRole (cr-bozo) which does not exist`, ii[0].Message) assert.Equal(t, rules.WarnLevel, ii[0].Level) } + +func TestRB_boundDefaultSA(t *testing.T) { + uu := map[string]struct { + roPath, robPath string + crPath, crbPath string + e bool + }{ + "happy": { + roPath: "auth/ro/1.yaml", + robPath: "auth/rob/1.yaml", + crPath: "auth/cr/1.yaml", + crbPath: "auth/crb/1.yaml", + }, + "role-bound": { + roPath: "auth/ro/1.yaml", + robPath: "auth/rob/2.yaml", + crPath: "auth/cr/1.yaml", + crbPath: "auth/crb/1.yaml", + }, + "cluster-role-bound": { + roPath: "auth/ro/1.yaml", + robPath: "auth/rob/1.yaml", + crPath: "auth/cr/1.yaml", + crbPath: "auth/crb/2.yaml", + }, + } + + for k, u := range uu { + t.Run(k, func(t *testing.T) { + dba, err := test.NewTestDB() + assert.NoError(t, err) + l := db.NewLoader(dba) + + ctx := test.MakeCtx(t) + assert.NoError(t, test.LoadDB[*rbacv1.RoleBinding](ctx, l.DB, u.robPath, internal.Glossary[internal.ROB])) + assert.NoError(t, test.LoadDB[*rbacv1.Role](ctx, l.DB, u.roPath, internal.Glossary[internal.RO])) + assert.NoError(t, test.LoadDB[*rbacv1.ClusterRole](ctx, l.DB, u.crPath, internal.Glossary[internal.CR])) + assert.NoError(t, test.LoadDB[*rbacv1.ClusterRoleBinding](ctx, l.DB, u.crbPath, internal.Glossary[internal.CRB])) + assert.NoError(t, test.LoadDB[*v1.ServiceAccount](ctx, l.DB, "core/sa/1.yaml", internal.Glossary[internal.SA])) + + assert.Equal(t, u.e, boundDefaultSA(dba)) + }) + } +} diff --git a/internal/lint/rs.go b/internal/lint/rs.go index 2e9763bd..dca34c11 100644 --- a/internal/lint/rs.go +++ b/internal/lint/rs.go @@ -36,7 +36,7 @@ func (s *ReplicaSet) Lint(ctx context.Context) error { rs := o.(*appsv1.ReplicaSet) fqn := client.FQN(rs.Namespace, rs.Name) s.InitOutcome(fqn) - ctx = internal.WithSpec(ctx, SpecFor(fqn, rs)) + ctx = internal.WithSpec(ctx, coSpecFor(fqn, rs, rs.Spec.Template.Spec)) s.checkHealth(ctx, rs) } diff --git a/internal/lint/sts.go b/internal/lint/sts.go index 6d94ea5d..cf34cdf1 100644 --- a/internal/lint/sts.go +++ b/internal/lint/sts.go @@ -48,7 +48,7 @@ func (s *StatefulSet) Lint(ctx context.Context) error { sts := o.(*appsv1.StatefulSet) fqn := client.FQN(sts.Namespace, sts.Name) s.InitOutcome(fqn) - ctx = internal.WithSpec(ctx, SpecFor(fqn, sts)) + ctx = internal.WithSpec(ctx, coSpecFor(fqn, sts, sts.Spec.Template.Spec)) s.checkStatefulSet(ctx, sts) s.checkContainers(ctx, fqn, sts) diff --git a/internal/lint/testdata/auth/crb/2.yaml b/internal/lint/testdata/auth/crb/2.yaml new file mode 100644 index 00000000..df2abcf3 --- /dev/null +++ b/internal/lint/testdata/auth/crb/2.yaml @@ -0,0 +1,43 @@ +--- +apiVersion: v1 +kind: List +items: + - apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: crb1 + subjects: + - kind: ServiceAccount + name: default + namespace: default + apiGroup: rbac.authorization.k8s.io + roleRef: + kind: ClusterRole + name: cr1 + apiGroup: rbac.authorization.k8s.io + - apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: crb2 + subjects: + - kind: ServiceAccount + name: sa2 + namespace: default + apiGroup: rbac.authorization.k8s.io + roleRef: + kind: ClusterRole + name: cr-bozo + apiGroup: rbac.authorization.k8s.io + - apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: crb3 + subjects: + - kind: ServiceAccount + name: sa-bozo + namespace: default + apiGroup: rbac.authorization.k8s.io + roleRef: + kind: Role + name: r-bozo + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/internal/lint/testdata/auth/rob/2.yaml b/internal/lint/testdata/auth/rob/2.yaml new file mode 100644 index 00000000..4663a1cf --- /dev/null +++ b/internal/lint/testdata/auth/rob/2.yaml @@ -0,0 +1,45 @@ +--- +apiVersion: v1 +kind: List +items: + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: rb1 + namespace: default + subjects: + - kind: ServiceAccount + name: default + apiGroup: rbac.authorization.k8s.io + roleRef: + kind: Role + name: r1 + apiGroup: rbac.authorization.k8s.io + + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: rb2 + namespace: default + subjects: + - kind: ServiceAccount + name: sa-bozo + apiGroup: rbac.authorization.k8s.io + roleRef: + kind: Role + name: r-bozo + apiGroup: rbac.authorization.k8s.io + + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: rb3 + namespace: default + subjects: + - kind: ServiceAccount + name: sa-bozo + apiGroup: rbac.authorization.k8s.io + roleRef: + kind: ClusterRole + name: cr-bozo + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/internal/lint/testdata/config/1.yaml b/internal/lint/testdata/config/1.yaml new file mode 100644 index 00000000..d36ab81b --- /dev/null +++ b/internal/lint/testdata/config/1.yaml @@ -0,0 +1,12 @@ +popeye: + excludes: + linters: + pods: + instances: + - codes: + - 100 + - 106 + - 113 + - 204 + containers: + - "rx:c2*" \ No newline at end of file diff --git a/internal/lint/testdata/core/pod/3.yaml b/internal/lint/testdata/core/pod/3.yaml index 49b1419f..86e6d5e6 100644 --- a/internal/lint/testdata/core/pod/3.yaml +++ b/internal/lint/testdata/core/pod/3.yaml @@ -1,7 +1,8 @@ --- apiVersion: v1 -kind: List +kind: PodList items: + - apiVersion: v1 kind: Pod metadata: @@ -62,6 +63,7 @@ items: phase: Running podIPs: - ip: 172.1.0.3 + - apiVersion: v1 kind: Pod metadata: diff --git a/internal/lint/testdata/net/np/1.yaml b/internal/lint/testdata/net/np/1.yaml index e25a10c4..e0c05859 100644 --- a/internal/lint/testdata/net/np/1.yaml +++ b/internal/lint/testdata/net/np/1.yaml @@ -1,6 +1,7 @@ -apiVersion: v1 -kind: List +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicyList items: + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -35,12 +36,14 @@ items: ports: - protocol: TCP port: 5978 + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: np2 namespace: default spec: + podSelector: {} ingress: - from: - ipBlock: @@ -66,6 +69,7 @@ items: ports: - protocol: TCP port: 5978 + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/internal/lint/testdata/net/np/2.yaml b/internal/lint/testdata/net/np/2.yaml index 0d088d36..7ecea392 100644 --- a/internal/lint/testdata/net/np/2.yaml +++ b/internal/lint/testdata/net/np/2.yaml @@ -1,6 +1,7 @@ -apiVersion: v1 -kind: List +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicyList items: + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -29,6 +30,7 @@ items: podSelector: {} policyTypes: - Egress + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -54,6 +56,7 @@ items: - {} policyTypes: - Ingress + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -82,6 +85,7 @@ items: policyTypes: - Ingress - Egress + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/internal/lint/testdata/net/np/3.yaml b/internal/lint/testdata/net/np/3.yaml index 3ae4bad3..10548950 100644 --- a/internal/lint/testdata/net/np/3.yaml +++ b/internal/lint/testdata/net/np/3.yaml @@ -1,6 +1,7 @@ -apiVersion: v1 -kind: List +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicyList items: + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -10,15 +11,14 @@ items: podSelector: {} policyTypes: - Ingress + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-egress namespace: ns2 spec: - # podSelector: - # matchLabels: - # app: p2 + podSelector: {} ingress: - from: - namespaceSelector: diff --git a/internal/lint/testdata/net/np/blee.yml b/internal/lint/testdata/net/np/blee.yml new file mode 100644 index 00000000..86a03d3d --- /dev/null +++ b/internal/lint/testdata/net/np/blee.yml @@ -0,0 +1,34 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: np1 + namespace: default +spec: + podSelector: + matchLabels: + app: p1 + policyTypes: + - Ingress + - Egress + ingress: + - from: + - ipBlock: + cidr: 172.1.0.0/16 + except: + - 172.1.0.0/24 + - namespaceSelector: + matchLabels: + ns: default + podSelector: + matchLabels: + app: p1 + ports: + - protocol: TCP + port: 6379 + egress: + - to: + - ipBlock: + cidr: 172.1.0.0/16 + ports: + - protocol: TCP + port: 5978 From a1ea9fe24c6530fdbd407cddcb95de938e8b1877 Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 30 Dec 2024 12:55:39 -0700 Subject: [PATCH 8/8] rel v0.21.6 --- .github/dependabot.yaml | 8 -------- Makefile | 2 +- README.md | 8 ++++++-- change_logs/release_v0.21.6.md | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 11 deletions(-) delete mode 100644 .github/dependabot.yaml create mode 100644 change_logs/release_v0.21.6.md diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml deleted file mode 100644 index 76ccfc89..00000000 --- a/.github/dependabot.yaml +++ /dev/null @@ -1,8 +0,0 @@ -version: 2 -updates: -- package-ecosystem: "gomod" - directory: "/" - allow: - - dependency-type: "all" -- package-ecosystem: "github-actions" - directory: "/" diff --git a/Makefile b/Makefile index 21f55d70..a6b085d0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ NAME := popeye PACKAGE := github.com/derailed/$(NAME) -VERSION := v0.21.5 +VERSION := v0.21.6 GIT := $(shell git rev-parse --short HEAD) DATE := $(shell date +%FT%T%Z) IMG_NAME := derailed/popeye diff --git a/README.md b/README.md index 8cffedd9..ed7d1033 100644 --- a/README.md +++ b/README.md @@ -125,10 +125,14 @@ popeye popeye -n fred # Run Popeye in all namespaces popeye -A -# Popeye uses a spinach config file of course! aka spinachyaml! +# Run Popeye uses a spinach config file of course! aka spinachyaml! popeye -f spinach.yaml -# Popeye a cluster using a kubeconfig context. +# Run Popeye a cluster using a kubeconfig context. popeye --context olive +# Run Popeye with specific linters and log to the console +popeye -n ns1 -s pod,svc --logs none +# Run Popeye for a given namespace in a given log file and debug logs +popeye -n ns1 --logs /tmp/fred.log -v4 # Stuck? popeye help ``` diff --git a/change_logs/release_v0.21.6.md b/change_logs/release_v0.21.6.md new file mode 100644 index 00000000..b9612a32 --- /dev/null +++ b/change_logs/release_v0.21.6.md @@ -0,0 +1,32 @@ + + +# Release v0.21.6 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for Popeye! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make Popeye better is as ever very much noticed and appreciated! + +This project offers a GitHub Sponsor button (over here 👆). As you well know this is not pimped out by big corps with deep pockets. If you feel `Popeye` is saving you cycles diagnosing potential cluster issues please consider sponsoring this project!! It does go a long way in keeping our servers lights on and beers in our fridge. + +Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +--- + +## Maintenance Release + +--- + +## Resolved Issues + +* [#370](https://github.com/derailed/popeye/issues/370) default service account check +* [#356](https://github.com/derailed/popeye/issues/356) Allow foreground execution, with output to STDOUT/STDERR and disabling output to popeye.log file +* [#341](https://github.com/derailed/popeye/issues/341) Linter Node : no linters matched query +* [#337](https://github.com/derailed/popeye/issues/337) Output logs in stdout instead of file +* [#301](https://github.com/derailed/popeye/issues/301) Allow Popeye to be used by more than one user on a host (/tmp/popeye.log permission problem) +* [#267](https://github.com/derailed/popeye/issues/267) Allow container exclusions based on regex +* [#200](https://github.com/derailed/popeye/issues/200) Can't filter containers in spinach.yaml for deployments +* [#168](https://github.com/derailed/popeye/issues/168) Skip checks at container level + +--- + +  © 2024 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)