Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
achetronic committed Aug 12, 2024
1 parent 6bcd03a commit 7b6d669
Show file tree
Hide file tree
Showing 30 changed files with 508 additions and 606 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release-binaries.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
run: |
export GOOS=${{ matrix.goos }}
export GOARCH=${{ matrix.goarch }}
export PACKAGE_NAME=hitman-${{ steps.read_tag.outputs.release_tag }}-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz
export PACKAGE_NAME=bss-${{ steps.read_tag.outputs.release_tag }}-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz
make package
make package-signature
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-charts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ jobs:
config: .github/chart-releaser-config.yaml
env:
CR_OWNER: "$GITHUB_REPOSITORY_OWNER"
CR_GIT_REPO: hitman
CR_GIT_REPO: bucket-simple-server
CR_SKIP_EXISTING: true
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ COPY ./ .
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
# the docker BUILDPLATFORM arg will be linux/arm64 when 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 hitman ./cmd
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o bss ./cmd

# 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
WORKDIR /
COPY --from=builder /workspace/hitman .
COPY --from=builder /workspace/bss .
USER 65532:65532

ENTRYPOINT ["/hitman"]
ENTRYPOINT ["/bss"]
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

# Image URL to use all building/pushing image targets
IMG ?= ghcr.io/prosimcorp/hitman:latest
IMG ?= ghcr.io/freepik-company/bucket-simple-server:latest

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
Expand Down Expand Up @@ -83,7 +83,7 @@ check-go-target: ## Check presente of GOOS and GOARCH vars.

.PHONY: build
build: fmt vet check-go-target ## Build CLI binary.
go build -o bin/hitman-$(GOOS)-$(GOARCH) cmd/main.go
go build -o bin/bss-$(GOOS)-$(GOARCH) cmd/main.go

.PHONY: run
run: fmt vet ## Run a controller from your host.
Expand Down Expand Up @@ -125,9 +125,9 @@ package: check-go-target ## Package binary.
@mkdir -p dist

@if [ "$(OS)" = "linux" ]; then \
tar --transform="s/hitman-$(GOOS)-$(GOARCH)/hitman/" -cvzf dist/$(PACKAGE_NAME) -C bin hitman-$(GOOS)-$(GOARCH) -C ../ LICENSE README.md; \
tar --transform="s/bss-$(GOOS)-$(GOARCH)/bss/" -cvzf dist/$(PACKAGE_NAME) -C bin bss-$(GOOS)-$(GOARCH) -C ../ LICENSE README.md; \
elif [ "$(OS)" = "darwin" ]; then \
tar -cvzf dist/$(PACKAGE_NAME) -s '/hitman-$(GOOS)-$(GOARCH)/hitman/' -C bin hitman-$(GOOS)-$(GOARCH) -C ../ LICENSE README.md; \
tar -cvzf dist/$(PACKAGE_NAME) -s '/bss-$(GOOS)-$(GOARCH)/bss/' -C bin bss-$(GOOS)-$(GOARCH) -C ../ LICENSE README.md; \
else \
echo "Unsupported OS: $(GOOS)"; \
exit 1; \
Expand Down
115 changes: 54 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
# Hitman
# Bucket Simple Server

