Skip to content

Commit

Permalink
Rebasing before merge
Browse files Browse the repository at this point in the history
Signed-off-by: Arthur Luiz Lara Quites <arthur.quites@cesar.org.br>
  • Loading branch information
Arthur Luiz Lara Quites committed Dec 14, 2022
1 parent 61f8a39 commit 075a700
Show file tree
Hide file tree
Showing 32 changed files with 4,362 additions and 0 deletions.
72 changes: 72 additions & 0 deletions .github/workflows/hybrid-integration-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
## This code is to be runned when the PR is fully merged. We are not able to merge with it running because the fork doesn't share the github action variables with the main repo.
## After merging, uncomment this code and run

# name: integration test

# on:
# workflow_dispatch:
# pull_request:
# paths:
# - 'hybrid/**'
# jobs:
# build:
# runs-on: ubuntu-latest

# steps:
# - name: Checkout Repository
# uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2

# - name: Setup Go
# uses: actions/setup-go@b22fbbc2921299758641fab08929b4ac52b32923 # v3.2.0
# with:
# go-version: '>=1.17.0'

# - name: Configure AWS credentials
# uses: aws-actions/configure-aws-credentials@v1
# with:
# aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
# aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# aws-region: ${{ secrets.AWS_REGION }}

# - name: Login to Amazon ECR Public
# id: login-ecr-public
# uses: aws-actions/amazon-ecr-login@v1
# with:
# registry-type: public

# - name: Install eksctl
# run: |
# curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp && mv /tmp/eksctl /usr/local/bin

# - name: Check cluster exists
# run: |
# echo "CLUSTER=$(eksctl get cluster --name ${{ secrets.AWS_TEST_CLUSTER }} | grep -c ${{ secrets.AWS_TEST_CLUSTER }} )" >> $GITHUB_ENV

# - name: Create cluster
# env :
# AWS_TEST_CLUSTER: ${{ secrets.AWS_TEST_CLUSTER }}
# if: "${{ env.CLUSTER == 0 }}"
# run: |
# eksctl create cluster --name ${{ secrets.AWS_TEST_CLUSTER }} --region ${{ secrets.AWS_REGION }} --zones ${{ secrets.AWS_ZONES }} --version 1.22 --node-type m5.large --nodes-min 1 --nodes-max 1 --nodes 1

# - name: Update context
# run: |
# aws eks update-kubeconfig --region ${{ secrets.AWS_REGION }} --name ${{ secrets.AWS_TEST_CLUSTER }}

# - name: Set Context
# run: |
# kubectl config use-context arn:aws:eks:${{ secrets.AWS_REGION }}:${{ secrets.AWS_ACCOUNT_ID }}:cluster/${{ secrets.AWS_TEST_CLUSTER }}

# - name: Run integration test
# env:
# DOCKER_HUB: ${{ secrets.DOCKER_HUB }}
# AWS_TEST_CLUSTER: ${{ secrets.AWS_TEST_CLUSTER }}
# run: |
# ./hybrid/test/integration/test.sh

# - name: Delete cluster
# run: |
# eksctl get nodegroup --cluster ${{ secrets.AWS_TEST_CLUSTER }} | awk 'NR==2 {first = $2} END {print first}' | while read a ; do eksctl delete nodegroup --cluster ${{ secrets.AWS_TEST_CLUSTER }} --region ${{ secrets.AWS_REGION }} --name $a;done
# aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE --region ${{ secrets.AWS_REGION }} | grep StackName | grep ${{ secrets.AWS_TEST_CLUSTER }} | grep nodegroup | sed 's/"StackName": "//' | sed 's/",//' | while read a ; do aws cloudformation delete-stack --stack-name $a;done
# aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE --region ${{ secrets.AWS_REGION }} | grep StackName | grep ${{ secrets.AWS_TEST_CLUSTER }} | grep cluster | sed 's/"StackName": "//' | sed 's/",//' | while read a ; do aws cloudformation delete-stack --stack-name $a;done
# eksctl delete cluster --name ${{ secrets.AWS_TEST_CLUSTER }} --region ${{ secrets.AWS_REGION }}
22 changes: 22 additions & 0 deletions .github/workflows/hybrid-pr-build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Hybrid PR Build

on:
pull_request:
paths:
- 'hybrid/**'

defaults:
run:
working-directory: hybrid

env:
GO_VERSION: 1.19

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2
- uses: actions/setup-go@b22fbbc2921299758641fab08929b4ac52b32923 # v3.2.0
with:
go-version: ${{ env.GO_VERSION }}
26 changes: 26 additions & 0 deletions .github/workflows/scripts/split.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash

set -e

