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

Rename & reorg #175

Merged
merged 8 commits into from
Feb 14, 2024
Merged
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
2 changes: 2 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ builds:
- linux
- windows
- darwin
binary: overmind

archives:
- format: tar.gz
# this name template makes the OS and Arch compatible with the results of uname.
name_template: >-
{{ .Binary }}_
{{ .ProjectName }}_
{{- .Version }}_
{{- title .Os }}_
Expand Down
62 changes: 23 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,31 @@
# ovm-cli
# Overmind CLI

CLI to interact with the overmind API
CLI to interact with the Overmind API

```
Usage:
ovm-cli [command]

Available Commands:
completion Generate the autocompletion script for the specified shell
create-bookmark Creates a bookmark from JSON.
create-invite Create a new invite
end-change Finishes the specified change. Call this just after you finished the change. This will store a snapshot of the current system state for later reference.
get-affected-bookmarks Calculates the bookmarks that would be overlapping with a snapshot.
get-bookmark Displays the contents of a bookmark.
get-change Displays the contents of a change.
get-snapshot Displays the contents of a snapshot.
help Help about any command
list-changes Displays the contents of a change.
list-invites List all invites
manual-change Creates a new Change from a given query
request Runs a request against the overmind API
revoke-invites Revoke an existing invite
start-change Starts the specified change. Call this just before you're about to start the change. This will store a snapshot of the current system state for later reference.
submit-plan Creates a new Change from a given terraform plan file
overmind [command]

Infrastructure as Code:
terraform Run Terrafrom with Overmind's change tracking - COMING SOON

Overmind API:
bookmarks Interact with the bookarks that were created in the Explore view
changes Create, update and delete changes in Overmind
invites Manage invites for your team to Overmind
request Runs a request against the overmind API
snapshots Create, view and delete snapshots if your infrastructure

Additional Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command

Flags:
--api-key string The API key to use for authentication, also read from OVM_API_KEY environment variable
--api-key-url string The overmind API Keys endpoint (defaults to --url)
--auth0-client-id string OAuth Client ID to use when connecting with auth (default "j3LylZtIosVPZtouKI8WuVHmE6Lluva1")
--auth0-domain string Auth0 domain to connect to (default "om-prod.eu.auth0.com")
--gateway-url string The overmind Gateway endpoint (defaults to /api/gateway on --url)
-h, --help help for ovm-cli
--honeycomb-api-key string If specified, configures opentelemetry libraries to submit traces to honeycomb. This requires --otel to be set.
--json-log Set to true to emit logs as json for easier parsing.
--log string Set the log level. Valid values: panic, fatal, error, warn, info, debug, trace (default "info")
--otel If specified, configures opentelemetry and - optionally, see --sentry-dsn - sentry using their default environment configs.
--run-mode string Set the run mode for this service, 'release', 'debug' or 'test'. Defaults to 'release'. (default "release")
--sentry-dsn string If specified, configures sentry libraries to capture errors. This requires --otel to be set.
--stdout-trace-dump Dump all otel traces to stdout for debugging. This requires --otel to be set.
--url string The overmind API endpoint (default "https://api.prod.overmind.tech")
-v, --version version for ovm-cli

Use "ovm-cli [command] --help" for more information about a command.
-h, --help help for overmind
--log string Set the log level. Valid values: panic, fatal, error, warn, info, debug, trace (default "info")
-v, --version version for overmind

Use "overmind [command] --help" for more information about a command.
```

## Examples
Expand All @@ -50,7 +34,7 @@ Upload a terraform plan to overmind for Blast Radius Analysis:

```
terraform show -json ./tfplan > ./tfplan.json
ovm-cli submit-plan --title "example change" ./tfplan1.json ./tfplan2.json ./tfplan3.json
overmind changes submit-plan --title "example change" ./tfplan1.json ./tfplan2.json ./tfplan3.json
```

