diff --git a/.air.toml b/.air.toml new file mode 100644 index 0000000..2f1bcc3 --- /dev/null +++ b/.air.toml @@ -0,0 +1,56 @@ +root = "." +testdata_dir = "testdata" +tmp_dir = "tmp" + +[build] +args_bin = [ + "--watch-kube-secrets", + "--kubeconfig=/app/kubeconfig.yaml", + "--expose-per-cert-error-metrics", +] +bin = "tmp/x509-certificate-exporter" +cmd = "hack/air-build-server.sh" +delay = 1000 +exclude_dir = ["hack", "testdata", "tmp", "vendor"] +exclude_file = [] +exclude_regex = ["_test.go"] +exclude_unchanged = false +follow_symlink = false +full_bin = "" +include_dir = [] +include_ext = ["go", "tpl", "tmpl", "html"] +include_file = [] +kill_delay = "0s" +log = "build-errors.log" +poll = false +poll_interval = 0 +post_cmd = [] +pre_cmd = [] +rerun = false +rerun_delay = 500 +send_interrupt = false +stop_on_error = true + +[color] +app = "" +build = "yellow" +main = "magenta" +runner = "green" +watcher = "cyan" + +[log] +main_only = false +silent = false +time = false + +[misc] +clean_on_exit = false + +[proxy] +app_port = 0 +enabled = false +proxy_port = 0 + +[screen] +clear_on_rebuild = false +keep_scroll = true diff --git a/.env b/.env new file mode 100644 index 0000000..1a63eef --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +USER_ID=1000 +GROUP_ID=1000 diff --git a/.gitignore b/.gitignore index 470be27..2c8d622 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,14 @@ -__pycache__ -*.pyc +*.out +*.so +*.dylib +*.exe +*.exe~ +*.dll +*.test *.cov *.debug +*.kubeconfig.yaml +kubeconfig.yaml coverage.html -/kubeconfig* +/vendor +/tmp diff --git a/Dockerfile b/Dockerfile index 7ebe996..f80e16e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,43 +1,48 @@ -## Build Stage - -# https://github.com/hadolint/hadolint/issues/861 -# hadolint ignore=DL3029 -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23.4-alpine as build - -WORKDIR $GOPATH/src/github.com/enix/x509-certificate-exporter - +FROM --platform=$BUILDPLATFORM golang:1.23.4 AS base +WORKDIR /app + +FROM --platform=$BUILDPLATFORM cosmtrek/air:v1.61.5 AS air + +FROM base AS dev +ARG USER_ID=1000 +ARG GROUP_ID=1000 +RUN groupadd -g ${GROUP_ID} air \ + && useradd -l -u ${USER_ID} -g air air \ + && install -d -m 0700 -o air -g air /home/air +USER ${USER_ID}:${GROUP_ID} +COPY --from=air /go/bin/air /go/bin/air +CMD [ "/go/bin/air" ] + +FROM base AS build COPY go.mod go.mod COPY go.sum go.sum - -RUN go mod download - +RUN go mod download -x COPY internal internal +# COPY pkg pkg COPY cmd cmd - -ARG VERSION="devel" -ARG VCS_REF="unknown" ARG TARGETOS ARG TARGETARCH - +ARG VERSION="devel" +ARG VCS_REF="unknown" ENV GOOS=${TARGETOS} ENV GOARCH=${TARGETARCH} - -RUN go build -v \ - -tags netgo,osusergo \ - -ldflags "-X \"github.com/enix/x509-certificate-exporter/v3/internal.Version=${VERSION}\" \ - -X \"github.com/enix/x509-certificate-exporter/v3/internal.Revision=${VCS_REF}\" \ - -X \"github.com/enix/x509-certificate-exporter/v3/internal.BuildDateTime=$(date -u -Iseconds)\"" \ - ./cmd/x509-certificate-exporter - - -## Production Stage - -# https://github.com/hadolint/hadolint/issues/861 -# hadolint ignore=DL3029 -FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.21.0 - -COPY --from=build /go/src/github.com/enix/x509-certificate-exporter/x509-certificate-exporter /x509-certificate-exporter - +RUN go build -v -a -buildvcs=false \ + -tags netgo,osusergo \ + -ldflags " \ + -X \"github.com/enix/x509-certificate-exporter/v3/internal.Version=${VERSION}\" \ + -X \"github.com/enix/x509-certificate-exporter/v3/internal.Revision=${VCS_REF}\" \ + -X \"github.com/enix/x509-certificate-exporter/v3/internal.BuildDateTime=$(date -u -Iseconds)\" \ + " \ + -o /x509-certificate-exporter \ + ./cmd/x509-certificate-exporter +FROM scratch AS distroless +COPY --from=build --chown=0:0 --chmod=0555 /x509-certificate-exporter /x509-certificate-exporter +USER 65534:65534 EXPOSE 9793/tcp +ENTRYPOINT [ "/x509-certificate-exporter" ] +FROM cgr.dev/chainguard/wolfi-base:latest@sha256:3b271f8bff9356a38aa23118ffdea3c0d659f39e207feedacf01bdea4b900871 +COPY --from=build --chown=0:0 --chmod=0555 /x509-certificate-exporter /x509-certificate-exporter +USER nobody:nobody +EXPOSE 9793/tcp ENTRYPOINT [ "/x509-certificate-exporter" ] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f0a2d6e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +services: + app: + build: + context: . + target: dev + args: + USER_ID: ${USER_ID:-1000} + GROUP_ID: ${GROUP_ID:-1000} + user: ${USER_ID:-1000}:${GROUP_ID:-1000} + network_mode: "host" + volumes: + - .:/app:z diff --git a/hack/air-build-server.sh b/hack/air-build-server.sh new file mode 100755 index 0000000..6a01c42 --- /dev/null +++ b/hack/air-build-server.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +export CGO_ENABLED=0 +export GO111MODULE=on +export GOFLAGS="-mod=vendor" + +MODULE=$(go list -m) + +LDFLAGS=() +LDFLAGS+=" -X ${MODULE}/internal/internal.Version=$(git describe --tags --always --dirty)" +LDFLAGS+=" -X ${MODULE}/internal/internal.BuildDateTime=$(date --iso-8601=seconds)" +LDFLAGS+=" -X ${MODULE}/internal/internal.Revision=$(git rev-parse HEAD)" + +go build \ + -ldflags "${LDFLAGS[*]}" \ + -o ./tmp/x509-certificate-exporter \ + ./cmd/x509-certificate-exporter diff --git a/hack/kind.sh b/hack/kind.sh new file mode 100755 index 0000000..ce512b8 --- /dev/null +++ b/hack/kind.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# This script should be somewhat idempotent + +[ -d hack ] || { + echo "Run this script from the project root with: ./hack/$(basename $0)" >&2 + exit 1 +} + +set -xe + +. .env + +# create the Kind cluster +C="${KIND_NAME:-x509}" +kind create cluster -n "$C" || true +CTX="kind-$C" +K="kubectl --context $CTX" +$K cluster-info + +# wait for nodes to be Ready +$K wait --timeout=1h --for=condition=Ready=true node -l node-role.kubernetes.io/control-plane +sleep 2 + +# get kubeconfig +kind get kubeconfig --name $C > kubeconfig.yaml