Skip to content

Commit

Permalink
nomad provider
Browse files Browse the repository at this point in the history
  • Loading branch information
mkvolkov committed May 30, 2024
1 parent ef5fbbc commit eb6d4fa
Show file tree
Hide file tree
Showing 7 changed files with 564 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ Install with `go get -u github.com/knadh/koanf/providers/$provider`
| etcd/v2 | `etcd.Provider(etcd.Config{})` | CNCF etcd provider |
| consul/v2 | `consul.Provider(consul.Config{})` | Hashicorp Consul provider |
| parameterstore/v2 | `parameterstore.Provider(parameterstore.Config{})` | AWS Systems Manager Parameter Store provider |
| nomad/v2 | `nomad.Provider(api.Config{}, datatype string)` | Nomad provider |


### Bundled Parsers
Expand Down
25 changes: 25 additions & 0 deletions examples/read-nomad/httpecho.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
job "httpecho" {
datacenters = ["dc1"]

group "echo" {
count = 5
network {
port "http" {}
}

task "server" {
driver = "docker"

config {
image = "hashicorp/http-echo:latest"

ports = ["http"]

args = [
"-listen", ":${NOMAD_PORT_http}",
"-text", "Hello and welcome to ${NOMAD_IP_http} running on port ${NOMAD_PORT_http}",
]
}
}
}
}
282 changes: 282 additions & 0 deletions examples/read-nomad/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
package main

import (
"encoding/json"
"fmt"
"log"
"os"
"os/exec"
"strconv"

"github.com/hashicorp/nomad/api"

Check failure on line 11 in examples/read-nomad/main.go

View workflow job for this annotation

GitHub Actions / Go 1.20 Tests

no required module provides package github.com/hashicorp/nomad/api; to add it:

Check failure on line 11 in examples/read-nomad/main.go

View workflow job for this annotation

GitHub Actions / Go 1.21 Tests

no required module provides package github.com/hashicorp/nomad/api; to add it:
"github.com/knadh/koanf/providers/nomad/v2"

Check failure on line 12 in examples/read-nomad/main.go

View workflow job for this annotation

GitHub Actions / Go 1.20 Tests

no required module provides package github.com/knadh/koanf/providers/nomad/v2; to add it:

Check failure on line 12 in examples/read-nomad/main.go

View workflow job for this annotation

GitHub Actions / Go 1.21 Tests

no required module provides package github.com/knadh/koanf/providers/nomad/v2; to add it:
"github.com/knadh/koanf/v2"
)

