diff --git a/deploy/charts/version-checker/templates/clusterrole.yaml b/deploy/charts/version-checker/templates/clusterrole.yaml index c9d54df7..63c1be3e 100644 --- a/deploy/charts/version-checker/templates/clusterrole.yaml +++ b/deploy/charts/version-checker/templates/clusterrole.yaml @@ -9,6 +9,7 @@ rules: - "" resources: - "pods" + - "nodes" verbs: - "get" - "list" diff --git a/deploy/charts/version-checker/values.yaml b/deploy/charts/version-checker/values.yaml index 132ca626..84ecb46d 100644 --- a/deploy/charts/version-checker/values.yaml +++ b/deploy/charts/version-checker/values.yaml @@ -108,7 +108,6 @@ selfhosted: # password: bar # token: - # -- Setup version-checkers resource requests/limits resources: {} @@ -121,7 +120,8 @@ resources: # # -- Set container-level security context -securityContext: {} +securityContext: + {} # allowPrivilegeEscalation: false # capabilities: # drop: diff --git a/deploy/yaml/deploy.yaml b/deploy/yaml/deploy.yaml index aac17973..6e7d40cf 100644 --- a/deploy/yaml/deploy.yaml +++ b/deploy/yaml/deploy.yaml @@ -49,33 +49,33 @@ spec: spec: serviceAccountName: version-checker containers: - - image: quay.io/jetstack/version-checker:v0.7.0 - imagePullPolicy: Always - ports: - - containerPort: 8080 - name: version-checker - command: ["version-checker"] - livenessProbe: - httpGet: - path: /readyz - port: 8080 - initialDelaySeconds: 3 - periodSeconds: 3 - readinessProbe: - httpGet: - path: /readyz - port: 8080 - initialDelaySeconds: 3 - periodSeconds: 3 + - image: quay.io/jetstack/version-checker:v0.7.0 + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: version-checker + command: ["version-checker"] + livenessProbe: + httpGet: + path: /readyz + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /readyz + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 3 --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: version-checker rules: -- apiGroups: [""] - resources: ["pods"] - verbs: ["get", "watch", "list"] + - apiGroups: [""] + resources: ["pods", "nodes"] + verbs: ["get", "watch", "list"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 @@ -86,6 +86,6 @@ roleRef: kind: ClusterRole name: version-checker subjects: -- kind: ServiceAccount - name: version-checker - namespace: version-checker + - kind: ServiceAccount + name: version-checker + namespace: version-checker diff --git a/go.mod b/go.mod index cece0765..41cc15e1 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ toolchain go1.22.3 require ( github.com/Azure/go-autorest/autorest v0.11.29 github.com/Azure/go-autorest/autorest/adal v0.9.24 - github.com/aws/aws-sdk-go-v2 v1.30.0 + github.com/aws/aws-sdk-go-v2 v1.30.1 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/hashicorp/go-retryablehttp v0.7.7 github.com/prometheus/client_golang v1.19.1 @@ -28,12 +28,12 @@ require ( ) require ( - github.com/aws/aws-sdk-go-v2/config v1.27.21 - github.com/aws/aws-sdk-go-v2/credentials v1.17.21 - github.com/aws/aws-sdk-go-v2/service/ecr v1.29.1 + github.com/aws/aws-sdk-go-v2/config v1.27.24 + github.com/aws/aws-sdk-go-v2/credentials v1.17.24 + github.com/aws/aws-sdk-go-v2/service/ecr v1.30.1 github.com/gofri/go-github-ratelimit v1.1.0 - github.com/google/go-containerregistry v0.19.0 - github.com/google/go-github/v58 v58.0.0 + github.com/google/go-containerregistry v0.20.0 + github.com/google/go-github/v62 v62.0.0 ) require ( @@ -42,25 +42,25 @@ require ( github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.8 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.12 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.12 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.14 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.21.1 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.25.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.29.1 // indirect - github.com/aws/smithy-go v1.20.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect + github.com/aws/smithy-go v1.20.3 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/docker/cli v24.0.0+incompatible // indirect - github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v24.0.9+incompatible // indirect - github.com/docker/docker-credential-helpers v0.7.0 // indirect + github.com/docker/cli v27.0.3+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v27.0.3+incompatible // indirect + github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/evanphx/json-patch v5.9.0+incompatible // indirect github.com/go-errors/errors v1.5.1 // indirect @@ -85,7 +85,7 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.16.5 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -95,20 +95,20 @@ require ( github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc3 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/vbatts/tar-split v0.11.3 // indirect + github.com/vbatts/tar-split v0.11.5 // indirect github.com/xlab/treeprint v1.2.0 // indirect - go.starlark.net v0.0.0-20240520160348-046347dcd104 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/net v0.26.0 // indirect + go.starlark.net v0.0.0-20240705175910-70002002b310 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/protobuf v1.34.2 // indirect @@ -117,7 +117,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a // indirect + k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.17.2 // indirect sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect diff --git a/go.sum b/go.sum index 699e53f6..c0c04d1c 100644 --- a/go.sum +++ b/go.sum @@ -19,32 +19,58 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/aws/aws-sdk-go-v2 v1.30.0 h1:6qAwtzlfcTtcL8NHtbDQAqgM5s6NDipQTkPxyH/6kAA= github.com/aws/aws-sdk-go-v2 v1.30.0/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= +github.com/aws/aws-sdk-go-v2 v1.30.1 h1:4y/5Dvfrhd1MxRDD77SrfsDaj8kUkkljU7XE83NPV+o= +github.com/aws/aws-sdk-go-v2 v1.30.1/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= github.com/aws/aws-sdk-go-v2/config v1.27.21 h1:yPX3pjGCe2hJsetlmGNB4Mngu7UPmvWPzzWCv1+boeM= github.com/aws/aws-sdk-go-v2/config v1.27.21/go.mod h1:4XtlEU6DzNai8RMbjSF5MgGZtYvrhBP/aKZcRtZAVdM= +github.com/aws/aws-sdk-go-v2/config v1.27.24 h1:NM9XicZ5o1CBU/MZaHwFtimRpWx9ohAUAqkG6AqSqPo= +github.com/aws/aws-sdk-go-v2/config v1.27.24/go.mod h1:aXzi6QJTuQRVVusAO8/NxpdTeTyr/wRcybdDtfUwJSs= github.com/aws/aws-sdk-go-v2/credentials v1.17.21 h1:pjAqgzfgFhTv5grc7xPHtXCAaMapzmwA7aU+c/SZQGw= github.com/aws/aws-sdk-go-v2/credentials v1.17.21/go.mod h1:nhK6PtBlfHTUDVmBLr1dg+WHCOCK+1Fu/WQyVHPsgNQ= +github.com/aws/aws-sdk-go-v2/credentials v1.17.24 h1:YclAsrnb1/GTQNt2nzv+756Iw4mF8AOzcDfweWwwm/M= +github.com/aws/aws-sdk-go-v2/credentials v1.17.24/go.mod h1:Hld7tmnAkoBQdTMNYZGzztzKRdA4fCdn9L83LOoigac= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.8 h1:FR+oWPFb/8qMVYMWN98bUZAGqPvLHiyqg1wqQGfUAXY= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.8/go.mod h1:EgSKcHiuuakEIxJcKGzVNWh5srVAQ3jKaSrBGRYvM48= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 h1:Aznqksmd6Rfv2HQN9cpqIV/lQRMaIpJkLLaJ1ZI76no= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.12 h1:SJ04WXGTwnHlWIODtC5kJzKbeuHt+OUNOgKg7nfnUGw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.12/go.mod h1:FkpvXhA92gb3GE9LD6Og0pHHycTxW7xGpnEh5E7Opwo= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13 h1:5SAoZ4jYpGH4721ZNoS1znQrhOfZinOhc4XuTXx/nVc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13/go.mod h1:+rdA6ZLpaSeM7tSg/B0IEDinCIBJGmW8rKDFkYpP04g= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.12 h1:hb5KgeYfObi5MHkSSZMEudnIvX30iB+E21evI4r6BnQ= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.12/go.mod h1:CroKe/eWJdyfy9Vx4rljP5wTUjNJfb+fPz1uMYUhEGM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13 h1:WIijqeaAO7TYFLbhsZmi2rgLEAtWOC1LhxCAVTJlSKw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13/go.mod h1:i+kbfa76PQbWw/ULoWnp51EYVWH4ENln76fLQE3lXT8= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= github.com/aws/aws-sdk-go-v2/service/ecr v1.29.1 h1:ywNLJrn/Qn4enDsz/XnKlvpnLqvJxFGQV2BltWltbis= github.com/aws/aws-sdk-go-v2/service/ecr v1.29.1/go.mod h1:WadVIk+UrTvWuAsCp6BKGX4i2snurpz8mPWhJQnS7Dg= +github.com/aws/aws-sdk-go-v2/service/ecr v1.30.1 h1:zV3FlyuyPzfyFOXKu6mJW9JBGzdtOgpdlj3va+naOD8= +github.com/aws/aws-sdk-go-v2/service/ecr v1.30.1/go.mod h1:l0zC7cSb2vAH1fr8+BRlolWT9cwlKpbRC8PjW6tyyIU= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.14 h1:zSDPny/pVnkqABXYRicYuPf9z2bTqfH13HT3v6UheIk= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.14/go.mod h1:3TTcI5JSzda1nw/pkVC9dhgLre0SNBFj2lYS4GctXKI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15 h1:I9zMeF107l0rJrpnHpjEiiTSCKYAIw8mALiXcPsGBiA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15/go.mod h1:9xWJ3Q/S6Ojusz1UIkfycgD1mGirJfLLKqq3LPT7WN8= github.com/aws/aws-sdk-go-v2/service/sso v1.21.1 h1:sd0BsnAvLH8gsp2e3cbaIr+9D7T1xugueQ7V/zUAsS4= github.com/aws/aws-sdk-go-v2/service/sso v1.21.1/go.mod h1:lcQG/MmxydijbeTOp04hIuJwXGWPZGI3bwdFDGRTv14= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 h1:p1GahKIjyMDZtiKoIn0/jAj/TkMzfzndDv5+zi2Mhgc= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.25.1 h1:1uEFNNskK/I1KoZ9Q8wJxMz5V9jyBlsiaNrM7vA3YUQ= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.25.1/go.mod h1:z0P8K+cBIsFXUr5rzo/psUeJ20XjPN0+Nn8067Nd+E4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 h1:ORnrOK0C4WmYV/uYt3koHEWBLYsRDwk2Np+eEoyV4Z0= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2/go.mod h1:xyFHA4zGxgYkdD73VeezHt3vSKEG9EmFnGwoKlP00u4= github.com/aws/aws-sdk-go-v2/service/sts v1.29.1 h1:myX5CxqXE0QMZNja6FA1/FSE3Vu1rVmeUmpJMMzeZg0= github.com/aws/aws-sdk-go-v2/service/sts v1.29.1/go.mod h1:N2mQiucsO0VwK9CYuS4/c2n6Smeh1v47Rz3dWCPFLdE= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 h1:+woJ607dllHJQtsnJLi52ycuqHMwlW+Wqm2Ppsfp4nQ= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.1/go.mod h1:jiNR3JqT15Dm+QWq2SRgh0x0bCNSRP2L25+CqPNpJlQ= github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= +github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= 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= @@ -53,6 +79,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= +github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= +github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= @@ -63,12 +91,20 @@ 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/docker/cli v24.0.0+incompatible h1:0+1VshNwBQzQAx9lOl+OYCTCEAD8fKs/qeXMx3O0wqM= github.com/docker/cli v24.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.0.3+incompatible h1:usGs0/BoBW8MWxGeEtqPMkzOY56jZ6kYlSN5BLDioCQ= +github.com/docker/cli v27.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.0.3+incompatible h1:aBGI9TeQ4MPlhquTQKq9XbK79rKFVwXNUAYz9aXyEBE= +github.com/docker/docker v27.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= +github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= @@ -109,8 +145,10 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.19.0 h1:uIsMRBV7m/HDkDxE/nXMnv1q+lOOSPlQ/ywc5JbB8Ic= github.com/google/go-containerregistry v0.19.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= -github.com/google/go-github/v58 v58.0.0 h1:Una7GGERlF/37XfkPwpzYJe0Vp4dt2k1kCjlxwjIvzw= -github.com/google/go-github/v58 v58.0.0/go.mod h1:k4hxDKEfoWpSqFlc8LTpGd9fu2KrV1YAa6Hi6FmDNY4= +github.com/google/go-containerregistry v0.20.0 h1:wRqHpOeVh3DnenOrPy9xDOLdnLatiGuuNRVelR2gSbg= +github.com/google/go-containerregistry v0.20.0/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= +github.com/google/go-github/v62 v62.0.0 h1:/6mGCaRywZz9MuHyw9gD1CwsbmBX8GWsbFkwMmHdhl4= +github.com/google/go-github/v62 v62.0.0/go.mod h1:EMxeUqGJq2xRu9DYBMwel/mr7kZrzUOfQmmpYrZn2a4= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -146,6 +184,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -179,6 +219,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -192,6 +234,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= @@ -221,6 +265,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= +github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= +github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -228,6 +274,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.starlark.net v0.0.0-20240520160348-046347dcd104 h1:3qhteRISupnJvaWshOmeqEUs2y9oc/+/ePPvDh3Eygg= go.starlark.net v0.0.0-20240520160348-046347dcd104/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8= +go.starlark.net v0.0.0-20240705175910-70002002b310 h1:tEAOMoNmN2MqVNi0MMEWpTtPI4YNCXgxmAGtuv3mST0= +go.starlark.net v0.0.0-20240705175910-70002002b310/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -239,6 +287,8 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58 golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= 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/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -254,6 +304,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -279,6 +331,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -286,6 +340,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -340,6 +396,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-20240521193020-835d969ad83a h1:zD1uj3Jf+mD4zmA7W+goE5TxDkI7OGJjBNBzq5fJtLA= k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= +k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6zX/gcJr22cjrsej+W784Tc= +k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/pkg/api/types.go b/pkg/api/types.go index b7a6cbb0..ed0aba61 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -58,6 +58,10 @@ type Options struct { PinPatch *int64 `json:"pin-patch,omitempty"` RegexMatcher *regexp.Regexp `json:"-"` + + // Architecture and OS to search for + Architecture *Architecture `json:"pin-architecture,omitempty"` + OS *OS `json:"pin-os,omitempty"` } // ImageTag describes a container image tag. @@ -67,6 +71,7 @@ type ImageTag struct { Timestamp time.Time `json:"timestamp"` OS OS `json:"os,omitempty"` Architecture Architecture `json:"architecture,omitempty"` + Children []ImageTag `json:"children,omitempty"` } type OS string diff --git a/pkg/client/ghcr/ghcr.go b/pkg/client/ghcr/ghcr.go index 169a12f0..03e7f6ba 100644 --- a/pkg/client/ghcr/ghcr.go +++ b/pkg/client/ghcr/ghcr.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/gofri/go-github-ratelimit/github_ratelimit" - "github.com/google/go-github/v58/github" + "github.com/google/go-github/v62/github" "github.com/jetstack/version-checker/pkg/api" ) diff --git a/pkg/client/quay/quay.go b/pkg/client/quay/quay.go index ca6031e9..fce572bb 100644 --- a/pkg/client/quay/quay.go +++ b/pkg/client/quay/quay.go @@ -102,7 +102,6 @@ func (c *Client) fetchImageManifest(ctx context.Context, repo, image string, tag } // Fallback to not using multi-arch image - os, arch := util.OSArchFromTag(tag.Name) return []api.ImageTag{ diff --git a/pkg/controller/checker/architecture/architecture.go b/pkg/controller/checker/architecture/architecture.go new file mode 100644 index 00000000..4f025518 --- /dev/null +++ b/pkg/controller/checker/architecture/architecture.go @@ -0,0 +1,74 @@ +package architecture + +import ( + "errors" + "fmt" + "sync" + + corev1 "k8s.io/api/core/v1" + + "github.com/jetstack/version-checker/pkg/api" + "github.com/sirupsen/logrus" +) + +// NodeMetadata metadata about a particular node +type nodeMetadata struct { + OS api.OS + Architecture api.Architecture +} + +type NodeMap struct { + mu sync.RWMutex + nodes map[string]*nodeMetadata +} + +func New() *NodeMap { + // might need to pass an initial map + return &NodeMap{ + nodes: make(map[string]*nodeMetadata), + } +} + +func (m *NodeMap) GetArchitecture(nodeName string) (*nodeMetadata, bool) { + m.mu.RLock() + defer m.mu.RUnlock() + + meta, ok := m.nodes[nodeName] + return meta, ok +} + +func (m *NodeMap) Add(node *corev1.Node) error { + m.mu.Lock() + defer m.mu.Unlock() + if node == nil { + return errors.New("passed node is nil") + } + + arch, ok := node.Labels[corev1.LabelArchStable] + if !ok { + return fmt.Errorf("missing %q label on node %q", corev1.LabelArchStable, node.Name) + } + + os, ok := node.Labels[corev1.LabelOSStable] + if !ok { + return fmt.Errorf("missing %q label on node %q", corev1.LabelOSStable, node.Name) + } + + logrus.WithField("module", "architecture"). + WithField("node", node.Name). + WithField("os", os). + WithField("arch", arch). + Debug("node successfully added") + + m.nodes[node.Name] = &nodeMetadata{ + OS: api.OS(os), + Architecture: api.Architecture(arch), + } + return nil +} + +func (m *NodeMap) Delete(nodeName string) { + m.mu.Lock() + defer m.mu.Unlock() + delete(m.nodes, nodeName) +} diff --git a/pkg/controller/checker/checker.go b/pkg/controller/checker/checker.go index 1ba6b147..47ce066d 100644 --- a/pkg/controller/checker/checker.go +++ b/pkg/controller/checker/checker.go @@ -2,12 +2,14 @@ package checker import ( "context" + "errors" "fmt" "strings" corev1 "k8s.io/api/core/v1" "github.com/jetstack/version-checker/pkg/api" + "github.com/jetstack/version-checker/pkg/controller/checker/architecture" "github.com/jetstack/version-checker/pkg/controller/search" "github.com/jetstack/version-checker/pkg/version/semver" "github.com/sirupsen/logrus" @@ -15,6 +17,7 @@ import ( type Checker struct { search search.Searcher + nodes *architecture.NodeMap } type Result struct { @@ -22,11 +25,18 @@ type Result struct { LatestVersion string IsLatest bool ImageURL string + OS api.OS + Architecture api.Architecture } -func New(search search.Searcher) *Checker { +const ( + nodeMissingMetadata = "error fetching node architecture" +) + +func New(search search.Searcher, nodesArchInfo *architecture.NodeMap) *Checker { return &Checker{ search: search, + nodes: nodesArchInfo, } } @@ -34,6 +44,20 @@ func New(search search.Searcher) *Checker { func (c *Checker) Container(ctx context.Context, log *logrus.Entry, pod *corev1.Pod, container *corev1.Container, opts *api.Options) (*Result, error) { + if opts == nil { + // create new options if nil + opts = new(api.Options) + } + + // Get information about the pod node architecture + arch, ok := c.nodes.GetArchitecture(pod.Spec.NodeName) + if ok { + opts.OS = &arch.OS + opts.Architecture = &arch.Architecture + } else { + return nil, errors.New(nodeMissingMetadata) + } + // If the container image SHA status is not ready yet, exit early statusSHA := containerStatusImageSHA(pod, container.Name) if len(statusSHA) == 0 { @@ -90,6 +114,8 @@ func (c *Checker) Container(ctx context.Context, log *logrus.Entry, LatestVersion: latestVersion, IsLatest: isLatest, ImageURL: imageURL, + OS: latestImage.OS, + Architecture: latestImage.Architecture, }, nil } @@ -174,6 +200,8 @@ func (c *Checker) isLatestSHA(ctx context.Context, imageURL, currentSHA string, LatestVersion: latestVersion, IsLatest: isLatest, ImageURL: imageURL, + OS: latestImage.OS, + Architecture: latestImage.Architecture, }, nil } diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 2f63cec4..ea840180 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -18,6 +18,8 @@ import ( "github.com/jetstack/version-checker/pkg/client" "github.com/jetstack/version-checker/pkg/controller/checker" + "github.com/jetstack/version-checker/pkg/controller/checker/architecture" + "github.com/jetstack/version-checker/pkg/controller/nodes" "github.com/jetstack/version-checker/pkg/controller/scheduler" "github.com/jetstack/version-checker/pkg/controller/search" "github.com/jetstack/version-checker/pkg/metrics" @@ -38,6 +40,9 @@ type Controller struct { workqueue workqueue.RateLimitingInterface scheduledWorkQueue scheduler.ScheduledWorkQueue + nodesArchitecture *architecture.NodeMap + nodeController *nodes.NodeInformer + metrics *metrics.Metrics checker *checker.Checker @@ -56,17 +61,23 @@ func New( scheduledWorkQueue := scheduler.NewScheduledWorkQueue(clock.RealClock{}, workqueue.Add) log = log.WithField("module", "controller") + nodesArchitecture := architecture.New() + versionGetter := version.New(log, imageClient, cacheTimeout) search := search.New(log, cacheTimeout, versionGetter) + nodeController := nodes.New(log, nodesArchitecture) + c := &Controller{ log: log, kubeClient: kubeClient, workqueue: workqueue, scheduledWorkQueue: scheduledWorkQueue, metrics: metrics, - checker: checker.New(search), + checker: checker.New(search, nodesArchitecture), defaultTestAll: defaultTestAll, + nodesArchitecture: nodesArchitecture, + nodeController: nodeController, } return c @@ -78,6 +89,8 @@ func (c *Controller) Run(ctx context.Context, cacheRefreshRate time.Duration) er sharedInformerFactory := informers.NewSharedInformerFactoryWithOptions(c.kubeClient, time.Second*30) c.podLister = sharedInformerFactory.Core().V1().Pods().Lister() + nodeInformer := c.nodeController.Register(sharedInformerFactory) + podInformer := sharedInformerFactory.Core().V1().Pods().Informer() podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: c.addObject, @@ -92,7 +105,7 @@ func (c *Controller) Run(ctx context.Context, cacheRefreshRate time.Duration) er c.log.Info("starting control loop") sharedInformerFactory.Start(ctx.Done()) - if !cache.WaitForCacheSync(ctx.Done(), podInformer.HasSynced) { + if !cache.WaitForCacheSync(ctx.Done(), nodeInformer.HasSynced, podInformer.HasSynced) { return fmt.Errorf("error waiting for informer caches to sync") } diff --git a/pkg/controller/nodes/nodes.go b/pkg/controller/nodes/nodes.go new file mode 100644 index 00000000..a09c346a --- /dev/null +++ b/pkg/controller/nodes/nodes.go @@ -0,0 +1,56 @@ +package nodes + +import ( + "github.com/jetstack/version-checker/pkg/controller/checker/architecture" + "github.com/sirupsen/logrus" + + corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/informers" + "k8s.io/client-go/tools/cache" +) + +// NodeInformer is the wrapper for the k8s Node Informer +type NodeInformer struct { + log *logrus.Entry + nodes *architecture.NodeMap +} + +// New returns a new instance of NodeInformer +func New(log *logrus.Entry, nodes *architecture.NodeMap) *NodeInformer { + return &NodeInformer{ + log: log.WithField("module", "controller_node"), + nodes: nodes, + } +} + +// Register returns the node informer with event handler set to update node architecture map +func (c *NodeInformer) Register(sharedInformerFactory informers.SharedInformerFactory) cache.SharedIndexInformer { + nodeInformer := sharedInformerFactory.Core().V1().Nodes().Informer() + nodeInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + // Add node info and data to the map + err := c.nodes.Add(obj.(*corev1.Node)) + if err != nil { + c.log.Errorf("error adding the node %q to architecture map: %s", obj.(*corev1.Node), err) + return + } + c.log.Debugf("added node %q to architecture map", obj.(*corev1.Node).Name) + }, + UpdateFunc: func(old, new interface{}) { + // override the map + err := c.nodes.Add(new.(*corev1.Node)) + if err != nil { + c.log.Errorf("error updating the node %q in architecture map: %s", old.(*corev1.Node), err) + return + } + c.log.Debugf("updated node %q in architecture map", old.(*corev1.Node).Name) + }, + DeleteFunc: func(obj interface{}) { + // remove node from the map + c.nodes.Delete((obj.(*corev1.Node)).Name) + c.log.Debugf("removed node %q from architecture map", obj.(*corev1.Node).Name) + }, + }) + + return nodeInformer +} diff --git a/pkg/controller/search/search.go b/pkg/controller/search/search.go index 43e3086c..d4c291cd 100644 --- a/pkg/controller/search/search.go +++ b/pkg/controller/search/search.go @@ -79,10 +79,10 @@ func calculateHashIndex(imageURL string, opts *api.Options) (string, error) { return "", fmt.Errorf("failed to marshal options: %s", err) } - hash := fnv.New32() + hash := fnv.New64() if _, err := hash.Write(append(optsJSON, []byte(imageURL)...)); err != nil { return "", fmt.Errorf("failed to calculate search hash: %s", err) } - return fmt.Sprintf("%d", hash.Sum32()), nil + return fmt.Sprintf("%d", hash.Sum64()), nil } diff --git a/pkg/controller/sync.go b/pkg/controller/sync.go index 6b5a33ae..d0e8351f 100644 --- a/pkg/controller/sync.go +++ b/pkg/controller/sync.go @@ -10,6 +10,7 @@ import ( "github.com/jetstack/version-checker/pkg/api" "github.com/jetstack/version-checker/pkg/controller/options" + "github.com/jetstack/version-checker/pkg/metrics" versionerrors "github.com/jetstack/version-checker/pkg/version/errors" ) @@ -86,18 +87,25 @@ func (c *Controller) checkContainer(ctx context.Context, log *logrus.Entry, pod } if result.IsLatest { - log.Debugf("image is latest %s:%s", - result.ImageURL, result.CurrentVersion) + log.Debugf("image is latest %s [%s/%s]:%s", + result.ImageURL, result.OS, result.Architecture, result.CurrentVersion) } else { - log.Debugf("image is not latest %s: %s -> %s", - result.ImageURL, result.CurrentVersion, result.LatestVersion) + log.Debugf("image is not latest %s [%s/%s]: %s -> %s", + result.ImageURL, result.OS, result.Architecture, result.CurrentVersion, result.LatestVersion) } - c.metrics.AddImage(pod.Namespace, pod.Name, - container.Name, containerType, - result.ImageURL, result.IsLatest, - result.CurrentVersion, result.LatestVersion, - ) + c.metrics.AddImage(&metrics.Entry{ + Namespace: pod.Namespace, + Pod: pod.Name, + Container: container.Name, + ContainerType: containerType, + ImageURL: result.ImageURL, + IsLatest: result.IsLatest, + CurrentVersion: result.CurrentVersion, + LatestVersion: result.LatestVersion, + OS: string(result.OS), + Arch: string(result.Architecture), + }) return nil } diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 58b10e70..b32ab86a 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -34,6 +34,22 @@ type cacheItem struct { image string currentVersion string latestVersion string + os string + arch string +} + +// Entry is a struct containing a single metrics label set +type Entry struct { + Namespace string + Pod string + Container string + ContainerType string + ImageURL string + IsLatest bool + CurrentVersion string + LatestVersion string + OS string + Arch string } func New(log *logrus.Entry) *Metrics { @@ -44,7 +60,7 @@ func New(log *logrus.Entry) *Metrics { Help: "Where the container in use is using the latest upstream registry version", }, []string{ - "namespace", "pod", "container", "container_type", "image", "current_version", "latest_version", + "namespace", "pod", "container", "container_type", "image", "current_version", "latest_version", "architecture", "os", }, ) @@ -91,27 +107,29 @@ func (m *Metrics) Run(servingAddress string) error { return nil } -func (m *Metrics) AddImage(namespace, pod, container, containerType, imageURL string, isLatest bool, currentVersion, latestVersion string) { +func (m *Metrics) AddImage(entry *Entry) { // Remove old image url/version if it exists - m.RemoveImage(namespace, pod, container, containerType) + m.RemoveImage(entry.Namespace, entry.Pod, entry.Container, entry.ContainerType) m.mu.Lock() defer m.mu.Unlock() isLatestF := 0.0 - if isLatest { + if entry.IsLatest { isLatestF = 1.0 } m.containerImageVersion.With( - m.buildLabels(namespace, pod, container, containerType, imageURL, currentVersion, latestVersion), + m.buildLabels(entry), ).Set(isLatestF) - index := m.latestImageIndex(namespace, pod, container, containerType) + index := m.latestImageIndex(entry.Namespace, entry.Pod, entry.Container, entry.ContainerType) m.containerCache[index] = cacheItem{ - image: imageURL, - currentVersion: currentVersion, - latestVersion: latestVersion, + image: entry.ImageURL, + currentVersion: entry.CurrentVersion, + latestVersion: entry.LatestVersion, + os: entry.OS, + arch: entry.Arch, } } @@ -126,7 +144,16 @@ func (m *Metrics) RemoveImage(namespace, pod, container, containerType string) { } m.containerImageVersion.Delete( - m.buildLabels(namespace, pod, container, containerType, item.image, item.currentVersion, item.latestVersion), + m.buildLabels(&Entry{ + Namespace: namespace, + Pod: pod, + Container: container, + ImageURL: item.image, + CurrentVersion: item.currentVersion, + LatestVersion: item.latestVersion, + OS: item.os, + Arch: item.arch, + }), ) delete(m.containerCache, index) } @@ -135,15 +162,17 @@ func (m *Metrics) latestImageIndex(namespace, pod, container, containerType stri return strings.Join([]string{namespace, pod, container, containerType}, "") } -func (m *Metrics) buildLabels(namespace, pod, container, containerType, imageURL, currentVersion, latestVersion string) prometheus.Labels { +func (m *Metrics) buildLabels(entry *Entry) prometheus.Labels { return prometheus.Labels{ - "namespace": namespace, - "pod": pod, - "container_type": containerType, - "container": container, - "image": imageURL, - "current_version": currentVersion, - "latest_version": latestVersion, + "namespace": entry.Namespace, + "pod": entry.Pod, + "container": entry.Container, + "container_type": entry.ContainerType, + "image": entry.ImageURL, + "current_version": entry.CurrentVersion, + "latest_version": entry.LatestVersion, + "architecture": entry.Arch, + "os": entry.OS, } } diff --git a/pkg/version/utils.go b/pkg/version/utils.go new file mode 100644 index 00000000..a5ffafb4 --- /dev/null +++ b/pkg/version/utils.go @@ -0,0 +1,89 @@ +package version + +import ( + "github.com/jetstack/version-checker/pkg/api" + "github.com/jetstack/version-checker/pkg/version/semver" +) + +// latestSemver will return the latest ImageTag based on the given options +// restriction, using semver. This should not be used is UseSHA has been +// enabled. +// TODO: add tests.. +func latestSemver(tags []api.ImageTag, opts *api.Options) (*api.ImageTag, error) { + var ( + latestImageTag *api.ImageTag + latestV *semver.SemVer + ) + + for i := range tags { + // forcing it be the specific arch and os (defalts to true, if not set) + if !osArchMatch(tags[i], opts) { + continue + } + + v := semver.Parse(tags[i].Tag) + + // If regex enabled continue here. + // If we match, and is less than, update latest. + if opts.RegexMatcher != nil { + if opts.RegexMatcher.MatchString(tags[i].Tag) && + (latestV == nil || latestV.LessThan(v)) { + latestV = v + latestImageTag = &tags[i] + } + + continue + } + + // If we have declared we wont use metadata but version has it, continue. + if !opts.UseMetaData && v.HasMetaData() { + continue + } + + if opts.PinMajor != nil && *opts.PinMajor != v.Major() { + continue + } + if opts.PinMinor != nil && *opts.PinMinor != v.Minor() { + continue + } + if opts.PinPatch != nil && *opts.PinPatch != v.Patch() { + continue + } + + // If no latest yet set + if latestV == nil || + // If the latest set is less than + latestV.LessThan(v) || + // If the latest is the same tag, but smaller timestamp + (latestV.Equal(v) && tags[i].Timestamp.After(latestImageTag.Timestamp)) { + latestV = v + latestImageTag = &tags[i] + } + } + + return latestImageTag, nil +} + +// latestSHA will return the latest ImageTag based on image timestamps. +func latestSHA(tags []api.ImageTag, opts *api.Options) (*api.ImageTag, error) { + var latestTag *api.ImageTag + + for i := range tags { + // forcing it be the specific arch and os (defalts to true, if not set) + if !osArchMatch(tags[i], opts) { + continue + } + if latestTag == nil || tags[i].Timestamp.After(latestTag.Timestamp) { + latestTag = &tags[i] + } + } + + return latestTag, nil +} + +func osArchMatch(tag api.ImageTag, opts *api.Options) bool { + if opts.OS == nil || opts.Architecture == nil { + return true + } + return tag.OS == *opts.OS && tag.Architecture == *opts.Architecture +} diff --git a/pkg/version/version.go b/pkg/version/version.go index a78ef138..35996c9c 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -13,7 +13,6 @@ import ( "github.com/jetstack/version-checker/pkg/cache" versionerrors "github.com/jetstack/version-checker/pkg/version/errors" - "github.com/jetstack/version-checker/pkg/version/semver" ) type Version struct { @@ -48,6 +47,7 @@ func (v *Version) LatestTagFromImage(ctx context.Context, imageURL string, opts v.log.Debugf("overriding image lookup %s -> %s", imageURL, *override) imageURL = *override } + tagsI, err := v.imageCache.Get(ctx, imageURL, imageURL, nil) if err != nil { return nil, err @@ -58,7 +58,7 @@ func (v *Version) LatestTagFromImage(ctx context.Context, imageURL string, opts // If UseSHA then return early if opts.UseSHA { - tag, err = latestSHA(tags) + tag, err = latestSHA(tags, opts) if err != nil { return nil, err } @@ -69,7 +69,7 @@ func (v *Version) LatestTagFromImage(ctx context.Context, imageURL string, opts } } else { - tag, err = latestSemver(opts, tags) + tag, err = latestSemver(tags, opts) if err != nil { return nil, err } @@ -101,70 +101,3 @@ func (v *Version) Fetch(ctx context.Context, imageURL string, _ *api.Options) (i return tags, nil } - -// latestSemver will return the latest ImageTag based on the given options -// restriction, using semver. This should not be used is UseSHA has been -// enabled. -// TODO: add tests.. -func latestSemver(opts *api.Options, tags []api.ImageTag) (*api.ImageTag, error) { - var ( - latestImageTag *api.ImageTag - latestV *semver.SemVer - ) - - for i := range tags { - v := semver.Parse(tags[i].Tag) - - // If regex enabled continue here. - // If we match, and is less than, update latest. - if opts.RegexMatcher != nil { - if opts.RegexMatcher.MatchString(tags[i].Tag) && - (latestV == nil || latestV.LessThan(v)) { - latestV = v - latestImageTag = &tags[i] - } - - continue - } - - // If we have declared we wont use metadata but version has it, continue. - if !opts.UseMetaData && v.HasMetaData() { - continue - } - - if opts.PinMajor != nil && *opts.PinMajor != v.Major() { - continue - } - if opts.PinMinor != nil && *opts.PinMinor != v.Minor() { - continue - } - if opts.PinPatch != nil && *opts.PinPatch != v.Patch() { - continue - } - - // If no latest yet set - if latestV == nil || - // If the latest set is less than - latestV.LessThan(v) || - // If the latest is the same tag, but smaller timestamp - (latestV.Equal(v) && tags[i].Timestamp.After(latestImageTag.Timestamp)) { - latestV = v - latestImageTag = &tags[i] - } - } - - return latestImageTag, nil -} - -// latestSHA will return the latest ImageTag based on image timestamps. -func latestSHA(tags []api.ImageTag) (*api.ImageTag, error) { - var latestTag *api.ImageTag - - for i := range tags { - if latestTag == nil || tags[i].Timestamp.After(latestTag.Timestamp) { - latestTag = &tags[i] - } - } - - return latestTag, nil -}