Skip to content
New issue

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

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

Already on GitHub? # to your account

Experimental cmd export #67

Closed
Closed
18 changes: 9 additions & 9 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ builds:
# export GO_VERSION=$(go version | awk '{print $3}')
# export BUILD_USER=$(whoami)
ldflags:
- "-X github.com/OpenCHAMI/magellan/internal/version.GitCommit={{ .Commit }} \
-X github.com/OpenCHAMI/magellan/internal/version.BuildTime={{ .Timestamp }} \
-X github.com/OpenCHAMI/magellan/internal/version.Version={{ .Version }} \
-X github.com/OpenCHAMI/magellan/internal/version.GitBranch={{ .Branch }} \
-X github.com/OpenCHAMI/magellan/internal/version.GitTag={{ .Tag }} \
-X github.com/OpenCHAMI/magellan/internal/version.GitState={{ .Env.GIT_STATE }} \
-X github.com/OpenCHAMI/magellan/internal/version.BuildHost={{ .Env.BUILD_HOST }} \
-X github.com/OpenCHAMI/magellan/internal/version.GoVersion={{ .Env.GO_VERSION }} \
-X github.com/OpenCHAMI/magellan/internal/version.BuildUser={{ .Env.BUILD_USER }} "
- "-X github.com/davidallendj/magellan/internal/version.GitCommit={{ .Commit }} \
-X github.com/davidallendj/magellan/internal/version.BuildTime={{ .Timestamp }} \
-X github.com/davidallendj/magellan/internal/version.Version={{ .Version }} \
-X github.com/davidallendj/magellan/internal/version.GitBranch={{ .Branch }} \
-X github.com/davidallendj/magellan/internal/version.GitTag={{ .Tag }} \
-X github.com/davidallendj/magellan/internal/version.GitState={{ .Env.GIT_STATE }} \
-X github.com/davidallendj/magellan/internal/version.BuildHost={{ .Env.BUILD_HOST }} \
-X github.com/davidallendj/magellan/internal/version.GoVersion={{ .Env.GO_VERSION }} \
-X github.com/davidallendj/magellan/internal/version.BuildUser={{ .Env.BUILD_USER }} "
tags:
- version
goos:
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ Tidied up CLI flag names

* Ability to update firmware
* Refactored connection handling for faster scanning
* Updated to reflect home at github.com/OpenCHAMI
* Updated to reflect home at github.com/davidallendj
* Updated to reflect ghcr.io as container home

## [Unreleased]
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ diff: ## git diff
.PHONY: docs
docs: ## go docs
$(call print-target)
go doc github.com/OpenCHAMI/magellan/cmd
go doc github.com/OpenCHAMI/magellan/internal
go doc github.com/OpenCHAMI/magellan/pkg/crawler
go doc github.com/davidallendj/magellan/cmd
go doc github.com/davidallendj/magellan/internal
go doc github.com/davidallendj/magellan/pkg/crawler

.PHONY: emulator
emulator:
Expand Down
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# OpenCHAMI Magellan
# Magellan