if [ -z "$NUM_RUNNERS" ]; then
echo "split.sh: NUM_RUNNERS environment variable must be set"
exit 1
fi

if [ -z "$THIS_RUNNER" ]; then
echo "split.sh: THIS_RUNNER environment variable must be set"
exit 1
fi

declare -a job_set
current_runner=1
for FILE in test/integration/suites/*; do
job_set[$current_runner]+="${FILE##test/integration/} "

((current_runner++))
if [ $current_runner -gt "$NUM_RUNNERS" ]; then
current_runner=1
fi
done

echo "${job_set[$THIS_RUNNER]}"
56 changes: 56 additions & 0 deletions hybrid/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
.ONESHELL:

EKS_DIR ?= ./dev/kubernetes
BINARIES ?= hybrid_server hybrid_agent

OSES ?= linux windows
ARCHITECTURES ?= amd64 arm64
VERSION ?= latest-local
DOCKER_HUB ?= ${DOCKER_HUB}

BUILD_DIR ?= ./build
PLATFORM_LINUX ?= $(foreach os, $(OSES), $(foreach architecture, $(ARCHITECTURES), $(if $(findstring linux, $(os)), --platform $(os)/$(architecture))))
BUILD_TARGETS := $(foreach binary, $(BINARIES), $(foreach os, $(OSES), $(foreach architecture, $(ARCHITECTURES), $(binary)-$(os)-$(architecture))))
DOCKER_TARGETS := $(foreach binary, $(BINARIES), $(binary)-docker)

target_words = $(subst -, ,$@)
target_binary = $(word 1, $(target_words))
target_binary_unified = $(subst _,,$(word 1, $(target_words)))
target_os = $(word 2, $(target_words))
target_architecture = $(word 3, $(target_words))
target_software_type = $(word 2, $(subst _, ,$(target_binary)))

target_binary_hyphens = $(subst _,-attestor-,$(target_binary))

build: $(BUILD_TARGETS)
$(BUILD_TARGETS):
CGO_ENABLED=0 GOOS=$(target_os) GOARCH=$(target_architecture) go build -ldflags="-s -w -extldflags -static" -o $(BUILD_DIR)/$(target_os)/$(target_architecture)/$(target_binary_unified) cmd/$(target_binary)/main.go

test: test-unit test-integration
go test ./...

test-unit:
go test ./...

test-unit-race:
go test -race ./...

test-integration:
bash ./test/integration/test.sh

docker-linux: $(DOCKER_TARGETS)
$(DOCKER_TARGETS):
docker build -f ./dev/docker/$(target_software_type).Dockerfile $(PLATFORM_LINUX) --build-arg BINARY=$(target_binary_unified) -t $(DOCKER_HUB)/$(target_binary_hyphens):$(VERSION) .
docker push $(DOCKER_HUB)/$(target_binary_hyphens):$(VERSION)

deploy-spire-eks:
kubectl delete --all daemonsets.app --namespace=spire
kubectl delete --all statefulset.app --namespace=spire
kubectl delete --ignore-not-found namespace spire
envsubst < $(EKS_DIR)/server.yaml | kubectl apply -f -
envsubst < $(EKS_DIR)/agent.yaml | kubectl apply -f -

clean:
rm -rf $(BUILD_DIR)

.PHONY: $(BUILD_TARGETS) $(DOCKER_TARGETS) build test docker clean
94 changes: 94 additions & 0 deletions hybrid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
[![PR Build](https://github.com/HewlettPackard/roven/actions/workflows/hybrid-pr-build.yaml/badge.svg)](https://github.com/HewlettPackard/roven/actions/workflows/hybrid-pr-build.yaml)

# Hybrid Node Attestor
The `hybrid` node attestor plugin for SPIRE is an external plugin, that combines the power of any built-in plugin supported by SPIRE. With this approach you can use any combination of the built-in plugins in order to attest the node. For example, you can mix the k8s_psat and the aws_iid plugins to attest that the agent node is running on an AWS EKS or an EC2 instance with a self managed k8s cluster.

## SpiffeID
The hybrid plugin will always return the SpiffeID generated by the first plugin of the list supplied to the server.

## Basic deployment
The hybrid plugin works as any external plugin would. It is designed to work as an external plugin, acting as a plugin aggregator.
To deploy it, first build and update the configuration for both SPIRE Server and Agent passing the list of built-in plugins that will be used in combination in order to attest the node. The order of the plugins supplied for both server and agent does not have to be the same.

## Building
Start by building the binaries

`make build`

## Configuring
In order to use the hybrid plugin with the SPIRE instance, add in the SPIRE configuration file as an external plugin, informing the name, `plugin_cmd` and in the section plugins, inside `plugin_data`, add the built-in plugins configuration. Here's an example:

**Server**
```
plugins{
NodeAttestor "hybrid" {
plugin_cmd = "path/to/attestor/server/binary""
plugin_data {
plugins {
<first_plugin> {
[plugin_config]
}
<second_plugin> {
[plugin_config]
}
[...]
}
}
}
}
```

**Agent**
```
plugins {
NodeAttestor "hybrid" {
plugin_cmd = "path/to/attestor/agent/binary"
plugin_data {
plugins {
<first_plugin> {
[plugin_config]
}
<second_plugin> {
[plugin_config]
}
}
}
}
}
```

### Deploying the hybrid using aws_iid and k8s_psat node attestors
To combine those two plugins, you have to be running the agent and server in an kubernetes instance inside aws.

Start off by creating an EC2 instance and deploying a custom Kubernetes cluster or creating an EKS cluster.

After that, run the following command while in the hybrid root directory:

`make build`

To build the docker images and push them to a registry, set the environment variable `DOCKER_HUB` and run the following command:

`make docker`

With the hybrid node attestor built and the Docker image constructed, you now have to deploy it in the running Kubernetes cluster in AWS.
Configure kubectl to point to the aws cluster.
Change the credentials in the server.yaml and agent.yaml that are in the hybrid/dev/kubernetes and run the following command:

`make deploy-spire-eks`

You should now be able to see the running agent/server node attestor. First set the corresponding environment variables with their required values ($AWS_SECRET_ACCESS_KEY, $AWS_ACCESS_KEY_ID, $AWS_ASSUME_ROLE, $AWS_ACCOUNT_ID)

## Supported plugins
The following list show the supported built-in plugins:

| Plugin | Supported |
| ------- | ------------------ |
| aws_iid | :heavy_check_mark: |
| azure_msi | :heavy_check_mark: |
| gcp_iit | :heavy_check_mark: |
| k8s_psat | :heavy_check_mark: |
| join_token | :x: |
| k8s_sat | :x: |
| sshpop | :x: |
| tpm_devid | :x: |
| s509pop | :x: |
14 changes: 14 additions & 0 deletions hybrid/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Security Policy

## Supported Versions

Versions of the project that are currently being supported with security updates:

| Version | Supported |
| ------- | ------------------ |
| 1.0.0 | :white_check_mark: |


## Reporting a Vulnerability

If you've found a vulnerability or a potential vulnerability in this plugin please let us know at juliano.fantozzi@hpe.com. We'll send a confirmation email to acknowledge your report, and we'll send an additional email when we've identified the issue positively or negatively.
17 changes: 17 additions & 0 deletions hybrid/cmd/hybrid_agent/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

import (
hybridagent "github.com/hewlettpackard/hybrid/pkg/agent"

"github.com/spiffe/spire-plugin-sdk/pluginmain"
nodeattestorv1 "github.com/spiffe/spire-plugin-sdk/proto/spire/plugin/agent/nodeattestor/v1"
configv1 "github.com/spiffe/spire-plugin-sdk/proto/spire/service/common/config/v1"
)

func main() {
p := hybridagent.New()
pluginmain.Serve(
nodeattestorv1.NodeAttestorPluginServer(p),
configv1.ConfigServiceServer(p),
)
}
17 changes: 17 additions & 0 deletions hybrid/cmd/hybrid_server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

import (
hybridserver "github.com/hewlettpackard/hybrid/pkg/server"

"github.com/spiffe/spire-plugin-sdk/pluginmain"
nodeattestorv1 "github.com/spiffe/spire-plugin-sdk/proto/spire/plugin/server/nodeattestor/v1"
configv1 "github.com/spiffe/spire-plugin-sdk/proto/spire/service/common/config/v1"
)

func main() {
p := hybridserver.New()
pluginmain.Serve(
nodeattestorv1.NodeAttestorPluginServer(p),
configv1.ConfigServiceServer(p),
)
}
3 changes: 3 additions & 0 deletions hybrid/dev/docker/agent.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM gcr.io/spiffe-io/spire-agent:1.5.1 AS spire-agent-psat-iid
COPY ./build/linux/amd64/hybridagent /usr/local/bin/agentattestor
RUN chmod +x /usr/local/bin/agentattestor
3 changes: 3 additions & 0 deletions hybrid/dev/docker/server.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM gcr.io/spiffe-io/spire-server:1.5.1 AS spire-server-psat-iid
COPY ./build/linux/amd64/hybridserver /usr/local/bin/serverattestor
RUN chmod +x /usr/local/bin/serverattestor
Loading

0 comments on commit 075a700

Please sign in to comment.