![GitHub go.mod Go version (subdirectory of monorepo)](https://img.shields.io/github/go-mod/go-version/achetronic/hitman)
![GitHub](https://img.shields.io/github/license/achetronic/hitman)
![GitHub go.mod Go version (subdirectory of monorepo)](https://img.shields.io/github/go-mod/go-version/freepik-company/bucket-simple-server)
![GitHub](https://img.shields.io/github/license/freepik-company/bucket-simple-server)

![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCeSb3yfsPNNVr13YsYNvCAw?label=achetronic&link=http%3A%2F%2Fyoutube.com%2Fachetronic)
![X (formerly Twitter) Follow](https://img.shields.io/twitter/follow/achetronic?style=flat&logo=twitter&link=https%3A%2F%2Ftwitter.com%2Fachetronic)

A daemon for Kubernetes to kill target resources under user-defined templated conditions
A tiny server to safely expose some routes from your buckets without sharing cloud credentials

## Motivation

In today's fast-paced environments, Kubernetes clusters often manage systems that dynamically create and destroy resources automatically. Examples of these are pipelines and cronjobs.
This project was created to solve a common problem: securely sharing reports and small files without exposing an entire storage bucket.

However, these automated processes can sometimes get stuck, causing disruptions that affect the smooth operation of the entire system. Often, simply terminating some of these objects can restore normalcy.
Setting up a complex proxy like Envoy is time-consuming and often requires crafting custom plugins to connect to different storage services. While Envoy is great for large-scale projects, this lightweight solution is perfect for smaller needs, such as automated
reports, etc.

There is a need for a solution that empowers Kubernetes administrators to automate this cleanup process efficiently.
This project exists to provide a robust agent for automating the deletion of potential stuck resources,
ensuring your Kubernetes clusters run smoothly and reliably.
It’s simple, focused, and easy to use, making secure file sharing much easier.

## Flags

Expand All @@ -25,16 +24,16 @@ They are described in the following table:

| Name | Description | Default | Example |
|:------------------|:-------------------------------|:-------------:|:-------------------------|
| `--config` | Path to the YAML config file | `hitman.yaml` | `--config ./hitman.yaml` |
| `--config` | Path to the YAML config file | `config.yaml` | `--config ./config.yaml` |
| `--log-level` | Verbosity level for logs | `info` | `--log-level info` |
| `--disable-trace` | Disable showing traces in logs | `info` | `--log-level info` |

> Output is thrown always in JSON as it is more suitable for automations
```console
hitman run \
bss run \
--log-level=info
--config="./hitman.yaml"
--config="./config.yaml"
```

## Examples
Expand All @@ -45,48 +44,42 @@ Here you have a complete example. More up-to-date one will always be maintained

```yaml
version: v1alpha1
kind: Hitman
kind: Config
metadata:
name: killing-sample
name: access-to-reports
spec:
synchronization:
time: 1m

resources:

- target:
group: ""
version: v1
resource: pods

# Select the resources by their name
# Choose one of the following options
name:
matchRegex: ^(coredns-)
#matchExact: "coredns-xxxxxxxxxx-yyyyy"

# Select the namespace where the resources are located
# Choose one of the following options
namespace:
matchRegex: ^(kube-system)
#matchExact: kube-system

conditions:

# Delete the resources when they are older than 10 minutes
- key: |-
{{/* Define some variables */}}
{{- $maxAgeMinutes := 10 -}}
{{- $nowTimestamp := (now | unixEpoch) -}}
{{- $podStartTime := (toDate "2006-01-02T15:04:05Z07:00" .object.status.startTime) | unixEpoch -}}
{{/* Calculate the age of the resource in minutes */}}
{{- $minutedFromNow := int (round (div (sub $nowTimestamp $podStartTime) 60) 0) -}}
{{/* Print true ONLY if the resource is older than 5 minutes */}}
{{- printf "%v" (ge $minutedFromNow $maxAgeMinutes) -}}
value: true
# Source of data to be served.
# This section can be extended to support other sources like S3, Azure Blob Storage, etc.
source:
gcs:
bucket: general-purposes-bucket
credentials:
path: /tmp/credentials.json

# Web server configuration
# Here it's the place to define the server configuration like port, host, credentials, etc.
webServer:
listener:
port: 9090
host: localhost

# Several credentials can be defined
credentials:
- type: "bearer"
token: "12345xxxx12345"

- type: "bearer"
token: "6789yyyy6789"

- type: "bearer"
token: "${TOKEN_FROM_ENV}"

# Routes must be defined to allow access to the data
# They are defined as golang regular expressions
# Remember: negative lookbehind is not supported
allowedTargets:
- route: "^/qa-reports/(.*).json$"
- route: "^/pipelines-results/(.*).json$"

```

Expand All @@ -95,31 +88,31 @@ spec:
## How to deploy

This project is designed specially for Kubernetes, but also provides binary files
This project can be deployed in Kubernetes, but also provides binary files
and Docker images to make it easy to be deployed however wanted

### Binaries

Binary files for most popular platforms will be added to the [releases](https://github.com/achetronic/hitman/releases)
Binary files for most popular platforms will be added to the [releases](https://github.com/freepik-company/bucket-simple-server/releases)

### Kubernetes

You can deploy `hitman` in Kubernetes using Helm as follows:
You can deploy `bucket-simple-server` in Kubernetes using Helm as follows:

```console
helm repo add hitman https://achetronic.github.io/hitman/
helm repo add bucket-simple-server https://freepik-company.github.io/bucket-simple-server/

helm upgrade --install --wait hitman \
--namespace hitman \
--create-namespace achetronic/hitman
helm upgrade --install --wait bucket-simple-server \
--namespace bucket-simple-server \
--create-namespace freepik-company/bucket-simple-server
```

> More information and Helm packages [here](https://achetronic.github.io/hitman/)
> More information and Helm packages [here](https://freepik-company.github.io/bucket-simple-server/)

### Docker

Docker images can be found in GitHub's [packages](https://github.com/achetronic/hitman/pkgs/container/hitman)
Docker images can be found in GitHub's [packages](https://github.com/freepik-company/bucket-simple-server/pkgs/container/bucket-simple-server)
related to this repository

> Do you need it in a different container registry? I think this is not needed, but if I'm wrong, please, let's discuss
Expand Down
66 changes: 37 additions & 29 deletions api/v1alpha1/config_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,50 +16,58 @@ limitations under the License.

package v1alpha1

// TargetNameT defines TODO
type TargetSelectorT struct {
MatchExact string `yaml:"matchExact,omitempty"`
MatchRegex string `yaml:"matchRegex,omitempty"`
// MetadataT TODO
type MetadataT struct {
Name string `yaml:"name"`
}

// TargetT defines TODO
type TargetT struct {
Group string `yaml:"group"`
Version string `yaml:"version"`
Resource string `yaml:"resource"`
Name TargetSelectorT `yaml:"name"`
Namespace TargetSelectorT `yaml:"namespace"`
// GoogleContentStorageCredentialsT TODO
type GoogleContentStorageCredentialsT struct {
Path string `yaml:"path"`
}

// ConditionT defines TODO
type ConditionT struct {
Key string `yaml:"key"`
Value string `yaml:"value"`
// ConditionT TODO
type GoogleContentStorageT struct {
Bucket string `yaml:"bucket"`
Credentials GoogleContentStorageCredentialsT `yaml:"credentials"`
}

// ResourceT defines TODO
type ResourceT struct {
Target TargetT `yaml:"target"`
Conditions []ConditionT `yaml:"conditions"`
// SourceT TODO
type SourceT struct {
GCS GoogleContentStorageT `yaml:"gcs"`
}

// MetadataSpec TODO
type MetadataT struct {
Name string `yaml:"name"`
// ListenerT TODO
type ListenerT struct {
Port int `yaml:"port"`
Host string `yaml:"host"`
}

// CredentialT TODO
type CredentialT struct {
Type string `yaml:"type"`
Token string `yaml:"token"`
}

// AllowedTargetT TODO
type AllowedTargetT struct {
Route string `yaml:"route"`
}

// SynchronizationT defines TODO
type SynchronizationT struct {
Time string `yaml:"time"`
// WebserverT TODO
type WebserverT struct {
Listener ListenerT `yaml:"listener"`
Credentials []CredentialT `yaml:"credentials"`
AllowedTargets []AllowedTargetT `yaml:"allowedTargets"`
}

// SpecificationSpec TODO
// SpecificationT TODO
type SpecificationT struct {
Synchronization SynchronizationT `yaml:"synchronization"`
Resources []ResourceT `yaml:"resources"`
Source SourceT `yaml:"source"`
Webserver WebserverT `yaml:"webServer"`
}

// ConfigSpec TODO
// ConfigT TODO
type ConfigT struct {
ApiVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Expand Down
20 changes: 20 additions & 0 deletions charts/bucket-simple-server/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: v2
name: bucketSimpleServer
type: application
description: >-
A Helm chart for bucketSimpleServer, a tiny server to safely expose
some routes on from buckets without sharing cloud credentials
version: 0.1.0 # chart version
appVersion: "0.1.0" # application version
kubeVersion: ">=1.22.0-0" # kubernetes version
home: https://github.com/freepik-company/bucketSimpleServer
sources:
- https://github.com/freepik-company/bucketSimpleServer
keywords:
- bucketSimpleServer
- bucket
maintainers:
- name: Alby Hernández
email: [email protected]
url: https://github.com/achetronic/

Loading

0 comments on commit 7b6d669

Please sign in to comment.