## Terraform ➡ Overmind Mapping
Expand Down
56 changes: 14 additions & 42 deletions cmd/auth_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,89 +16,61 @@ import (
// embedded in the context and otel instrumentation
func AuthenticatedApiKeyClient(ctx context.Context) sdpconnect.ApiKeyServiceClient {
httpClient := NewAuthenticatedClient(ctx, otelhttp.DefaultClient)
url := viper.GetString("api-key-url")
if url == "" {
url = viper.GetString("url")
viper.Set("api-key-url", url)
}
log.WithContext(ctx).WithField("api-key-url", url).Debug("Connecting to overmind apikeys API (pre-authenticated)")
url := viper.GetString("url")
log.WithContext(ctx).WithField("url", url).Debug("Connecting to overmind apikeys API (pre-authenticated)")
return sdpconnect.NewApiKeyServiceClient(httpClient, url)
}

// UnauthenticatedApiKeyClient Returns an apikey client with otel instrumentation
// but no authentication. Can only be used for ExchangeKeyForToken
func UnauthenticatedApiKeyClient(ctx context.Context) sdpconnect.ApiKeyServiceClient {
url := viper.GetString("api-key-url")
if url == "" {
url = viper.GetString("url")
viper.Set("api-key-url", url)
}
log.WithContext(ctx).WithField("api-key-url", url).Debug("Connecting to overmind apikeys API")
url := viper.GetString("url")
log.WithContext(ctx).WithField("url", url).Debug("Connecting to overmind apikeys API")
return sdpconnect.NewApiKeyServiceClient(otelhttp.DefaultClient, url)
}

// AuthenticatedBookmarkClient Returns a bookmark client that uses the auth
// embedded in the context and otel instrumentation
func AuthenticatedBookmarkClient(ctx context.Context) sdpconnect.BookmarksServiceClient {
httpClient := NewAuthenticatedClient(ctx, otelhttp.DefaultClient)
url := viper.GetString("bookmark-url")
if url == "" {
url = viper.GetString("url")
viper.Set("bookmark-url", url)
}
log.WithContext(ctx).WithField("bookmark-url", url).Debug("Connecting to overmind bookmark API")
url := viper.GetString("url")
log.WithContext(ctx).WithField("url", url).Debug("Connecting to overmind bookmark API")
return sdpconnect.NewBookmarksServiceClient(httpClient, url)
}

// AuthenticatedChangesClient Returns a bookmark client that uses the auth
// embedded in the context and otel instrumentation
func AuthenticatedChangesClient(ctx context.Context) sdpconnect.ChangesServiceClient {
httpClient := NewAuthenticatedClient(ctx, otelhttp.DefaultClient)
url := viper.GetString("changes-url")
if url == "" {
url = viper.GetString("url")
viper.Set("changes-url", url)
}
log.WithContext(ctx).WithField("changes-url", url).Debug("Connecting to overmind changes API")
url := viper.GetString("url")
log.WithContext(ctx).WithField("url", url).Debug("Connecting to overmind changes API")
return sdpconnect.NewChangesServiceClient(httpClient, url)
}

// AuthenticatedManagementClient Returns a bookmark client that uses the auth
// embedded in the context and otel instrumentation
func AuthenticatedManagementClient(ctx context.Context) sdpconnect.ManagementServiceClient {
httpClient := NewAuthenticatedClient(ctx, otelhttp.DefaultClient)
url := viper.GetString("management-url")
if url == "" {
url = viper.GetString("url")
viper.Set("management-url", url)
}
log.WithContext(ctx).WithField("management-url", url).Debug("Connecting to overmind management API")
url := viper.GetString("url")
log.WithContext(ctx).WithField("url", url).Debug("Connecting to overmind management API")
return sdpconnect.NewManagementServiceClient(httpClient, url)
}

// AuthenticatedSnapshotsClient Returns a Snapshots client that uses the auth
// embedded in the context and otel instrumentation
func AuthenticatedSnapshotsClient(ctx context.Context) sdpconnect.SnapshotsServiceClient {
httpClient := NewAuthenticatedClient(ctx, otelhttp.DefaultClient)
url := viper.GetString("snapshot-url")
if url == "" {
url = viper.GetString("url")
viper.Set("snapshot-url", url)
}
log.WithContext(ctx).WithField("snapshot-url", url).Debug("Connecting to overmind snapshot API")
url := viper.GetString("url")
log.WithContext(ctx).WithField("url", url).Debug("Connecting to overmind snapshot API")
return sdpconnect.NewSnapshotsServiceClient(httpClient, url)
}

// AuthenticatedInviteClient Returns a Invite client that uses the auth
// embedded in the context and otel instrumentation
func AuthenticatedInviteClient(ctx context.Context) sdpconnect.InviteServiceClient {
httpClient := NewAuthenticatedClient(ctx, otelhttp.DefaultClient)
url := viper.GetString("invite-url")
if url == "" {
url = viper.GetString("url")
viper.Set("invite-url", url)
}
log.WithContext(ctx).WithField("invite-url", url).Debug("Connecting to overmind invite API")
url := viper.GetString("url")
log.WithContext(ctx).WithField("url", url).Debug("Connecting to overmind invite API")
return sdpconnect.NewInviteServiceClient(httpClient, url)
}

Expand Down
36 changes: 36 additions & 0 deletions cmd/bookmarks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
"github.com/spf13/cobra"
)

