Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
choffmeister committed Feb 22, 2022
0 parents commit ca8a34e
Show file tree
Hide file tree
Showing 35 changed files with 3,316 additions and 0 deletions.
17 changes: 17 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.go]
indent_style = tab
indent_size = 4

[Makefile]
indent_style = tab
indent_size = 4
29 changes: 29 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: release
on:
push:
tags:
- "*"
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v2
with:
go-version: 1.17.x
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- uses: docker/login-action@v1
with:
registry: ghcr.io
username: airfocusio
password: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
distribution: goreleaser
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30 changes: 30 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: test
on:
push:
branches:
- "main"
pull_request:
branches:
- main
env:
GO111MODULE: on
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v2
with:
go-version: 1.17.x
- uses: actions/checkout@v2
- name: Install talosctl
run: |
mkdir -p $HOME/bin
wget -qO $HOME/bin/talosctl https://github.com/talos-systems/talos/releases/download/v0.14.2/talosctl-linux-amd64
chmod +x $HOME/bin/talosctl
echo "$HOME/bin" >> $GITHUB_PATH
- name: Build sources
run: go build ./...
- name: Run tests
run: go test -v ./...
env:
HCLOUD_TOKEN: ${{ secrets.HCLOUD_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist/
test/
coverage.out
50 changes: 50 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
project_name: hcloud-talos
before:
hooks:
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
goarch:
- amd64
- arm64
dockers:
- image_templates:
- "ghcr.io/airfocusio/{{ .ProjectName }}:{{ .Version }}-amd64"
- "ghcr.io/airfocusio/{{ .ProjectName }}:latest-amd64"
use: buildx
goarch: amd64
dockerfile: Dockerfile
build_flag_templates:
- "--platform=linux/amd64"
- image_templates:
- "ghcr.io/airfocusio/{{ .ProjectName }}:{{ .Version }}-arm64v8"
- "ghcr.io/airfocusio/{{ .ProjectName }}:latest-arm64v8"
use: buildx
goarch: arm64
dockerfile: Dockerfile
build_flag_templates:
- "--platform=linux/arm64/v8"
docker_manifests:
- name_template: ghcr.io/airfocusio/{{ .ProjectName }}:{{ .Version }}
image_templates:
- ghcr.io/airfocusio/{{ .ProjectName }}:{{ .Version }}-amd64
- ghcr.io/airfocusio/{{ .ProjectName }}:{{ .Version }}-arm64v8
- name_template: ghcr.io/airfocusio/{{ .ProjectName }}:latest
image_templates:
- ghcr.io/airfocusio/{{ .ProjectName }}:latest-amd64
- ghcr.io/airfocusio/{{ .ProjectName }}:latest-arm64v8
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "0.0.0-dev"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM scratch
ENTRYPOINT ["/bin/hcloud-talos"]
COPY --from=ghcr.io/talos-systems/talosctl:v0.14.2 /talosctl /bin/talosctl
COPY hcloud-talos /bin/hcloud-talos
WORKDIR /workdir
27 changes: 27 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Copyright (c) 2022 airfocus GmbH. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Christian Hoffmeister nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 changes: 32 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.PHONY: *

run-bootstrap-cluster:
mkdir -p test
cd test && go run .. bootstrap-cluster --cluster-name=cluster --node-name=controlplane-01 --force

run-destroy-cluster:
mkdir -p test
cd test && go run .. destroy-cluster --force

run-apply-manifests:
cd test && go run .. apply-manifests

run-add-node:
cd test && go run .. add-node --node-name=worker-01

test:
go test -v ./...

test-watch:
watch -n1 go test -v ./...

test-cover:
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out
go tool cover -html=coverage.out

build:
goreleaser release --rm-dist --skip-publish --snapshot

release:
goreleaser release --rm-dist
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# hcloud-talos

## Commands

This CLI tool provides an easy way to manage [Talos](https://talos.dev/) powered [Kubernetes](https://kubernetes.io/) clustes on the [Hetzner Cloud](https://www.hetzner.com/cloud).

* `bootstrap-cluster`
* Create a private network `10.0.0.0/8` for inter-node communication
* Create a placement group to ensure nodes to not run on the same physical machine
* Create a firewall that blocks all incoming traffic (except ICMP)
* Create a load balancer to access the controlplane nodes via Kubernetes API server (port `6443`) or Talos API server (port `50000`)
* Create a load balancer to access the nodes ingress (port `80` -> `30080`, `443` -> `30433`) with proxy protocol
* Create a first controlplane node running Talos
* Install [Hetzner Cloud Controller Manger](https://github.com/hetznercloud/hcloud-cloud-controller-manager)
* Install [Hetzner CSI Driver](https://github.com/hetznercloud/csi-driver)
* `add-node`
* Create an additional node running Talos, either controlplane or worker
* `destroy-cluster`
* Remove all Hetzner resources (by label)

## Usage

```bash
mkdir my-cluster
cd my-cluster
export HCLOUD_TOKEN=...
# bootstrap cluster
hcloud-talos bootstrap-cluster --cluster-name=my-cluster --node-name=controlplane-01 --force

# add more nodes
hcloud-talos add-node --cluster-name=cluster --node-name=controlplane-02 --controlplane
hcloud-talos add-node --node-name=worker-01
```
102 changes: 102 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package cmd

import (
"flag"
"fmt"
"os"
"runtime/debug"

"github.com/airfocusio/hcloud-talos/internal/cmds"
"github.com/airfocusio/hcloud-talos/internal/utils"
)

func Execute(logger *utils.Logger, version FullVersion) error {
dir := ""
flags := flag.NewFlagSet("root", flag.ContinueOnError)
flags.StringVar(&dir, "dir", "", "")
if err := flags.Parse(os.Args[1:]); err != nil {
return err
}
if dir == "" {
dirOut, err := os.Getwd()
if err != nil {
return err
}
dir = dirOut
}

command := ""
commandArgs := flags.Args()
if flags.NArg() >= 1 {
command = flags.Arg(0)
commandArgs = flags.Args()[1:]
}

switch command {
case "version":
os.Stdout.Write([]byte(version.Version))
return nil
case "bootstrap-cluster":
cmd := cmds.BootstrapClusterCommand{}
return RunCommand(logger, &cmd, commandArgs, dir)
case "destroy-cluster":
cmd := cmds.DestroyClusterCommand{}
return RunCommand(logger, &cmd, commandArgs, dir)
case "apply-manifests":
cmd := cmds.ApplyManifestsCommand{}
return RunCommand(logger, &cmd, commandArgs, dir)
case "add-node":
cmd := cmds.AddNodeCommand{}
return RunCommand(logger, &cmd, commandArgs, dir)
case "":
err := fmt.Errorf("unknown command %s", command)
os.Stderr.Write([]byte(err.Error()))
return err
default:
err := fmt.Errorf("unknown command %s", command)
os.Stderr.Write([]byte(err.Error()))
return err
}
}

func RunCommand(logger *utils.Logger, cmd cmds.Command, args []string, dir string) error {
flags := flag.NewFlagSet("command", flag.ContinueOnError)
cmd.RegisterOpts(flags)
if err := flags.Parse(args); err != nil {
return err
}
if err := cmd.ValidateOpts(); err != nil {
logger.Error.Printf("%v\n", err)
return err
}
if err := cmd.Run(logger, dir); err != nil {
logger.Error.Printf("%v\n", err)
return err
}
logger.Info.Printf("Done\n")
return nil
}

type FullVersion struct {
Version string
Commit string
Date string
BuiltBy string
}

func (v FullVersion) ToString() string {
result := v.Version
if v.Commit != "" {
result = fmt.Sprintf("%s\ncommit: %s", result, v.Commit)
}
if v.Date != "" {
result = fmt.Sprintf("%s\nbuilt at: %s", result, v.Date)
}
if v.BuiltBy != "" {
result = fmt.Sprintf("%s\nbuilt by: %s", result, v.BuiltBy)
}
if info, ok := debug.ReadBuildInfo(); ok && info.Main.Sum != "" {
result = fmt.Sprintf("%s\nmodule version: %s, checksum: %s", result, info.Main.Version, info.Main.Sum)
}
return result
}
12 changes: 12 additions & 0 deletions cmd/root_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package cmd

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestEmpty(t *testing.T) {
// TODO
assert.Equal(t, 0, 0)
}
Loading

0 comments on commit ca8a34e

Please sign in to comment.