inital release refactor

This commit is contained in:
Alex Lovell-Troy 2023-09-14 15:10:08 -04:00
parent 34367f830a
commit 3351de48a6
12 changed files with 215 additions and 84 deletions

40
.goreleaser.yaml Normal file
View file

@ -0,0 +1,40 @@
before:
hooks:
- go mod download
builds:
- env:
- CGO_ENABLED=0
goos:
- darwin
- linux
- windows
goarch:
- amd64
archives:
- format_overrides:
- goos: windows
format: zip
dockers:
- image_templates:
- "bikeshack.azurecr.io/magellan:latest"
- "bikeshack.azurecr.io/magellan:{{ .Major }}"
- "bikeshack.azurecr.io/magellan:{{ .Major }}.{{ .Minor }}"
- "bikeshack.azurecr.io/magellan:{{ .Major }}.{{ .Minor }}.{{ .Patch }}"
dockerfile: goreleaser.Dockerfile
build_flag_templates:
- "--pull"
- "--no-cache"
- "--build-arg=REGISTRY_HOST=docker.io/library/"
# OCI annotations: https://github.com/opencontainers/image-spec/blob/main/annotations.md
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.name={{.ProjectName}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Version}}"
- "--label=org.opencontainers.image.source={{.GitURL}}"
release:
github:
name_template: "{{.Version}}"
prerelease: auto
mode: append
changelog:
skip: true

87
Makefile Normal file
View file

@ -0,0 +1,87 @@
# import config.
# You can change the default config with `make cnf="config_special.env" build`
cnf ?= config.env
include $(cnf)
export $(shell sed 's/=.*//' $(cnf))
ifndef NAME
$(error NAME is not set. Please review and copy config.env.default to config.env and try again)
endif
ifndef VERSION
$(error VERSION is not set. Please review and copy config.env.default to config.env and try again)
endif
SHELL := /bin/bash
.DEFAULT_GOAL := all
.PHONY: all
all: ## build pipeline
all: mod inst build spell lint test
.PHONY: ci
ci: ## CI build pipeline
ci: all diff
.PHONY: help
help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.PHONY: clean
clean: ## remove files created during build pipeline
$(call print-target)
rm -rf dist
rm -f coverage.*
rm -f '"$(shell go env GOCACHE)/../golangci-lint"'
go clean -i -cache -testcache -modcache -fuzzcache -x
.PHONY: mod
mod: ## go mod tidy
$(call print-target)
go mod tidy
.PHONY: inst
inst: ## go install tools
$(call print-target)
go install github.com/client9/misspell/cmd/misspell@v0.3.4
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.52.2
go install github.com/goreleaser/goreleaser@v1.18.2
.PHONY: build
build: ## goreleaser build
build:
$(call print-target)
goreleaser build --clean --single-target --snapshot
.PHONY: docker
docker: ## docker build
docker:
$(call print-target)
docker build . --build-arg REGISTRY_HOST=${REGISTRY_HOST} --no-cache --pull --tag '${NAME}:${VERSION}'
.PHONY: spell
spell: ## misspell
$(call print-target)
misspell -error -locale=US -w **.md
.PHONY: lint
lint: ## golangci-lint
$(call print-target)
golangci-lint run --fix
.PHONY: test
test: ## go test
$(call print-target)
go test -race -covermode=atomic -coverprofile=coverage.out -coverpkg=./... ./...
go tool cover -html=coverage.out -o coverage.html
.PHONY: diff
diff: ## git diff
$(call print-target)
git diff --exit-code
RES=$$(git status --porcelain) ; if [ -n "$$RES" ]; then echo $$RES && exit 1 ; fi
define print-target
@printf "Executing target: \033[36m$@\033[0m\n"
endef

View file