// bookmarksCmd represents the bookmarks command
var bookmarksCmd = &cobra.Command{
Use: "bookmarks",
GroupID: "api",
Short: "Interact with the bookarks that were created in the Explore view",
Long: `A bookmark in Overmind is a set of queries that are stored together and can be
executed as a single block.`,
Run: func(cmd *cobra.Command, args []string) {
_ = cmd.Help()
},
}

func init() {
rootCmd.AddCommand(bookmarksCmd)

addAPIFlags(bookmarksCmd)

// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// bookmarksCmd.PersistentFlags().String("foo", "", "A help for foo")

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// bookmarksCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
10 changes: 3 additions & 7 deletions cmd/createbookmark.go → cmd/bookmarks_create_bookmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (

"connectrpc.com/connect"
"github.com/google/uuid"
"github.com/overmindtech/ovm-cli/tracing"
"github.com/overmindtech/cli/tracing"
"github.com/overmindtech/sdp-go"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -108,7 +108,7 @@ func CreateBookmark(ctx context.Context, ready chan bool) int {
})
if err != nil {
log.WithContext(ctx).WithError(err).WithFields(log.Fields{
"bookmark-url": viper.GetString("bookmark-url"),
"url": viper.GetString("url"),
}).Error("failed to get bookmark")
return 1
}
Expand Down Expand Up @@ -140,11 +140,7 @@ func CreateBookmark(ctx context.Context, ready chan bool) int {
}

func init() {
rootCmd.AddCommand(createBookmarkCmd)

createBookmarkCmd.PersistentFlags().String("bookmark-url", "", "The bookmark service API endpoint (defaults to --url)")
bookmarksCmd.AddCommand(createBookmarkCmd)

createBookmarkCmd.PersistentFlags().String("file", "", "JSON formatted file to read bookmark. (defaults to stdin)")

createBookmarkCmd.PersistentFlags().String("timeout", "5m", "How long to wait for responses")
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

"connectrpc.com/connect"
"github.com/google/uuid"
"github.com/overmindtech/ovm-cli/tracing"
"github.com/overmindtech/cli/tracing"
"github.com/overmindtech/sdp-go"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -102,7 +102,7 @@ func GetAffectedBookmarks(ctx context.Context, ready chan bool) int {
})
if err != nil {
log.WithContext(ctx).WithError(err).WithFields(log.Fields{
"bookmark-url": viper.GetString("bookmark-url"),
"url": viper.GetString("url"),
}).Error("failed to get affected bookmarks")
return 1
}
Expand All @@ -116,13 +116,8 @@ func GetAffectedBookmarks(ctx context.Context, ready chan bool) int {
}

func init() {
rootCmd.AddCommand(getAffectedBookmarksCmd)

getAffectedBookmarksCmd.PersistentFlags().String("bookmark-url", "", "The bookmark service API endpoint (defaults to --url)")
getAffectedBookmarksCmd.PersistentFlags().String("frontend", "https://app.overmind.tech/", "The frontend base URL")
bookmarksCmd.AddCommand(getAffectedBookmarksCmd)

getAffectedBookmarksCmd.PersistentFlags().String("snapshot-uuid", "", "The UUID of the snapshot that should be checked.")
getAffectedBookmarksCmd.PersistentFlags().String("bookmark-uuids", "", "A comma separated list of UUIDs of the potentially affected bookmarks.")

getAffectedBookmarksCmd.PersistentFlags().String("timeout", "5m", "How long to wait for responses")
}
10 changes: 3 additions & 7 deletions cmd/getbookmark.go → cmd/bookmarks_get_bookmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

"connectrpc.com/connect"
"github.com/google/uuid"
"github.com/overmindtech/ovm-cli/tracing"
"github.com/overmindtech/cli/tracing"
"github.com/overmindtech/sdp-go"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -91,7 +91,7 @@ func GetBookmark(ctx context.Context, ready chan bool) int {
})
if err != nil {
log.WithContext(ctx).WithError(err).WithFields(log.Fields{
"bookmark-url": viper.GetString("bookmark-url"),
"url": viper.GetString("url"),
}).Error("failed to get bookmark")
return 1
}
Expand All @@ -113,11 +113,7 @@ func GetBookmark(ctx context.Context, ready chan bool) int {
}

