From ee637c2989e586e8cbf1754c0e514564687b70ac Mon Sep 17 00:00:00 2001 From: Engin Diri Date: Tue, 13 Jul 2021 16:56:36 +0200 Subject: [PATCH] Add New Command - List Minecraft Server #11 Signed-off-by: Engin Diri --- README.md | 53 +++++++++++++++++++--- cmd/minectl/create.go | 14 ++++-- cmd/minectl/delete.go | 2 +- cmd/minectl/list.go | 46 +++++++++++++++---- config/bedrock/server-civo.yaml | 4 +- config/bedrock/server-do.yaml | 4 +- config/bedrock/server-scaleway.yaml | 4 +- go.mod | 5 ++- go.sum | 12 +++-- pgk/automation/automation.go | 5 ++- pgk/cloud/civo/civo.go | 37 +++++++++++++++- pgk/cloud/do/do.go | 24 +++++++++- pgk/cloud/scaleway/scaleway.go | 29 +++++++++--- pgk/common/common.go | 2 + pgk/provisioner/provisioner.go | 69 +++++++++++++++++++++-------- 15 files changed, 248 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 6fcf73e5..353260cc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,25 @@ -# minectl 🗺 ++ [TL;DR 🚀](#tldr-) ++ [Usage ⚙](#usage-) + - [Access Token 🔑](#access-token-) + * [Civo](#civo) + * [Digital Ocean](#digital-ocean) + * [Scaleway](#scaleway) + - [Server Config 📋](#server-config-) + - [Create Minecraft Server 🏗](#create-minecraft-server-) + - [Delete Minecraft Server 🗑](#delete-minecraft-server-) + - [List Minecraft Server 📒](#list-minecraft-server-) + - [Monitoring 📊](#monitoring-) + - [Getting Started 🎫](#getting-started-) ++ [Supported cloud provider ☁](#supported-cloud-provider-) ++ [Known Limitation 😵](#known-limitation-) ++ [Contributing 🤝](#contributing-) + - [Contributing via GitHub](#contributing-via-github) + - [License](#license) ++ [Roadmap 🛣️](#roadmap-) ++ [Libraries & Tools 🔥](#libraries--tools-) ++ [Legal Disclaimer 👮](#legal-disclaimer-) + +# minectl 🗺 ![Minecraft](https://img.shields.io/badge/Minecraft-62B47A?style=for-the-badge&logo=Minecraft&logoColor=white) ![Go](https://img.shields.io/badge/go-00ADD8?style=for-the-badge&logo=go&logoColor=white) @@ -26,7 +47,7 @@ the [release page](https://github.com/dirien/minectl/releases). ### Usage ⚙ -#### Access Token +#### Access Token 🔑 `minectl` is completely build on zero-trust. It does not save any API Tokens, instead it looks them up in the ENV variables. @@ -123,6 +144,27 @@ Flags: --id string contains the server id ``` +#### List Minecraft Server 📒 + +```bash +minectl list -h + +List all Minecraft Server. + +Usage: + minectl list [flags] + +Examples: +mincetl list \ + --provider civo \ + --region LON1 + +Flags: + -h, --help help for list + -p, --provider string The cloud provider - do, civo or scaleway + -r, --region string The region for your cloud provider +``` + #### Monitoring 📊 Every instance of minectl 🗺, has following monitoring components included: @@ -140,7 +182,7 @@ You can acces the `prometheus` via http://:9090/graph ``` -#### Getting Started +#### Getting Started 🎫 - [Civo Java Edition](docs/getting-started-civo.md) - [Civo Bedrock Edition](docs/getting-started-civo-bedrock.md) @@ -168,11 +210,11 @@ Feel free to join. Apache License, Version 2.0 -### Roadmap 🛣️ +### Roadmap 🛣 - [x] Support Bedrock edition [#10](https://github.com/dirien/minectl/issues/10) - [x] Add monitoring capabilities to minectl server [#21](https://github.com/dirien/minectl/issues/21) -- [ ] List Minecraft Server +- [x] List Minecraft Server [#11](https://github.com/dirien/minectl/issues/11) - [ ] Update Minecraft Server - [ ] Support Mods and Plugins - [ ] Add additional cloud provider @@ -188,6 +230,7 @@ Apache License, Version 2.0 - https://github.com/civo/civogo - https://github.com/digitalocean/godo - https://github.com/scaleway/scaleway-sdk-go +- https://github.com/olekukonko/tablewriter ### Legal Disclaimer 👮 diff --git a/cmd/minectl/create.go b/cmd/minectl/create.go index a48cd795..664535ec 100644 --- a/cmd/minectl/create.go +++ b/cmd/minectl/create.go @@ -4,7 +4,9 @@ import ( "fmt" "github.com/minectl/pgk/common" "github.com/minectl/pgk/provisioner" + "github.com/olekukonko/tablewriter" "log" + "os" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -33,7 +35,7 @@ func runCreate(cmd *cobra.Command, _ []string) error { if err != nil { return errors.Wrap(err, "Please provide a valid MinecraftServer manifest file") } - p, err := provisioner.NewCreateServerProvisioner(filename) + p, err := provisioner.NewProvisioner(filename) if err != nil { log.Fatal(err) } @@ -41,8 +43,14 @@ func runCreate(cmd *cobra.Command, _ []string) error { if err != nil { log.Fatal(err) } - common.PrintMixedGreen("Minecraft Server IP: %s\n", res.PublicIP) - common.PrintMixedGreen("Minecraft Server ID: %s\n", res.ID) + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader([]string{"ID", "NAME", "REGION", "TAGS", "IP"}) + + table.Append([]string{res.ID, res.Name, res.Region, res.Tags, res.PublicIP}) + + table.SetBorder(false) + fmt.Println("") + table.Render() common.PrintMixedGreen("\nTo delete the server type:\n\n %s", fmt.Sprintf("minectl delete -f %s --id %s\n", filename, res.ID)) return err diff --git a/cmd/minectl/delete.go b/cmd/minectl/delete.go index 1bb4d893..374993e1 100644 --- a/cmd/minectl/delete.go +++ b/cmd/minectl/delete.go @@ -34,7 +34,7 @@ func runDelete(cmd *cobra.Command, _ []string) error { return errors.Wrap(err, "failed to get 'filename' value.") } id, err := cmd.Flags().GetString("id") - newProvisioner, err := provisioner.NewDeleteServerProvisioner(id, filename) + newProvisioner, err := provisioner.NewProvisioner(filename, id) if err != nil { return err } diff --git a/cmd/minectl/list.go b/cmd/minectl/list.go index 114df26f..682c05ab 100644 --- a/cmd/minectl/list.go +++ b/cmd/minectl/list.go @@ -1,20 +1,26 @@ package minectl import ( + "fmt" + "github.com/minectl/pgk/provisioner" + "github.com/olekukonko/tablewriter" + "github.com/pkg/errors" "github.com/spf13/cobra" + "os" ) func init() { minectlCmd.AddCommand(listCmd) - listCmd.Flags().String("region", "", "that contains the configuration for minectl") - + listCmd.Flags().StringP("provider", "p", "", "The cloud provider - do, civo or scaleway") + listCmd.Flags().StringP("region", "r", "", "The region for your cloud provider") } var listCmd = &cobra.Command{ Use: "list", Short: "List all Minecraft Server.", Example: `mincetl list \ + --provider civo \ --region LON1`, RunE: runList, SilenceUsage: true, @@ -23,12 +29,36 @@ var listCmd = &cobra.Command{ func runList(cmd *cobra.Command, _ []string) error { - //_, err := cmd.Flags().GetString("filename") - /*if err != nil { - return errors.Wrap(err, "failed to get 'filename' value.") + provider, err := cmd.Flags().GetString("provider") + if err != nil { + return errors.Wrap(err, "failed to get 'provider' value.") + } + region, err := cmd.Flags().GetString("region") + if err != nil { + return errors.Wrap(err, "failed to get 'region' value.") + } + + newProvisioner, err := provisioner.ListProvisioner(provider, region) + if err != nil { + return err + } + servers, err := newProvisioner.ListServer() + if err != nil { + return err + } + + if len(servers) > 0 { + fmt.Println("") + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader([]string{"ID", "NAME", "REGION", "TAGS", "IP"}) + + for _, server := range servers { + table.Append([]string{server.ID, server.Name, server.Region, server.Tags, server.PublicIP}) + } + table.SetBorder(false) + table.Render() + } else { + fmt.Println("🤷 No server found") } - do, _ := provisioner.NewProvisioner(filename) - res, err := do.UpdateServer() - common.PrintMixedGreen("Minecraft Server IP: %s\n", res.PublicIP)*/ return nil } diff --git a/config/bedrock/server-civo.yaml b/config/bedrock/server-civo.yaml index 25e918ee..2289fb3d 100644 --- a/config/bedrock/server-civo.yaml +++ b/config/bedrock/server-civo.yaml @@ -1,14 +1,14 @@ apiVersion: ediri.io/minectl/v1alpha1 kind: MinecraftServer metadata: - name: minecraft-server + name: minecraft-server-be spec: server: cloud: civo region: LON1 size: g3.large volumeSize: 100 - ssh: "/Users/dirien/Tools/repos/stackit-minecraft/minecraft/ssh/minecraft.pub" + ssh: "/Users/dirien/Tools/repos/stackit-minecraft/minecraft/ssh/minecraft-be.pub" minecraft: edition: bedrock properties: | diff --git a/config/bedrock/server-do.yaml b/config/bedrock/server-do.yaml index abf0912a..116fdbe7 100644 --- a/config/bedrock/server-do.yaml +++ b/config/bedrock/server-do.yaml @@ -1,14 +1,14 @@ apiVersion: ediri.io/minectl/v1alpha1 kind: MinecraftServer metadata: - name: minecraft-server + name: minecraft-server-be spec: server: cloud: do region: fra1 size: s-4vcpu-8gb volumeSize: 100 - ssh: "/Users/dirien/Tools/repos/stackit-minecraft/minecraft/ssh/minecraft.pub" + ssh: "/Users/dirien/Tools/repos/stackit-minecraft/minecraft/ssh/minecraft-be.pub" minecraft: edition: bedrock properties: | diff --git a/config/bedrock/server-scaleway.yaml b/config/bedrock/server-scaleway.yaml index c789aef2..78d0431b 100644 --- a/config/bedrock/server-scaleway.yaml +++ b/config/bedrock/server-scaleway.yaml @@ -1,14 +1,14 @@ apiVersion: ediri.io/minectl/v1alpha1 kind: MinecraftServer metadata: - name: minecraft-server + name: minecraft-server-bedrock spec: server: cloud: scaleway region: fr-par-1 size: GP1-XS volumeSize: 100 - ssh: "/Users/dirien/Tools/repos/stackit-minecraft/minecraft/ssh/minecraft.pub" + ssh: "/Users/dirien/Tools/repos/stackit-minecraft/minecraft/ssh/minecraft-be.pub" minecraft: edition: bedrock properties: | diff --git a/go.mod b/go.mod index cecf136b..4482991e 100644 --- a/go.mod +++ b/go.mod @@ -9,15 +9,16 @@ require ( github.com/fatih/color v1.12.0 github.com/kr/pretty v0.2.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/magiconair/properties v1.8.0 github.com/morikuni/aec v1.0.0 + github.com/olekukonko/tablewriter v0.0.5 github.com/pkg/errors v0.9.1 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7 github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/testify v1.6.1 // indirect + github.com/stretchr/testify v1.6.1 github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 + golang.org/x/tools v0.0.0-20200825202427-b303f430e36d gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect sigs.k8s.io/yaml v1.2.0 ) diff --git a/go.sum b/go.sum index 5f4404be..8c0357cd 100644 --- a/go.sum +++ b/go.sum @@ -49,7 +49,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/civo/civogo v0.2.47 h1:qMzlm75hYOfuuvB0BXBaWhe/073TxzMNpYWkNKb5JR8= github.com/civo/civogo v0.2.47/go.mod h1:SR0ZOhABfQHjgNQE3UyfX4gaYsrfslkPFRFMx5P29rg= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -69,9 +68,7 @@ github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= @@ -162,7 +159,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= @@ -170,6 +166,8 @@ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -177,6 +175,8 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -356,7 +356,6 @@ golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fq golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -401,6 +400,7 @@ golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d h1:W07d4xkoAUSNOkOzdzXCdFGxT7o2rW4q8M34tB2i//k= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -458,7 +458,6 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -472,7 +471,6 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/pgk/automation/automation.go b/pgk/automation/automation.go index f23bc2a6..ce0a5dc6 100644 --- a/pgk/automation/automation.go +++ b/pgk/automation/automation.go @@ -5,7 +5,7 @@ import "github.com/minectl/pgk/model" type Automation interface { CreateServer(args ServerArgs) (*RessourceResults, error) DeleteServer(id string, args ServerArgs) error - ListServer(args ServerArgs) (*[]RessourceResults, error) + ListServer() ([]RessourceResults, error) UpdateServer(args ServerArgs) (*RessourceResults, error) } @@ -23,5 +23,8 @@ type ServerArgs struct { type RessourceResults struct { ID string + Name string + Region string PublicIP string + Tags string } diff --git a/pgk/cloud/civo/civo.go b/pgk/cloud/civo/civo.go index 935bad11..46b43796 100644 --- a/pgk/cloud/civo/civo.go +++ b/pgk/cloud/civo/civo.go @@ -9,6 +9,7 @@ import ( "github.com/minectl/pgk/common" minctlTemplate "github.com/minectl/pgk/template" "io/ioutil" + "strings" "time" ) @@ -57,6 +58,7 @@ func (c *Civo) CreateServer(args automation.ServerArgs) (*automation.RessourceRe config.SSHKeyID = sshPubKey.ID config.PublicIPRequired = "create" config.InitialUser = "root" + config.Tags = []string{common.InstanceTag, args.MinecraftServer.GetEdition()} tmpl, err := minctlTemplate.NewTemplateCivo(args.MinecraftServer) if err != nil { @@ -120,9 +122,16 @@ func (c *Civo) CreateServer(args automation.ServerArgs) (*automation.RessourceRe if err != nil { return nil, err } + region := c.client.Region + if len(instance.Region) > 0 { + region = instance.Region + } return &automation.RessourceResults{ ID: instance.ID, + Name: instance.Hostname, + Region: region, PublicIP: instance.PublicIP, + Tags: strings.Join(instance.Tags, ","), }, err } @@ -154,8 +163,32 @@ func (c *Civo) DeleteServer(id string, args automation.ServerArgs) error { return nil } -func (c *Civo) ListServer(args automation.ServerArgs) (*[]automation.RessourceResults, error) { - panic("implement me") +func (c *Civo) ListServer() ([]automation.RessourceResults, error) { + var result []automation.RessourceResults + instances, err := c.client.ListAllInstances() + if err != nil { + return nil, err + } + for _, instance := range instances { + if instance.Tags[0] == common.InstanceTag { + for _, tag := range instance.Tags { + if tag == common.InstanceTag { + region := c.client.Region + if len(instance.Region) > 0 { + region = instance.Region + } + result = append(result, automation.RessourceResults{ + ID: instance.ID, + PublicIP: instance.PublicIP, + Name: instance.Hostname, + Region: region, + Tags: strings.Join(instance.Tags, ","), + }) + } + } + } + } + return result, nil } func (c *Civo) UpdateServer(args automation.ServerArgs) (*automation.RessourceResults, error) { diff --git a/pgk/cloud/do/do.go b/pgk/cloud/do/do.go index 84898d43..fdf13871 100644 --- a/pgk/cloud/do/do.go +++ b/pgk/cloud/do/do.go @@ -12,6 +12,7 @@ import ( "golang.org/x/oauth2" "io/ioutil" "strconv" + "strings" "time" ) @@ -45,8 +46,23 @@ func NewDigitalOcean(APIKey string) (*DigitalOcean, error) { return do, nil } -func (d *DigitalOcean) ListServer(args automation.ServerArgs) (*[]automation.RessourceResults, error) { - panic("implement me") +func (d *DigitalOcean) ListServer() ([]automation.RessourceResults, error) { + droplets, _, err := d.client.Droplets.ListByTag(context.Background(), common.InstanceTag, nil) + if err != nil { + return nil, err + } + var result []automation.RessourceResults + for _, droplet := range droplets { + ipv4, _ := droplet.PublicIPv4() + result = append(result, automation.RessourceResults{ + ID: strconv.Itoa(droplet.ID), + PublicIP: ipv4, + Name: droplet.Name, + Region: droplet.Region.Slug, + Tags: strings.Join(droplet.Tags, ","), + }) + } + return result, nil } func (d *DigitalOcean) UpdateServer(args automation.ServerArgs) (*automation.RessourceResults, error) { @@ -102,6 +118,7 @@ func (d *DigitalOcean) CreateServer(args automation.ServerArgs) (*automation.Res Slug: "ubuntu-20-04-x64", }, UserData: userData, + Tags: []string{common.InstanceTag, args.MinecraftServer.GetEdition()}, Volumes: []godo.DropletCreateVolume{ { ID: volume.ID, @@ -135,7 +152,10 @@ func (d *DigitalOcean) CreateServer(args automation.ServerArgs) (*automation.Res return &automation.RessourceResults{ ID: strconv.Itoa(droplet.ID), + Name: droplet.Name, + Region: droplet.Region.Slug, PublicIP: ipv4, + Tags: strings.Join(droplet.Tags, ","), }, err } diff --git a/pgk/cloud/scaleway/scaleway.go b/pgk/cloud/scaleway/scaleway.go index 8eb5912f..4fe2248e 100644 --- a/pgk/cloud/scaleway/scaleway.go +++ b/pgk/cloud/scaleway/scaleway.go @@ -42,6 +42,7 @@ func NewScaleway(accessKey, secretKey, organizationID, region string) (*Scaleway } func (s Scaleway) CreateServer(args automation.ServerArgs) (*automation.RessourceResults, error) { + pubKeyFile, err := ioutil.ReadFile(args.MinecraftServer.GetSSH()) _, err = s.accountAPI.CreateSSHKey(&account.CreateSSHKeyRequest{ Name: fmt.Sprintf("%s-ssh", args.MinecraftServer.GetName()), @@ -50,25 +51,22 @@ func (s Scaleway) CreateServer(args automation.ServerArgs) (*automation.Ressourc if err != nil { return nil, err } - server, err := s.instanceAPI.CreateServer(&instance.CreateServerRequest{ Name: args.MinecraftServer.GetName(), CommercialType: args.MinecraftServer.GetSize(), Image: "ubuntu_focal", - Tags: []string{"minecraft"}, + Tags: []string{"minectl"}, DynamicIPRequired: scw.BoolPtr(true), }) if err != nil { return nil, err } - tmpl, err := minctlTemplate.NewTemplateCloudConfig(args.MinecraftServer, "sda") if err != nil { return nil, err } userData, err := tmpl.GetTemplate() - err = s.instanceAPI.SetServerUserData(&instance.SetServerUserDataRequest{ ServerID: server.Server.ID, Key: "cloud-init", @@ -118,7 +116,10 @@ func (s Scaleway) CreateServer(args automation.ServerArgs) (*automation.Ressourc return &automation.RessourceResults{ ID: server.Server.ID, + Name: server.Server.Name, + Region: server.Server.Zone.String(), PublicIP: getServer.Server.PublicIP.Address.String(), + Tags: strings.Join(server.Server.Tags, ","), }, err } @@ -167,8 +168,24 @@ func (s Scaleway) DeleteServer(id string, args automation.ServerArgs) error { return nil } -func (s Scaleway) ListServer(args automation.ServerArgs) (*[]automation.RessourceResults, error) { - panic("implement me") +func (s Scaleway) ListServer() ([]automation.RessourceResults, error) { + servers, err := s.instanceAPI.ListServers(&instance.ListServersRequest{ + Tags: []string{common.InstanceTag}, + }) + if err != nil { + return nil, err + } + var result []automation.RessourceResults + for _, server := range servers.Servers { + result = append(result, automation.RessourceResults{ + ID: server.ID, + PublicIP: server.PublicIP.Address.String(), + Name: server.Name, + Region: server.Zone.String(), + Tags: strings.Join(server.Tags, ","), + }) + } + return result, nil } func (s Scaleway) UpdateServer(args automation.ServerArgs) (*automation.RessourceResults, error) { diff --git a/pgk/common/common.go b/pgk/common/common.go index 984cdbb1..a9c203c0 100644 --- a/pgk/common/common.go +++ b/pgk/common/common.go @@ -5,6 +5,8 @@ import ( "github.com/fatih/color" ) +const InstanceTag = "minectl" + func PrintMixedGreen(format string, value string) { green := color.New(color.FgGreen).SprintFunc() fmt.Printf(format, green(value)) diff --git a/pgk/provisioner/provisioner.go b/pgk/provisioner/provisioner.go index 0e81123d..f44f77c1 100644 --- a/pgk/provisioner/provisioner.go +++ b/pgk/provisioner/provisioner.go @@ -1,6 +1,7 @@ package provisioner import ( + "fmt" "github.com/minectl/pgk/automation" "github.com/minectl/pgk/cloud" "github.com/minectl/pgk/cloud/civo" @@ -8,6 +9,7 @@ import ( "github.com/minectl/pgk/cloud/scaleway" "github.com/minectl/pgk/common" "github.com/minectl/pgk/manifest" + "github.com/pkg/errors" "os" ) @@ -21,6 +23,7 @@ type Provisioner interface { CreateServer() (*automation.RessourceResults, error) DeleteServer() error UpdateServer() (*automation.RessourceResults, error) + ListServer() ([]automation.RessourceResults, error) } func (p PulumiProvisioner) UpdateServer() (*automation.RessourceResults, error) { @@ -31,45 +34,73 @@ func (p PulumiProvisioner) CreateServer() (*automation.RessourceResults, error) return p.auto.CreateServer(p.args) } -func (p PulumiProvisioner) DeleteServer() error { - return p.auto.DeleteServer(p.args.ID, p.args) +func (p PulumiProvisioner) ListServer() ([]automation.RessourceResults, error) { + return p.auto.ListServer() } -func NewCreateServerProvisioner(manifestPath string) (*PulumiProvisioner, error) { - return newProvisioner(manifestPath, "") +func (p PulumiProvisioner) DeleteServer() error { + return p.auto.DeleteServer(p.args.ID, p.args) } -func NewDeleteServerProvisioner(id, manifestPath string) (*PulumiProvisioner, error) { - return newProvisioner(manifestPath, id) +// NewProvisioner has variable args: only manifest file or manifest file and the id +func NewProvisioner(args ...string) (*PulumiProvisioner, error) { + if len(args) == 2 { + return newProvisioner(args[0], args[1]) + } + return newProvisioner(args[0], "") } -func newProvisioner(manifestPath, id string) (*PulumiProvisioner, error) { - manifest, err := manifest.NewMinecraftServer(manifestPath) +func ListProvisioner(args ...string) (*PulumiProvisioner, error) { + fmt.Println("📒 List all server") + cloudProvider, err := getProvisioner(args[0], args[1]) + common.PrintMixedGreen("🛎 Using cloud provider %s\n", cloud.GetCloudProviderFullName(args[0])) if err != nil { return nil, err } - args := automation.ServerArgs{ - MinecraftServer: manifest.MinecraftServer, - ID: id, + p := &PulumiProvisioner{ + auto: cloudProvider, } + return p, nil +} - var cloudProvider automation.Automation - common.PrintMixedGreen("🛎 Using cloud provider %s\n", cloud.GetCloudProviderFullName(args.MinecraftServer.GetCloud())) - if args.MinecraftServer.GetCloud() == "do" { - cloudProvider, err = do.NewDigitalOcean(os.Getenv("DIGITALOCEAN_TOKEN")) +func getProvisioner(provider, region string) (automation.Automation, error) { + switch provider { + case "do": + cloudProvider, err := do.NewDigitalOcean(os.Getenv("DIGITALOCEAN_TOKEN")) if err != nil { return nil, err } - } else if args.MinecraftServer.GetCloud() == "civo" { - cloudProvider, err = civo.NewCivo(os.Getenv("CIVO_TOKEN"), args.MinecraftServer.GetRegion()) + return cloudProvider, nil + case "civo": + cloudProvider, err := civo.NewCivo(os.Getenv("CIVO_TOKEN"), region) if err != nil { return nil, err } - } else if manifest.MinecraftServer.GetCloud() == "scaleway" { - cloudProvider, err = scaleway.NewScaleway(os.Getenv("ACCESS_KEY"), os.Getenv("SECRET_KEY"), os.Getenv("ORGANISATION_ID"), args.MinecraftServer.GetRegion()) + return cloudProvider, nil + case "scaleway": + cloudProvider, err := scaleway.NewScaleway(os.Getenv("ACCESS_KEY"), os.Getenv("SECRET_KEY"), os.Getenv("ORGANISATION_ID"), region) if err != nil { return nil, err } + return cloudProvider, nil + default: + return nil, errors.Errorf("Could not find provider %s", provider) + } +} + +func newProvisioner(manifestPath, id string) (*PulumiProvisioner, error) { + manifest, err := manifest.NewMinecraftServer(manifestPath) + if err != nil { + return nil, err + } + args := automation.ServerArgs{ + MinecraftServer: manifest.MinecraftServer, + ID: id, + } + cloudProvider, err := getProvisioner(args.MinecraftServer.GetCloud(), args.MinecraftServer.GetRegion()) + common.PrintMixedGreen("🛎 Using cloud provider %s\n", cloud.GetCloudProviderFullName(args.MinecraftServer.GetCloud())) + if err != nil { + return nil, err } common.PrintMixedGreen("🗺 Minecraft %s edition\n", args.MinecraftServer.GetEdition())