@ -1,18 +1,17 @@
package cmd
import (
magellan "davidallendj/magellan/internal"
"davidallendj/magellan/internal/api/smd"
"davidallendj/magellan/internal/db/sqlite"
magellan "github.com/bikeshack/magellan/internal"
"github.com/bikeshack/magellan/internal/api/smd"
"github.com/bikeshack/magellan/internal/db/sqlite"
"github.com/cznic/mathutil"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var collectCmd = &cobra.Command{
Use: "collect",
Use: "collect",
Short: "Query information about BMC",
Run: func(cmd *cobra.Command, args []string) {
// make application logger
@ -28,13 +27,13 @@ var collectCmd = &cobra.Command{
threads = mathutil.Clamp(len(probeStates), 1, 255)
}
q := &magellan.QueryParams{
User: user,
Pass: pass,
Drivers: drivers,
Timeout: timeout,
Threads: threads,
Verbose: verbose,
WithSecureTLS: withSecureTLS,
User: user,
Pass: pass,
Drivers: drivers,
Timeout: timeout,
Threads: threads,
Verbose: verbose,
WithSecureTLS: withSecureTLS,
}
magellan.CollectInfo(&probeStates, l, q)
@ -46,7 +45,7 @@ var collectCmd = &cobra.Command{
},
}
func init(){
func init() {
collectCmd.PersistentFlags().StringSliceVar(&drivers, "driver", []string{"redfish"}, "set the driver(s) and fallback drivers to use")
collectCmd.PersistentFlags().StringVar(&smd.Host, "host", smd.Host, "set the host to the smd API")
collectCmd.PersistentFlags().IntVar(&smd.Port, "port", smd.Port, "set the port to the smd API")

View file

@ -1,16 +1,16 @@
package cmd
import (
"davidallendj/magellan/internal/db/sqlite"
"fmt"
"github.com/bikeshack/magellan/internal/db/sqlite"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var listCmd = &cobra.Command{
Use: "list",
Use: "list",
Short: "List information from scan",
Run: func(cmd *cobra.Command, args []string) {
probeResults, err := sqlite.GetProbeResults(dbpath)

View file

@ -1,10 +1,11 @@
package cmd
import (
magellan "davidallendj/magellan/internal"
"davidallendj/magellan/internal/db/sqlite"
"fmt"
magellan "github.com/bikeshack/magellan/internal"
"github.com/bikeshack/magellan/internal/db/sqlite"
"github.com/cznic/mathutil"
"github.com/spf13/cobra"
)

5
config.env Normal file
View file

@ -0,0 +1,5 @@
## This configuration is used by the Makefile
NAME=magellan
VERSION=$(shell git describe --tags --abbrev=0)

8
go.mod
View file

@ -1,10 +1,9 @@
module davidallendj/magellan
module github.com/bikeshack/magellan
go 1.20
replace github.com/bmc-toolbox/dora => ../../dora
require (
github.com/Cray-HPE/hms-xname v1.3.0
github.com/bmc-toolbox/bmclib/v2 v2.0.1-0.20230714152943-a1b87e2ff47f
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548
github.com/jacobweinstock/registrar v0.4.7
@ -13,10 +12,10 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0
github.com/stmcginnis/gofish v0.14.0
golang.org/x/exp v0.0.0-20230127130021-4ca2cb1a16b7
)
require (
github.com/Cray-HPE/hms-xname v1.3.0 // indirect
github.com/VictorLowther/simplexml v0.0.0-20180716164440-0bff93621230 // indirect
github.com/VictorLowther/soap v0.0.0-20150314151524-8e36fca84b22 // indirect
github.com/bmc-toolbox/common v0.0.0-20230717121556-5eb9915a8a5a // indirect
@ -31,7 +30,6 @@ require (
github.com/satori/go.uuid v1.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.8.3 // indirect
golang.org/x/exp v0.0.0-20230127130021-4ca2cb1a16b7 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/sys v0.11.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect

View file

@ -1,31 +1,32 @@
package dora
import (
"davidallendj/magellan/internal/api"
"encoding/json"
"fmt"
"github.com/bikeshack/magellan/internal/api"
"github.com/jmoiron/sqlx"
)
const (
Host = "http://localhost"
DbType = "sqlite3"
DbPath = "../data/assets.db"
Host = "http://localhost"
DbType = "sqlite3"
DbPath = "../data/assets.db"
BaseEndpoint = "/v1"
Port = 8000
Port = 8000
)
type ScannedResult struct {
id string
site any
cidr string
ip string
port int
id string
site any
cidr string
ip string
port int
protocol string
scanner string
state string
updated string
scanner string
state string
updated string
}
func makeEndpointUrl(endpoint string) string {

View file

@ -4,18 +4,18 @@ package smd
// https://github.com/Cray-HPE/hms-smd/blob/master/docs/examples.adoc
// https://github.com/alexlovelltroy/hms-smd
import (
"davidallendj/magellan/internal/api"
"fmt"
"github.com/bikeshack/magellan/internal/api"
// hms "github.com/alexlovelltroy/hms-smd"
)
var (
Host = "http://localhost"
Host = "http://localhost"
BaseEndpoint = "/hsm/v2"
Port = 27779
Port = 27779
)
func makeEndpointUrl(endpoint string) string {
return Host + ":" + fmt.Sprint(Port) + BaseEndpoint + endpoint
}

View file

@ -3,13 +3,14 @@ package magellan
import (
"context"
"crypto/x509"
"davidallendj/magellan/internal/api/smd"
"encoding/json"
"fmt"
"os"
"sync"
"time"
"github.com/bikeshack/magellan/internal/api/smd"
"github.com/Cray-HPE/hms-xname/xnames"
bmclib "github.com/bmc-toolbox/bmclib/v2"
"github.com/jacobweinstock/registrar"
@ -42,13 +43,13 @@ type QueryParams struct {
User string
Pass string
Drivers []string
Threads int
Preferred string
Threads int
Preferred string
Timeout int
WithSecureTLS bool
CertPoolFile string
Verbose bool
IpmitoolPath string
IpmitoolPath string
}
func NewClient(l *Logger, q *QueryParams) (*bmclib.Client, error) {
@ -123,15 +124,15 @@ func CollectInfo(probeStates *[]BMCProbeResult, l *Logger, q *QueryParams) error
// generate custom xnames for bmcs
node := xnames.Node{
Cabinet: 1000,
Chassis: 1,
ComputeModule: 7,
NodeBMC: -1,
Cabinet: 1000,
Chassis: 1,
ComputeModule: 7,
NodeBMC: -1,
}
found := make([]string, 0, len(*probeStates))
done := make(chan struct{}, q.Threads+1)
chanProbeState := make(chan BMCProbeResult, q.Threads+1)
found := make([]string, 0, len(*probeStates))
done := make(chan struct{}, q.Threads+1)
chanProbeState := make(chan BMCProbeResult, q.Threads+1)
// collect bmc information asynchronously
var wg sync.WaitGroup
@ -139,7 +140,7 @@ func CollectInfo(probeStates *[]BMCProbeResult, l *Logger, q *QueryParams) error
for i := 0; i < q.Threads; i++ {
go func() {
for {
ps, ok := <- chanProbeState
ps, ok := <-chanProbeState
if !ok {
wg.Done()
return
@ -181,13 +182,13 @@ func CollectInfo(probeStates *[]BMCProbeResult, l *Logger, q *QueryParams) error
headers["Content-Type"] = "application/json"
data := make(map[string]any)
data["ID"] = fmt.Sprintf("%v", node.String()[:len(node.String())-2])
data["Type"] = ""
data["Name"] = ""
data["FQDN"] = ps.Host
data["RediscoverOnUpdate"] = false
data["Inventory"] = inventory
data["Chassis"] = chassis
data["ID"] = fmt.Sprintf("%v", node.String()[:len(node.String())-2])
data["Type"] = ""
data["Name"] = ""
data["FQDN"] = ps.Host
data["RediscoverOnUpdate"] = false
data["Inventory"] = inventory
data["Chassis"] = chassis
b, err := json.MarshalIndent(data, "", " ")
if err != nil {
@ -228,7 +229,7 @@ func CollectInfo(probeStates *[]BMCProbeResult, l *Logger, q *QueryParams) error
for _, ps := range *probeStates {
// skip if found info from host
foundHost := slices.Index(found, ps.Host)
if !ps.State || foundHost >= 0{
if !ps.State || foundHost >= 0 {
continue
}
chanProbeState <- ps
@ -394,11 +395,11 @@ func QueryBios(client *bmclib.Client, l *Logger, q *QueryParams) ([]byte, error)
func QueryEthernetInterfaces(client *bmclib.Client, l *Logger, q *QueryParams) ([]byte, error) {
config := gofish.ClientConfig{
Endpoint: fmt.Sprintf("https://%s:%d", q.Host, q.Port),
Username: q.User,
Password: q.Pass,
Insecure: !q.WithSecureTLS,
TLSHandshakeTimeout: q.Timeout,
Endpoint: fmt.Sprintf("https://%s:%d", q.Host, q.Port),
Username: q.User,
Password: q.Pass,
Insecure: !q.WithSecureTLS,
TLSHandshakeTimeout: q.Timeout,
}
c, err := gofish.Connect(config)
if err != nil {
@ -418,12 +419,12 @@ func QueryEthernetInterfaces(client *bmclib.Client, l *Logger, q *QueryParams) (
}
func QueryChassis(q *QueryParams) ([]byte, error) {
config := gofish.ClientConfig {
Endpoint: fmt.Sprintf("https://%s:%d", q.Host, q.Port),
Username: q.User,
Password: q.Pass,
Insecure: !q.WithSecureTLS,
TLSHandshakeTimeout: q.Timeout,
config := gofish.ClientConfig{
Endpoint: fmt.Sprintf("https://%s:%d", q.Host, q.Port),
Username: q.User,
Password: q.Pass,
Insecure: !q.WithSecureTLS,
TLSHandshakeTimeout: q.Timeout,
}
c, err := gofish.Connect(config)
if err != nil {

View file

@ -3,7 +3,7 @@ package sqlite
import (
"fmt"
magellan "davidallendj/magellan/internal"
magellan "github.com/bikeshack/magellan/internal"
"github.com/jmoiron/sqlx"
)

View file

@ -1,8 +1,7 @@
package main
import (
"davidallendj/magellan/cmd"
// smd "github.com/alexlovelltroy/hms-smd/pkg/redfish"
"github.com/bikeshack/magellan/cmd"
)
func main() {