// Example and test
// Requirements:
//
// - Docker installed
// - Docker daemon running
// - Nomad installed
// - Nomad running
// (sudo nomad agent -dev)
// - Nomad echo project running
// (nomad run httpecho.hcl)
// - curl
func main() {
fmt.Printf("Checking...\n")
var k = koanf.New(".")
var k2 = koanf.New(".")
var k3 = koanf.New(".")

// allocs
out, err := exec.Command("curl", "http://localhost:4646/v1/allocations").Output()
if err != nil {
log.Fatalf("error retreiving allocs from curl: %v\n", err)
}

var aListStub = []api.AllocationListStub{}
if err = json.Unmarshal(out, &aListStub); err != nil {
log.Fatalf("error unmarshalling alloc list: %s\n", err)
}

nAllocs := len(aListStub)
allocsHTTPData := make([]api.Allocation, nAllocs)

for i := 0; i < nAllocs; i++ {
cmdPath := fmt.Sprintf("http://localhost:4646/v1/allocation/%s", aListStub[i].ID)
out, err := exec.Command("curl", cmdPath).Output()
if err != nil {
log.Fatalf("error retrieving alloc with ID = %s: %s\n", aListStub[i].ID, err)
}

json.Unmarshal(out, &allocsHTTPData[i])
}

nmdAllocs, err := nomad.Provider(nil, "allocs")
if err != nil {
log.Fatalf("error creating provider: %v\n", err)
}

if err = k.Load(nmdAllocs, nil); err != nil {
log.Fatalf("error loading allocs: %v\n", err)
}

// allocs: checking
for i1 := 0; i1 < nAllocs; i1++ {
ID := allocsHTTPData[i1].ID

var key string
var flagFound bool = false

// finding alloc with this ID
for i2 := 0; i2 < nAllocs; i2++ {
key = "echo" + strconv.Itoa(i2)
if k.String(key+".ID") == ID {
flagFound = true
break
}
}

if !flagFound {
log.Fatalf("Alloc ID not found: test failed\n")
}

// comparing all data
if k.String(key+".Namespace") != allocsHTTPData[i1].Namespace {
fmt.Printf("Alloc Namespace: test failed\n")
os.Exit(1)
}

if k.String(key+".EvalID") != allocsHTTPData[i1].EvalID {
fmt.Printf("Alloc EvalID: test failed\n")
os.Exit(1)
}

if k.String(key+".Name") != allocsHTTPData[i1].Name {
fmt.Printf("Alloc Name: test failed\n")
os.Exit(1)
}

if k.String(key+".NodeID") != allocsHTTPData[i1].NodeID {
fmt.Printf("Alloc NodeID: test failed\n")
os.Exit(1)
}

if k.String(key+".NodeName") != allocsHTTPData[i1].NodeName {
fmt.Printf("Alloc NodeName: test failed\n")
os.Exit(1)
}

if k.String(key+".JobID") != allocsHTTPData[i1].JobID {
fmt.Printf("Alloc JobID: test failed\n")
os.Exit(1)
}

if k.String(key+".TaskGroup") != allocsHTTPData[i1].TaskGroup {
fmt.Printf("Alloc TaskGroup: test failed\n")
os.Exit(1)
}

if k.String(key+".DesiredStatus") != allocsHTTPData[i1].DesiredStatus {
fmt.Printf("Alloc DesiredStatus: test failed\n")
os.Exit(1)
}

if k.String(key+".ClientStatus") != allocsHTTPData[i1].ClientStatus {
fmt.Printf("Alloc ClientStatus: test failed\n")
os.Exit(1)
}

if k.String(key+".DeploymentID") != allocsHTTPData[i1].DeploymentID {
fmt.Printf("Alloc DeploymentID: test failed\n")
os.Exit(1)
}

if k.String(key+".DeploymentID") == allocsHTTPData[i1].ID {
fmt.Printf("Alloc DeploymentID = ID: test failed\n")
os.Exit(1)
}

// network comparison
for k1 := 0; k1 < len(allocsHTTPData[i1].Resources.Networks); k1++ {
ipSearch := allocsHTTPData[i1].Resources.Networks[k1].IP

// ipSearch in koanf
// koanf key
var keyNetwork string
for k2 := 0; k2 < len(allocsHTTPData[i1].Resources.Networks); k2++ {
keyNetwork = key + ".Network" + strconv.Itoa(k1) + ".IP"
if ipSearch == k.String(keyNetwork) {
break
}
}

// port search
for k2 := 0; k2 < len(allocsHTTPData[i1].Resources.Networks[k1].DynamicPorts); k2++ {
flagPort := false
for k3 := 0; k3 <= k2; k3++ {
keyPort := key + ".Network" + strconv.Itoa(k1) + ".Port" + strconv.Itoa(k3)
if k.Int(keyPort) == allocsHTTPData[i1].Resources.Networks[k1].DynamicPorts[k2].Value {
flagPort = true
break
}
}

if flagPort {
flagPort = false
} else {
fmt.Printf(
"Alloc ports: test failed, port %d isn't found\n",
allocsHTTPData[i1].Resources.Networks[k1].DynamicPorts[k2].Value)
os.Exit(1)
}
}
}
}

fmt.Printf("Allocations: test passed\n")

// raft
out, err = exec.Command("curl", "http://localhost:4646/v1/operator/raft/configuration").Output()
if err != nil {
log.Fatalf("error retreiving raft configuration from curl: %v\n", err)
}

raftCfg := api.RaftConfiguration{}
if err = json.Unmarshal(out, &raftCfg); err != nil {
log.Fatalf("error unmarshalling raft configuration: %s\n", err)
}

nmdRaft, err := nomad.Provider(nil, "raft")
if err != nil {
log.Fatalf("error creating provider: %v\n", err)
}

if err = k2.Load(nmdRaft, nil); err != nil {
log.Fatalf("error loading allocs: %v\n", err)
}

nServers := len(raftCfg.Servers)

// raft: checking
for i1 := 0; i1 < nServers; i1++ {
ID := raftCfg.Servers[i1].ID

var key string
var flagFound bool = false

// finding alloc with this ID
for i2 := 0; i2 < nServers; i2++ {
key = "server" + strconv.Itoa(i2)
if k2.String(key+".ID") == ID {
flagFound = true
break
}
}

if !flagFound {
log.Fatalf("Raft server ID not found: test failed")
}

if k2.String(key+".Node") != raftCfg.Servers[i1].Node {
log.Fatalf("Raft server node: test failed")
}

if k2.String(key+".Address") != raftCfg.Servers[i1].Address {
log.Fatalf("Raft server address: test failed")
}

if k2.Bool(key+".Leader") != raftCfg.Servers[i1].Leader {
log.Fatalf("Raft server leader: test failed")
}

if k2.Bool(key+".Voter") != raftCfg.Servers[i1].Voter {
log.Fatalf("Raft server voter: test failed")
}

if k2.String(key+".RaftProtocol") != raftCfg.Servers[i1].RaftProtocol {
log.Fatalf("Raft server protocol: test failed")
}
}

fmt.Printf("Raft configuration: test passed\n")

// vars
_, err = exec.Command(
"curl",
"--header",
"Content-Type: application/json",
"--request",
"POST",
"--data",
`{"Path": "databases/sql", "Items": {"mysql": "75cp21", "postgresql": "52pg24"}}`,
"http://localhost:4646/v1/var/databases/sql",
).Output()
if err != nil {
log.Fatalf("Couldn't create variables: %v\n", err)
}

nmdVars, err := nomad.Provider(nil, "vars")
if err != nil {
log.Fatalf("error creating provider: %v\n", err)
}

if err = k3.Load(nmdVars, nil); err != nil {
log.Fatalf("error loading vars: %v\n", err)
}

// vars: checking
if k3.String("databases/sql.mysql") != "75cp21" {
log.Fatalf("Vars: test failed\n")
}

if k3.String("databases/sql.postgresql") != "52pg24" {
log.Fatalf("Vars: test failed\n")
}

fmt.Printf("Vars: test passed\n")

fmt.Printf("ALL TESTS PASSED\n")
}
7 changes: 2 additions & 5 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q=
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
Expand All @@ -137,18 +136,16 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb
github.com/hashicorp/consul/sdk v0.13.1/go.mod h1:SW/mM4LbKfqmMvcFu8v+eiQQ7oitXEFeiBe9StxERb0=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
Expand Down
19 changes: 19 additions & 0 deletions providers/nomad/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module github.com/knadh/koanf/providers/nomad/v2

go 1.22.3

require github.com/hashicorp/nomad/api v0.0.0-20240530092428-bf11e39ac86f

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/cronexpr v1.1.2 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit eb6d4fa

Please sign in to comment.