Skip to content

Commit

Permalink
Merge pull request #536 from apricote/hetzner
Browse files Browse the repository at this point in the history
platform: Hetzner API implementation
  • Loading branch information
tormath1 authored Aug 27, 2024
2 parents a0b4473 + 1ce68f9 commit 6807d6c
Show file tree
Hide file tree
Showing 298 changed files with 26,416 additions and 9,547 deletions.
9 changes: 8 additions & 1 deletion cmd/kola/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ var (
kolaOffering string
defaultTargetBoard = sdk.DefaultBoard()
kolaArchitectures = []string{"amd64"}
kolaPlatforms = []string{"aws", "azure", "brightbox", "do", "esx", "external", "gce", "openstack", "equinixmetal", "qemu", "qemu-unpriv", "scaleway"}
kolaPlatforms = []string{"aws", "azure", "brightbox", "do", "esx", "external", "gce", "hetzner", "openstack", "equinixmetal", "qemu", "qemu-unpriv", "scaleway"}
kolaDistros = []string{"cl", "fcos", "rhcos"}
kolaChannels = []string{"alpha", "beta", "stable", "edge", "lts"}
kolaOfferings = []string{"basic", "pro"}
Expand Down Expand Up @@ -243,6 +243,12 @@ func init() {
sv(&kola.ScalewayOptions.SecretKey, "scaleway-secret-key", "", "Scaleway credentials secret key")
sv(&kola.ScalewayOptions.Image, "scaleway-image", "", "Scaleway image ID")
sv(&kola.ScalewayOptions.InstanceType, "scaleway-instance-type", "DEV1-S", "Scaleway instance type")

// Hetzner specific options
sv(&kola.HetznerOptions.Token, "hetzner-token", "", "Hetzner token for client authentication")
sv(&kola.HetznerOptions.Location, "hetzner-location", "fsn1", "Hetzner location name")
sv(&kola.HetznerOptions.Image, "hetzner-image", "", "Hetzner image ID")
sv(&kola.HetznerOptions.ServerType, "hetzner-server-type", "cx22", "Hetzner instance type")
}

// Sync up the command line options if there is dependency
Expand All @@ -263,6 +269,7 @@ func syncOptions() error {
kola.EquinixMetalOptions.GSOptions = &kola.GCEOptions
kola.BrightboxOptions.Board = board
kola.ScalewayOptions.Board = board
kola.HetznerOptions.Board = board

validateOption := func(name, item string, valid []string) error {
for _, v := range valid {
Expand Down
12 changes: 12 additions & 0 deletions cmd/ore/hetzner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright The Mantle Authors.
// SPDX-License-Identifier: Apache-2.0

package main

import (
"github.com/flatcar/mantle/cmd/ore/hetzner"
)

func init() {
root.AddCommand(hetzner.Hetzner)
}
44 changes: 44 additions & 0 deletions cmd/ore/hetzner/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright The Mantle Authors.
// SPDX-License-Identifier: Apache-2.0

package hetzner

import (
"fmt"

"github.com/spf13/cobra"
)

var (
cmdCreate = &cobra.Command{
Use: "create-image",
Short: "Create image on Hetzner",
Long: `Upload an image to Hetzner.
After a successful run, the final line of output will be the ID of the image.
`,
RunE: runCreate,
}

path string
name string
board string
)

func init() {
Hetzner.AddCommand(cmdCreate)
cmdCreate.Flags().StringVar(&path, "file",
"https://alpha.release.flatcar-linux.net/amd64-usr/current/flatcar_production_hetzner_image.bin.bz2",
"Flatcar image (can be an absolute path or an URL)")
cmdCreate.Flags().StringVar(&name, "name", "", "image name")
cmdCreate.Flags().StringVar(&board, "board", "amd64-usr", "board of the image")
}

func runCreate(cmd *cobra.Command, args []string) error {
id, err := API.UploadImage(cmd.Context(), name, path, board)
if err != nil {
return fmt.Errorf("creating an image: %w", err)
}
fmt.Println(id)
return nil
}
35 changes: 35 additions & 0 deletions cmd/ore/hetzner/gc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright The Mantle Authors.
// SPDX-License-Identifier: Apache-2.0

package hetzner

import (
"fmt"
"time"

"github.com/spf13/cobra"
)

var (
cmdGC = &cobra.Command{
Use: "gc",
Short: "GC resources in Hetzner",
Long: `Delete instances and images created over the given duration ago`,
RunE: runGC,
}

gcDuration time.Duration
)

func init() {
Hetzner.AddCommand(cmdGC)
cmdGC.Flags().DurationVar(&gcDuration, "duration", 5*time.Hour, "how old resources must be before they're considered garbage")
}

func runGC(cmd *cobra.Command, args []string) error {
if err := API.GC(cmd.Context(), gcDuration); err != nil {
return fmt.Errorf("running garbage collection: %w", err)
}

return nil
}
42 changes: 42 additions & 0 deletions cmd/ore/hetzner/hetzner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright The Mantle Authors.
// SPDX-License-Identifier: Apache-2.0

package hetzner

import (
"fmt"

"github.com/coreos/pkg/capnslog"
"github.com/spf13/cobra"

"github.com/flatcar/mantle/cli"
"github.com/flatcar/mantle/platform/api/hetzner"
)

var (
plog = capnslog.NewPackageLogger("github.com/flatcar/mantle", "ore/hetzner")

Hetzner = &cobra.Command{
Use: "hetzner [command]",
Short: "hetzner image utilities",
}

API *hetzner.API
options hetzner.Options
)

func init() {
cli.WrapPreRun(Hetzner, preflightCheck)
Hetzner.PersistentFlags().StringVar(&options.Token, "hetzner-token", "", "Hetzner token for client authentication")
Hetzner.PersistentFlags().StringVar(&options.Location, "hetzner-location", "", "Hetzner location name")
}

func preflightCheck(cmd *cobra.Command, args []string) error {
api, err := hetzner.New(&options)
if err != nil {
return fmt.Errorf("creating the Hetner API client: %w", err)
}

API = api
return nil
}
23 changes: 12 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2
github.com/anatol/tang.go v0.0.0-20230725175645-dcc6e9494f14
github.com/apricote/hcloud-upload-image/hcloudimages v0.3.0
github.com/aws/aws-sdk-go v1.44.46
github.com/brightbox/gobrightbox/v2 v2.2.0
github.com/coreos/butane v0.14.1-0.20220401164106-6b5239299226
Expand All @@ -31,6 +32,7 @@ require (
github.com/golang/protobuf v1.5.4
github.com/gophercloud/gophercloud v0.25.0
github.com/gophercloud/utils v0.0.0-20220704184730-55bdbbaec4ba
github.com/hetznercloud/hcloud-go/v2 v2.9.0
github.com/kballard/go-shellquote v0.0.0-20150810074751-d8ec1a69a250
github.com/kylelemons/godebug v1.1.0
github.com/packethost/packngo v0.21.0
Expand All @@ -50,8 +52,8 @@ require (
go.uber.org/zap v1.17.0
golang.org/x/crypto v0.24.0
golang.org/x/net v0.26.0
golang.org/x/oauth2 v0.14.0
golang.org/x/sys v0.21.0
golang.org/x/oauth2 v0.16.0
golang.org/x/sys v0.22.0
google.golang.org/api v0.126.0
gopkg.in/yaml.v3 v3.0.1
)
Expand All @@ -64,7 +66,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
github.com/ajeddeloh/go-json v0.0.0-20200220154158-5ae607161559 // indirect
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 // indirect
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/clarketm/json v1.17.1 // indirect
Expand All @@ -91,23 +93,22 @@ require (
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/json-iterator/go v1.1.11 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/jwx v1.2.29 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.11.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
go.etcd.io/bbolt v1.3.9 // indirect
go.etcd.io/etcd/api/v3 v3.5.13 // indirect
Expand All @@ -124,7 +125,7 @@ require (
go.uber.org/multierr v1.6.0 // indirect
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/term v0.21.0 // indirect
golang.org/x/term v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
Expand Down
Loading

0 comments on commit 6807d6c

Please sign in to comment.