func init() {
rootCmd.AddCommand(getBookmarkCmd)

getBookmarkCmd.PersistentFlags().String("bookmark-url", "", "The bookmark service API endpoint (defaults to --url)")
bookmarksCmd.AddCommand(getBookmarkCmd)

getBookmarkCmd.PersistentFlags().String("uuid", "", "The UUID of the bookmark that should be displayed.")

getBookmarkCmd.PersistentFlags().String("timeout", "1m", "How long to wait for responses")
}
34 changes: 34 additions & 0 deletions cmd/changes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cmd

import (
"github.com/spf13/cobra"
)

// changesCmd represents the changes command
var changesCmd = &cobra.Command{
Use: "changes",
GroupID: "api",
Short: "Create, update and delete changes in Overmind",
Long: `Manage changes that are being tracked using Overmind. NOTE: It is probably
easier to use our IaC wrappers such as 'overmind terraform plan' rather than
using these commands directly, but they are provided for flexibility.`,
Run: func(cmd *cobra.Command, args []string) {
_ = cmd.Help()
},
}

func init() {
rootCmd.AddCommand(changesCmd)

addAPIFlags(changesCmd)

// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// changesCmd.PersistentFlags().String("foo", "", "A help for foo")

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// changesCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
10 changes: 3 additions & 7 deletions cmd/endchange.go → cmd/changes_end_change.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"time"

"connectrpc.com/connect"
"github.com/overmindtech/ovm-cli/tracing"
"github.com/overmindtech/cli/tracing"
"github.com/overmindtech/sdp-go"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -114,11 +114,7 @@ func EndChange(ctx context.Context, ready chan bool) int {
}

func init() {
rootCmd.AddCommand(endChangeCmd)
changesCmd.AddCommand(endChangeCmd)

withChangeUuidFlags(endChangeCmd)

endChangeCmd.PersistentFlags().String("frontend", "https://app.overmind.tech/", "The frontend base URL")

endChangeCmd.PersistentFlags().String("timeout", "5m", "How long to wait for responses")
addChangeUuidFlags(endChangeCmd)
}
Loading
Loading