Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
faisal-memon authored Jan 16, 2024
2 parents c773f96 + b889b88 commit 48048c0
Show file tree
Hide file tree
Showing 15 changed files with 328 additions and 58 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/nightly_build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Nightly Build
on:
schedule:
# Random minute number to avoid GH scheduler stampede
- cron: '37 21 * * *'
workflow_dispatch: {}

jobs:
build-and-publish-images:
runs-on: ubuntu-22.04

permissions:
contents: read
id-token: write
packages: write

steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup go
uses: actions/setup-go@v5
with:
go-version: 1.21.5
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install regctl
uses: regclient/actions/regctl-installer@main
- name: Build image
run: make docker-build
- name: Log in to GHCR
uses: docker/login-action@v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push images
run: ./.github/workflows/scripts/push-images.sh nightly
68 changes: 68 additions & 0 deletions .github/workflows/scripts/load-oci-archives.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
# shellcheck shell=bash
##
## USAGE: __PROG__
##
## "__PROG__" loads oci tarballs created with xbuild into docker.
##
## Usage example(s):
## ./__PROG__
## PLATFORM=linux/arm64 ./__PROG__
##
## Commands
## - ./__PROG__ loads the oci tarball into Docker.

function usage {
grep '^##' "$0" | sed -e 's/^##//' -e "s/__PROG__/$me/" >&2
}

