Skip to content

Commit

Permalink
Merge pull request #59 from Keyfactor/helm_utils
Browse files Browse the repository at this point in the history
feat(helm): `helm` command path for Chart CLI configuration tool
  • Loading branch information
spbsoluble authored Oct 9, 2023
2 parents a305d9f + 62129d5 commit 2b1ead9
Show file tree
Hide file tree
Showing 38 changed files with 6,138 additions and 8 deletions.
156 changes: 156 additions & 0 deletions .github/workflows/container.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
name: Build and Release
on:
push:
branches:
- '*'
pull_request:
branches:
- 'release-*'
types:
# action should run when the pull request is closed
# (regardless of whether it was merged or just closed)
- closed
# Make sure the action runs every time new commits are
# pushed to the pull request's branch
- synchronize

env:
REGISTRY: ghcr.io

jobs:
build:
name: Build Containers
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform:
- linux/arm64
- linux/amd64
- linux/s390x
- linux/ppc64le

permissions:
contents: read
packages: write

steps:

- name: Set IMAGE_NAME
run: |
echo "IMAGE_NAME=${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}
# Checkout code
# https://github.com/actions/checkout
- name: Checkout code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

# Set up QEMU
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0

# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

# Login to Docker registry
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Build and push Docker image with Buildx
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
push: ${{ github.event.pull_request.merged == true }}
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true

# Export digest
- name: Export digest
if: github.event.pull_request.merged == true
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
# Upload digest
- name: Upload digest
if: github.event.pull_request.merged == true
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: digests
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge:
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true
needs:
- build
steps:
- name: Set IMAGE_NAME
run: |
echo "IMAGE_NAME=${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}
# Download digests
# https://github.com/actions/download-artifact
- name: Download digests
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
with:
name: digests
path: /tmp/digests

# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

# Login to Docker registry
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Create manifest list and push
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
30 changes: 29 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -381,4 +381,32 @@ jobs:
# unset KFUTIL_DEBUG
# kfutil logout || true
# printenv | grep -i keyfactor
# go test -v ./cmd -run "^Test_PAM*"
# go test -v ./cmd -run "^Test_PAM*"

Test_Kfutil_pkg:
runs-on: ubuntu-latest
needs:
- build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
# Checkout code
# https://github.com/actions/checkout
- name: Checkout code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0

# Setup GoLang build environment
# https://github.com/actions/setup-go
- name: Set up Go 1.x
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with:
go-version-file: 'go.mod'
cache: true

# Install dependencies
- name: Install dependencies
run: go mod download

# Run the tests with coverage found in the pkg directory
- name: Run tests
run: go test -v -cover ./pkg/...
35 changes: 35 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Build the kfutil binary
FROM golang:1.19 as builder
ARG TARGETOS
ARG TARGETARCH

WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# 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
RUN go mod download

# Copy the go source
COPY main.go main.go
COPY cmd/ cmd/
COPY pkg/ pkg/

# Build
# the GOARCH has a default value to allow the binary be built according to the host where the command
# was called. For example, if we build in a local env which has the Apple Silicon M1 chip,
# the docker BUILDPLATFORM arg will be linux/arm64, but for Apple x86 it will be linux/amd64. Therefore,
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o kfutil main.go

FROM ubuntu:latest
WORKDIR /
COPY --from=builder /workspace/kfutil /usr/local/bin/kfutil

# Install ca-certificates so that HTTPS works consistently
RUN apt-get update
RUN apt-get install ca-certificates -y

# Spin forever so that the container doesn't exit and the user can exec into it
ENTRYPOINT ["tail", "-f", "/dev/null"]
69 changes: 69 additions & 0 deletions cmd/helm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
Copyright 2023 The Keyfactor Command Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"kfutil/pkg/cmdutil/flags"
)

// Ensure that HelmFlags implements Flags
var _ flags.Flags = &HelmFlags{}

type HelmFlags struct {
}

func NewHelmFlags() *HelmFlags {
return &HelmFlags{}
}

func (f *HelmFlags) AddFlags(flags *pflag.FlagSet) {
// Implement Flags interface
}

func NewCmdHelm() *cobra.Command {
helmFlags := NewHelmFlags()

cmd := &cobra.Command{
Use: "helm",
Short: helmShortDescription,
Long: helmLongDescription,
Example: "kubectl helm uo | helm install -f - keyfactor-universal-orchestrator keyfactor/keyfactor-universal-orchestrator",
}

helmFlags.AddFlags(cmd.Flags())

// Add subcommands
cmd.AddCommand(NewCmdHelmUo())

return cmd
}

// Example usage:
// kubectl helm uo | helm install -f - keyfactor-universal-orchestrator keyfactor/keyfactor-universal-orchestrator

func init() {
// Helm Command
helmCmd := NewCmdHelm()
RootCmd.AddCommand(helmCmd)
}

const (
helmShortDescription = `Helm utilities for configuring Keyfactor Helm charts`
helmLongDescription = helmShortDescription
)
47 changes: 47 additions & 0 deletions cmd/helm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Copyright 2023 The Keyfactor Command Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
"kfutil/pkg/cmdtest"
"strings"
"testing"
)

func TestHelm(t *testing.T) {
t.Run("Test helm command", func(t *testing.T) {
// The helm command doesn't have any flags or a RunE function, so the output should be the same as the help menu.
cmd := NewCmdHelm()

t.Logf("Testing %q", cmd.Use)

helmNoFlag, err := cmdtest.TestExecuteCommand(t, cmd, "")
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

helmHelp, err := cmdtest.TestExecuteCommand(t, cmd, "-h")
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

diff := strings.Compare(string(helmNoFlag), string(helmHelp))
if diff != 0 {
t.Errorf("Expected helmNoFlag to equal helmHelp, but got: %v", diff)
}
})
}
Loading

0 comments on commit 2b1ead9

Please sign in to comment.