The `magellan` CLI tool is a Redfish-based, board management controller (BMC) discovery tool designed to scan networks and is written in Go. The tool collects information from BMC nodes using the provided Redfish RESTful API with [`gofish`](https://github.com/stmcginnis/gofish) and loads the queried data into an [SMD](https://github.com/OpenCHAMI/smd/tree/master) instance. The tool strives to be more flexible by implementing multiple methods of discovery to work for a wider range of systems (WIP) and is capable of using independently of other tools or services.
The `magellan` CLI tool is a Redfish-based, board management controller (BMC) discovery tool designed to scan networks and is written in Go. The tool collects information from BMC nodes using the provided Redfish RESTful API with [`gofish`](https://github.com/stmcginnis/gofish) and loads the queried data into an [SMD](https://github.com/davidallendj/smd/tree/master) instance. The tool strives to be more flexible by implementing multiple methods of discovery to work for a wider range of systems (WIP) and is capable of using independently of other tools or services.

**Note: `magellan` v0.1.0 is incompatible with SMD v2.15.3 and earlier.**

Expand All @@ -25,7 +25,7 @@ See the [TODO](#todo) section for a list of soon-ish goals planned.
The `magellan` tool can be built to run on bare metal. Install the required Go tools, clone the repo, and then build the binary in the root directory with the following:

```bash
git clone https://github.com/OpenCHAMI/magellan
git clone https://github.com/davidallendj/magellan
cd magellan
go mod tidy && go build
```
Expand Down Expand Up @@ -58,10 +58,10 @@ This might take some time to complete initially because of the `go-sqlite3` driv

### Docker

The tool can also run using Docker. To build the Docker container, run `docker build -t magellan:testing .` in the project's directory. This is useful if you to run `magellan` on a different system through Docker desktop without having to install and build with Go (or if you can't do so for some reason). [Prebuilt images](https://github.com/OpenCHAMI/magellan/pkgs/container/magellan) are available as well on `ghcr`. Images can be pulled directly from the repository:
The tool can also run using Docker. To build the Docker container, run `docker build -t magellan:testing .` in the project's directory. This is useful if you to run `magellan` on a different system through Docker desktop without having to install and build with Go (or if you can't do so for some reason). [Prebuilt images](https://github.com/davidallendj/magellan/pkgs/container/magellan) are available as well on `ghcr`. Images can be pulled directly from the repository:

```bash
docker pull ghcr.io/openchami/magellan:latest
docker pull ghcr.io/davidallendj/magellan:latest
```

See the ["Running with Docker"](#running-with-docker) section below about running with the Docker container.
Expand Down Expand Up @@ -195,7 +195,7 @@ watch -n 1 "./magellan update 172.16.0.110 --status --username $USERNAME --passw

### Getting an Access Token (WIP)

The `magellan` tool has a `login` subcommand that works with the [`opaal`](https://github.com/OpenCHAMI/opaal) service to obtain a token needed to access the SMD service. If the SMD instance requires authentication, set the `ACCESS_TOKEN` environment variable to have `magellan` include it in the header for HTTP requests to SMD.
The `magellan` tool has a `login` subcommand that works with the [`opaal`](https://github.com/davidallendj/opaal) service to obtain a token needed to access the SMD service. If the SMD instance requires authentication, set the `ACCESS_TOKEN` environment variable to have `magellan` include it in the header for HTTP requests to SMD.

```bash
# must have a running OPAAL instance
Expand All @@ -205,7 +205,7 @@ The `magellan` tool has a `login` subcommand that works with the [`opaal`](https
export ACCESS_TOKEN=eyJhbGciOiJIUzI1NiIs...
```

Alternatively, if you are running the OpenCHAMI quickstart in the [deployment recipes](https://github.com/OpenCHAMI/deployment-recipes), you can run the provided script to generate a token and set the environment variable that way.
Alternatively, if you are running the OpenCHAMI quickstart in the [deployment recipes](https://github.com/davidallendj/deployment-recipes), you can run the provided script to generate a token and set the environment variable that way.

```bash
quickstart_dir=path/to/deployment/recipes/quickstart
Expand All @@ -218,8 +218,7 @@ export ACCESS_TOKEN=$(gen_access_token)
The `magellan` tool can be ran in a Docker container after pulling the latest image:

```bash
docker pull ghcr.io/openchami/magellan:latest

docker pull ghcr.io/davidallendj/magellan:latest
```

Then, run either with the helper script found in `bin/magellan.sh` or the binary in the container:
Expand Down Expand Up @@ -250,7 +249,7 @@ In summary, `magellan` needs at minimum the following configured to work on each

## TODO

See the [issue list](https://github.com/OpenCHAMI/magellan/issues) for plans for `magellan`. Here is a list of other features left to add, fix, or do (and some ideas!):
See the [issue list](https://github.com/davidallendj/magellan/issues) for plans for `magellan`. Here is a list of other features left to add, fix, or do (and some ideas!):

* [X] Confirm loading different components into SMD
* [X] Add ability to set subnet mask for scanning
Expand Down
96 changes: 96 additions & 0 deletions cmd/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package cmd

import (
"fmt"
"net/url"
"os"
"strconv"

magellan "github.com/davidallendj/magellan/internal"
"github.com/davidallendj/magellan/internal/cache/sqlite"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

var (
withHosts []string
withPorts []int
)

var cacheCmd = &cobra.Command{
Use: "cache",
Short: "Manage found assets in cache.",
Run: func(cmd *cobra.Command, args []string) {
// show the help for cache and exit
if len(args) <= 0 {
cmd.Help()
os.Exit(0)
}
},
}

var cacheRemoveCmd = &cobra.Command{
Use: "remove",
Short: "Remove a host from a scanned cache list.",
Run: func(cmd *cobra.Command, args []string) {
assets := []magellan.RemoteAsset{}

// add all assets directly from positional args
for _, arg := range args {
var (
port int
uri *url.URL
err error
)
uri, err = url.ParseRequestURI(arg)
if err != nil {
log.Error().Err(err).Msg("failed to parse arg")
}

// convert port to its "proper" type
if uri.Port() == "" {
uri.Host += ":443"
}
port, err = strconv.Atoi(uri.Port())
if err != nil {
log.Error().Err(err).Msg("failed to convert port to integer type")
}
asset := magellan.RemoteAsset{
Host: fmt.Sprintf("%s://%s", uri.Scheme, uri.Hostname()),
Port: port,
}
assets = append(assets, asset)
}

// Add all assets with specified hosts (same host different different ports)
// This should produce the following SQL:
// DELETE FROM magellan_scanned_assets WHERE host=:host
for _, host := range withHosts {
assets = append(assets, magellan.RemoteAsset{
Host: host,
Port: -1,
})
}
// Add all assets with specified ports (same port different hosts)
// This should produce the following SQL:
// DELETE FROM magellan_scanned_assets WHERE port=:port
for _, port := range withPorts {
assets = append(assets, magellan.RemoteAsset{
Host: "",
Port: port,
})
}
if len(assets) <= 0 {
log.Error().Msg("nothing to do")
os.Exit(1)
}
sqlite.DeleteScannedAssets(cachePath, assets...)
},
}

func init() {
cacheRemoveCmd.Flags().StringSliceVar(&withHosts, "with-hosts", []string{}, "Remove all assets with specified hosts")
cacheRemoveCmd.Flags().IntSliceVar(&withPorts, "with-ports", []int{}, "Remove all assets with specified ports")
cacheCmd.AddCommand(cacheRemoveCmd)
rootCmd.AddCommand(cacheCmd)
}
48 changes: 24 additions & 24 deletions cmd/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import (
"fmt"
"os/user"

magellan "github.com/OpenCHAMI/magellan/internal"
"github.com/OpenCHAMI/magellan/internal/cache/sqlite"
urlx "github.com/OpenCHAMI/magellan/internal/url"
"github.com/OpenCHAMI/magellan/pkg/auth"
"github.com/cznic/mathutil"
magellan "github.com/davidallendj/magellan/internal"
"github.com/davidallendj/magellan/internal/cache/sqlite"
urlx "github.com/davidallendj/magellan/internal/url"
"github.com/davidallendj/magellan/pkg/auth"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
Expand All @@ -17,7 +17,7 @@ import (
// The `collect` command fetches data from a collection of BMC nodes.
// This command should be ran after the `scan` to find available hosts
// on a subnet.
var collectCmd = &cobra.Command{
var CollectCmd = &cobra.Command{
Use: "collect",
Short: "Collect system information by interrogating BMC node",
Long: "Send request(s) to a collection of hosts running Redfish services found stored from the 'scan' in cache.\n" +
Expand Down Expand Up @@ -75,28 +75,28 @@ var collectCmd = &cobra.Command{

func init() {
currentUser, _ = user.Current()
collectCmd.PersistentFlags().StringVar(&host, "host", "", "Set the URI to the SMD root endpoint")
collectCmd.PersistentFlags().StringVar(&username, "username", "", "Set the BMC user")
collectCmd.PersistentFlags().StringVar(&password, "password", "", "Set the BMC password")
collectCmd.PersistentFlags().StringVar(&scheme, "scheme", "https", "Set the scheme used to query")
collectCmd.PersistentFlags().StringVar(&protocol, "protocol", "tcp", "Set the protocol used to query")
collectCmd.PersistentFlags().StringVarP(&outputPath, "output", "o", fmt.Sprintf("/tmp/%smagellan/inventory/", currentUser.Username+"/"), "Set the path to store collection data")
collectCmd.PersistentFlags().BoolVar(&forceUpdate, "force-update", false, "Set flag to force update data sent to SMD")
collectCmd.PersistentFlags().StringVar(&cacertPath, "cacert", "", "Path to CA cert. (defaults to system CAs)")
CollectCmd.PersistentFlags().StringVar(&host, "host", "", "Set the URI to the SMD root endpoint")
CollectCmd.PersistentFlags().StringVar(&username, "username", "", "Set the BMC user")
CollectCmd.PersistentFlags().StringVar(&password, "password", "", "Set the BMC password")
CollectCmd.PersistentFlags().StringVar(&scheme, "scheme", "https", "Set the scheme used to query")
CollectCmd.PersistentFlags().StringVar(&protocol, "protocol", "tcp", "Set the protocol used to query")
CollectCmd.PersistentFlags().StringVarP(&outputPath, "output", "o", fmt.Sprintf("/tmp/%smagellan/inventory/", currentUser.Username+"/"), "Set the path to store collection data")
CollectCmd.PersistentFlags().BoolVar(&forceUpdate, "force-update", false, "Set flag to force update data sent to SMD")
CollectCmd.PersistentFlags().StringVar(&cacertPath, "cacert", "", "Path to CA cert. (defaults to system CAs)")

// set flags to only be used together
collectCmd.MarkFlagsRequiredTogether("username", "password")
CollectCmd.MarkFlagsRequiredTogether("username", "password")

// bind flags to config properties
checkBindFlagError(viper.BindPFlag("collect.host", collectCmd.Flags().Lookup("host")))
checkBindFlagError(viper.BindPFlag("collect.username", collectCmd.Flags().Lookup("username")))
checkBindFlagError(viper.BindPFlag("collect.password", collectCmd.Flags().Lookup("password")))
checkBindFlagError(viper.BindPFlag("collect.scheme", collectCmd.Flags().Lookup("scheme")))
checkBindFlagError(viper.BindPFlag("collect.protocol", collectCmd.Flags().Lookup("protocol")))
checkBindFlagError(viper.BindPFlag("collect.output", collectCmd.Flags().Lookup("output")))
checkBindFlagError(viper.BindPFlag("collect.force-update", collectCmd.Flags().Lookup("force-update")))
checkBindFlagError(viper.BindPFlag("collect.cacert", collectCmd.Flags().Lookup("cacert")))
checkBindFlagError(viper.BindPFlags(collectCmd.Flags()))
checkBindFlagError(viper.BindPFlag("collect.host", CollectCmd.Flags().Lookup("host")))
checkBindFlagError(viper.BindPFlag("collect.username", CollectCmd.Flags().Lookup("username")))
checkBindFlagError(viper.BindPFlag("collect.password", CollectCmd.Flags().Lookup("password")))
checkBindFlagError(viper.BindPFlag("collect.scheme", CollectCmd.Flags().Lookup("scheme")))
checkBindFlagError(viper.BindPFlag("collect.protocol", CollectCmd.Flags().Lookup("protocol")))
checkBindFlagError(viper.BindPFlag("collect.output", CollectCmd.Flags().Lookup("output")))
checkBindFlagError(viper.BindPFlag("collect.force-update", CollectCmd.Flags().Lookup("force-update")))
checkBindFlagError(viper.BindPFlag("collect.cacert", CollectCmd.Flags().Lookup("cacert")))
checkBindFlagError(viper.BindPFlags(CollectCmd.Flags()))

rootCmd.AddCommand(collectCmd)
rootCmd.AddCommand(CollectCmd)
}
4 changes: 2 additions & 2 deletions cmd/crawl.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"fmt"
"log"

urlx "github.com/OpenCHAMI/magellan/internal/url"
"github.com/OpenCHAMI/magellan/pkg/crawler"
urlx "github.com/davidallendj/magellan/internal/url"
"github.com/davidallendj/magellan/pkg/crawler"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand Down
2 changes: 1 addition & 1 deletion cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"strings"
"time"

"github.com/OpenCHAMI/magellan/internal/cache/sqlite"
"github.com/davidallendj/magellan/internal/cache/sqlite"
"github.com/rs/zerolog/log"

"github.com/spf13/cobra"
Expand Down
4 changes: 2 additions & 2 deletions cmd/#.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"net/http"
"os"

magellan "github.com/OpenCHAMI/magellan/internal"
"github.com/OpenCHAMI/magellan/pkg/auth"
magellan "github.com/davidallendj/magellan/internal"
"github.com/davidallendj/magellan/pkg/auth"
"github.com/lestrrat-go/jwx/jwt"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"os"
"os/user"

magellan "github.com/OpenCHAMI/magellan/internal"
magellan "github.com/davidallendj/magellan/internal"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
Expand Down
Loading
Loading