function normalize_path {
# Remove all /./ sequences.
local path=${1//\/.\//\/}
local npath
# Remove first dir/.. sequence.
npath="${path//[^\/][^\/]*\/\.\.\//}"
# Remove remaining dir/.. sequence.
while [[ $npath != "$path" ]] ; do
path=$npath
npath="${path//[^\/][^\/]*\/\.\.\//}"
done
echo "$path"
}

me=$(basename "$0")
BASEDIR=$(dirname "$0")
ROOTDIR="$(normalize_path "$BASEDIR/../../../")"

command -v regctl >/dev/null 2>&1 || { usage; echo -e "\n * The regctl cli is required to run this script." >&2 ; exit 1; }
command -v docker >/dev/null 2>&1 || { usage; echo -e "\n * The docker cli is required to run this script." >&2 ; exit 1; }

# Takes the current platform architecture or plaftorm as defined externally in a platform variable.
# e.g.:
# linux/amd64
# linux/arm64
PLATFORM="${PLATFORM:-local}"
OCI_IMAGES=(
spiffe-helper
)

org_name=$(echo "$GITHUB_REPOSITORY" | tr '/' "\n" | head -1 | tr -d "\n")
org_name="${org_name:-spiffe}" # default to spiffe in case ran on local
registry=ghcr.io/${org_name}

echo "Importing ${OCI_IMAGES[*]} into docker".
for img in "${OCI_IMAGES[@]}"; do
oci_dir="ocidir://${ROOTDIR}oci/${img}"
platform_tar="${img}-${PLATFORM}-image.tar"
image_to_load="${registry}/${img}:devel"

# regclient works with directories rather than tars, so import the OCI tar to a directory
regctl image import "$oci_dir" "${img}-image.tar"
dig="$(regctl image digest --platform "$PLATFORM" "$oci_dir")"
# export the single platform image using the digest
regctl image export "$oci_dir@${dig}" "${platform_tar}"

docker load < "${platform_tar}"
docker image tag "localhost/oci/${img}:latest" "${image_to_load}"
docker image rm "localhost/oci/${img}:latest"
done
62 changes: 62 additions & 0 deletions .github/workflows/scripts/push-images.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
# shellcheck shell=bash
##
## USAGE: __PROG__
##
## "__PROG__" publishes images to a registry.
##
## Usage example(s):
## ./__PROG__ 1.5.2
## ./__PROG__ v1.5.2
## ./__PROG__ refs/tags/v1.5.2
##
## Commands
## - ./__PROG__ <version> pushes images to the registry using given version.

set -e

function usage {
grep '^##' "$0" | sed -e 's/^##//' -e "s/__PROG__/$me/" >&2
}

function normalize_path {
# Remove all /./ sequences.
local path=${1//\/.\//\/}
local npath
# Remove first dir/.. sequence.
npath="${path//[^\/][^\/]*\/\.\.\//}"
# Remove remaining dir/.. sequence.
while [[ $npath != "$path" ]] ; do
path=$npath
npath="${path//[^\/][^\/]*\/\.\.\//}"
done
echo "$path"
}

me=$(basename "$0")
BASEDIR=$(dirname "$0")
ROOTDIR="$(normalize_path "$BASEDIR/../../../")"

version="$1"
# remove the git tag prefix
# Push the images using the version tag (without the "v" prefix).
# Also strips the refs/tags part if the GITHUB_REF variable is used.
version="${version#refs/tags/v}"
version="${version#v}"

if [ -z "${version}" ]; then
usage
echo "version not provided!" 1>&2
exit 1
fi

image=spiffe-helper
org_name=$(echo "$GITHUB_REPOSITORY" | tr '/' "\n" | head -1 | tr -d "\n")
org_name="${org_name:-spiffe}" # default to spiffe in case ran outside of GitHub actions
registry=ghcr.io/${org_name}
image_to_push="${registry}/${image}:${version}"
oci_dir="ocidir://${ROOTDIR}oci/${image}"

echo "Pushing ${image_to_push}."
regctl image import "${oci_dir}" "${image}-image.tar"
regctl image copy "${oci_dir}" "${image_to_push}"
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ rpm/*.rpm
*.swp
*.swo
bootstrap.crt

# oci image builds
oci/
*-image.tar
44 changes: 37 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,40 @@
FROM golang
# Build the spiffe-helper binary
ARG go_version
FROM --platform=$BUILDPLATFORM golang:${go_version}-alpine as base
WORKDIR /workspace

WORKDIR /build
COPY . /build
RUN CGO_ENABLED=0 go build -o spiffe-helper ./cmd/spiffe-helper
# Cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
COPY go.* ./
RUN --mount=type=cache,target=/go/pkg/mod go mod download

# Copy the go source
COPY cmd/spiffe-helper/main.go cmd/spiffe-helper/main.go
COPY pkg/ pkg/

# xx is a helper for cross-compilation
# when bumping to a new version analyze the new version for security issues
# then use crane to lookup the digest of that version so we are immutable
# crane digest tonistiigi/xx:1.3.0
FROM --platform=${BUILDPLATFORM} tonistiigi/xx@sha256:904fe94f236d36d65aeb5a2462f88f2c537b8360475f6342e7599194f291fb7e AS xx

FROM --platform=${BUILDPLATFORM} base as builder
ARG TARGETPLATFORM
ARG TARGETARCH

ENV CGO_ENABLED=0
COPY --link --from=xx / /
RUN xx-go --wrap
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
go build -o bin/spiffe-helper cmd/spiffe-helper/main.go

# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
#FROM gcr.io/distroless/static:nonroot
FROM gcr.io/distroless/static AS spiffe-helper
WORKDIR /
COPY --link --from=builder /workspace/bin/spiffe-helper /spiffe-helper

FROM scratch
COPY --from=0 /build/spiffe-helper /spiffe-helper
ENTRYPOINT ["/spiffe-helper"]
CMD ["-config", "/etc/spiffe-helper.conf"]
CMD []
30 changes: 28 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export GO111MODULE=on
DIR := ${CURDIR}
PLATFORMS ?= linux/amd64,linux/arm64

E:=@
ifeq ($(V),1)
Expand Down Expand Up @@ -41,6 +42,15 @@ help:
@echo "For verbose output set V=1"
@echo " for example: $(cyan)make V=1 build$(reset)"

# Used to force some rules to run every time
.PHONY: FORCE
FORCE: ;

# CONTAINER_TOOL defines the container tool to be used for building images.
# Be aware that the target commands are only tested with Docker which is
# scaffolded by default. However, you might want to replace it to use other
# tools. (i.e. podman)
CONTAINER_TOOL ?= docker

############################################################################
# OS/ARCH detection
Expand Down Expand Up @@ -167,10 +177,26 @@ lint-code: $(golangci_lint_bin) | go-check
# Build targets
############################################################################

.PHONY: build test clean distclean artifact tarball rpm
.PHONY: build test clean distclean artifact tarball rpm docker-build container-builder load-images

build: | go-check
go build -o spiffe-helper${exe} ./cmd/spiffe-helper
CGO_ENABLED=0 go build -o spiffe-helper${exe} ./cmd/spiffe-helper

docker-build: $(addsuffix -image.tar, spiffe-helper) ## Build docker image with spiffe-helper.

container-builder: ## Create a buildx node to create crossplatform images.
$(CONTAINER_TOOL) buildx create --platform $(PLATFORMS) --name container-builder --node container-builder0 --use

spiffe-helper-image.tar: Dockerfile FORCE | container-builder
$(CONTAINER_TOOL) buildx build \
--platform $(PLATFORMS) \
--build-arg go_version=$(go_version) \
--target spiffe-helper \
-o type=oci,dest=$@ \
.

load-images: $(addsuffix -image.tar,$(BINARIES)) ## Load the image for your current PLATFORM into docker from the cross-platform oci tar.
./.github/workflows/scripts/load-oci-archives.sh

artifact: tarball rpm

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ The SPIFFE Helper is a simple utility for fetching X.509 SVID certificates from

If `-config` is not specified, the default value `helper.conf` is assumed.

The flag `-exitWhenReady` is also supported.

## Configuration
The configuration file is an [HCL](https://github.com/hashicorp/hcl) formatted file that defines the following configurations:

Expand All @@ -28,8 +30,7 @@ The configuration file is an [HCL](https://github.com/hashicorp/hcl) formatted f
| `svid_file_name` | File name to be used to store the X.509 SVID public certificate in PEM format. | `"svid.pem"` |
| `svid_key_file_name` | File name to be used to store the X.509 SVID private key and public certificate in PEM format. | `"svid_key.pem"` |
| `svid_bundle_file_name` | File name to be used to store the X.509 SVID Bundle in PEM format. | `"svid_bundle.pem"` |
| `jwt_audience` | JWT SVID audience. | `"your-audience"` |
| `jwt_svid_file_name` | File name to be used to store JWT SVID in Base64-encoded string. | `"jwt_svid.token"` |
| `jwt_svids` | An array with the audience and file name to store the JWT SVIDs. File is Base64-encoded string). | `[{jwt_audience="your-audience", jwt_svid_file_name="jwt_svid.token"}]` |
| `jwt_bundle_file_name` | File name to be used to store JWT Bundle in JSON format. | `"jwt_bundle.json"` |
| `include_federated_domains` | Include trust domains from federated servers in the CA bundle. | `true` |

Expand Down
7 changes: 4 additions & 3 deletions cmd/spiffe-helper/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,25 @@ func main() {
// 2. Run Sidecar's Daemon

configFile := flag.String("config", "helper.conf", "<configFile> Configuration file path")
exitWhenReady := flag.Bool("exitWhenReady", false, "Exit once the requested objects are retrieved")
flag.Parse()

log := logrus.WithField("system", "spiffe-helper")
log.Infof("Using configuration file: %q\n", *configFile)

if err := startSidecar(*configFile, log); err != nil {
if err := startSidecar(*configFile, *exitWhenReady, log); err != nil {
log.WithError(err).Error("Exiting due this error")
os.Exit(1)
}

log.Infof("Exiting")
}

func startSidecar(configPath string, log logrus.FieldLogger) error {
func startSidecar(configPath string, exitWhenReady bool, log logrus.FieldLogger) error {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

spiffeSidecar, err := sidecar.New(configPath, log)
spiffeSidecar, err := sidecar.New(configPath, exitWhenReady, log)
if err != nil {
return fmt.Errorf("Failed to create sidecar: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/hashicorp/hcl v1.0.0
github.com/spiffe/go-spiffe/v2 v2.1.6
github.com/stretchr/testify v1.8.4
golang.org/x/sys v0.15.0
golang.org/x/sys v0.16.0
google.golang.org/grpc v1.60.1
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
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-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
Expand Down
Loading

0 comments on commit 48048c0

Please sign in to comment.