Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Ping #300

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions cmd/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cmd

import (
"log"
"sort"
"sync"

"github.com/cdalar/onctl/internal/cloud"
"github.com/cdalar/onctl/internal/tools"
"github.com/spf13/cobra"
)

var pingCmd = &cobra.Command{
Use: "ping",
Short: "latency tests on multi cloud providers",
Run: func(cmd *cobra.Command, args []string) {
log.Println("[DEBUG] Ping")
messages := make(chan cloud.Location, 100)
listOfLocations, err := provider.Locations()
if err != nil {
log.Fatalln(err)
}
var wg sync.WaitGroup
for _, location := range listOfLocations {
wg.Add(1)
go func(location cloud.Location) {
defer wg.Done()
location.Latency, err = tools.Ping(location.Endpoint)
if err != nil {
log.Fatalln(err)
}
log.Println("[DEBUG]", location.Name, location.Latency)
messages <- location

}(location)
}
wg.Wait()
close(messages)
list := make([]cloud.Location, 0, 100)
for message := range messages {
list = append(list, message)
}

sort.Slice(list, func(i, j int) bool {
return list[i].Latency < list[j].Latency
})

log.Println("[DEBUG] Location List: ", list)
tmpl := "LOCATION\tLATENCY\n{{range .}}{{.Name}}\t{{.Latency}}\n{{end}}"
TabWriter(list, tmpl)
},
}
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func Execute() error {
case "gcp":
provider = &cloud.ProviderGcp{
Client: providergcp.GetClient(),
Regions: providergcp.GetRegionsClient(),
GroupClient: providergcp.GetGroupClient(),
}

Expand Down Expand Up @@ -92,4 +93,5 @@ func init() {
rootCmd.AddCommand(destroyCmd)
rootCmd.AddCommand(sshCmd)
rootCmd.AddCommand(initCmd)
rootCmd.AddCommand(pingCmd)
}
22 changes: 22 additions & 0 deletions internal/cloud/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,28 @@ func (p ProviderAws) Deploy(server Vm) (Vm, error) {
return mapAwsServer(instance), nil
}

func (p ProviderAws) Locations() ([]Location, error) {
log.Println("[DEBUG] Get Locations")
var locations []Location
output, err := p.Client.DescribeRegions(&ec2.DescribeRegionsInput{
// AllRegions: aws.Bool(true),
})
if err != nil {
log.Println(err)
}
log.Println("[DEBUG] " + output.String())
for _, region := range output.Regions {
log.Print("[DEBUG] " + *region.RegionName)
log.Println("[DEBUG] " + *region.Endpoint)
locations = append(locations, Location{
Name: *region.RegionName,
Endpoint: *region.Endpoint + ":443",
})
}

return locations, nil
}

func (p ProviderAws) Destroy(server Vm) error {
if server.ID == "" {
log.Println("[DEBUG] Server ID is empty")
Expand Down
5 changes: 5 additions & 0 deletions internal/cloud/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,11 @@ func (p ProviderAzure) Destroy(server Vm) error {

}

func (p ProviderAzure) Locations() ([]Location, error) {
log.Println("[DEBUG] Get Locations")
return []Location{}, nil
}

func (p ProviderAzure) SSHInto(serverName string, port int) {
s, err := p.GetByName(serverName)
if err != nil || s.ID == "" {
Expand Down
15 changes: 15 additions & 0 deletions internal/cloud/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ import (
"time"
)

type Location struct {
// ID
ID string
// Name is the name of the location
Name string
// Country is the country of the location
Region string
// Latency is the latency of the location
Latency time.Duration
// Endpoint is the endpoint of the location
Endpoint string
}

type VmList struct {
List []Vm
}
Expand Down Expand Up @@ -78,4 +91,6 @@ type CloudProviderInterface interface {
SSHInto(serverName string, port int)
// GetByName gets a VM by name
GetByName(serverName string) (Vm, error)
// GetLocation gets a location by name
Locations() ([]Location, error)
}
25 changes: 25 additions & 0 deletions internal/cloud/gcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,34 @@ var (

type ProviderGcp struct {
Client *compute.InstancesClient
Regions *compute.RegionsClient
GroupClient *compute.InstanceGroupsClient
}

func (p ProviderGcp) Locations() ([]Location, error) {
log.Println("[DEBUG] Get Locations")
regionList := make([]Location, 0, 100)
it := p.Regions.List(context.Background(), &computepb.ListRegionsRequest{
Project: viper.GetString("gcp.project"),
})

for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatalln(err)
}
regionList = append(regionList, Location{
Name: *resp.Name,
Endpoint: fmt.Sprintf("compute.%s.googleapis.com:443", *resp.Name),
})
log.Println("[DEBUG] Regions:", resp)
}
return regionList, nil
}

func (p ProviderGcp) List() (VmList, error) {
log.Println("[DEBUG] List Servers")
cloudList := make([]Vm, 0, 100)
Expand Down
19 changes: 19 additions & 0 deletions internal/cloud/hetzner.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,25 @@ func (p ProviderHetzner) Destroy(server Vm) error {
return nil
}

func (p ProviderHetzner) Locations() ([]Location, error) {
log.Println("[DEBUG] Get Locations")
list, err := p.Client.Location.All(context.TODO())
if err != nil {
log.Println(err)
}
if len(list) == 0 {
return []Location{}, nil
}
locationList := make([]Location, 0, len(list))
for _, location := range list {
locationList = append(locationList, Location{
Name: location.Name,
Endpoint: location.Name + "-speed.hetzner.com:80",
})
}
return locationList, nil
}

func (p ProviderHetzner) List() (VmList, error) {
log.Println("[DEBUG] List Servers")
list, _, err := p.Client.Server.List(context.TODO(), hcloud.ServerListOpts{
Expand Down
9 changes: 9 additions & 0 deletions internal/providergcp/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ func GetClient() *compute.InstancesClient {
return client
}

func GetRegionsClient() *compute.RegionsClient {
ctx := context.Background()
client, err := compute.NewRegionsRESTClient(ctx)
if err != nil {
log.Fatalln(err)
}
return client
}

func GetGroupClient() *compute.InstanceGroupsClient {
ctx := context.Background()
client, err := compute.NewInstanceGroupsRESTClient(ctx)
Expand Down
29 changes: 29 additions & 0 deletions internal/tools/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package tools

import (
"log"
"net"
"time"
)

func resolveDomain(domain string) (*net.TCPAddr, error) {
return net.ResolveTCPAddr("tcp4", domain)
}

func Ping(addr string) (time.Duration, error) {
tcpaddr, err := resolveDomain(addr)
if err != nil {
log.Fatalln("Error:", err)
}

start := time.Now()
// fsn1-speed.hetzner.com:80
conn, err := net.Dial("tcp", tcpaddr.String())
if err != nil {
log.Fatalln("Error:", err)

}
since := time.Since(start)
defer conn.Close()
return since, nil
}
Loading