Skip to content
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
20 changes: 18 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,26 @@ jobs:

echo "Running integration tests against Prism mock..."

# Test breeder list
echo "Testing: breeder list"
# Test breeder list with HTTP (default)
echo "Testing: breeder list (HTTP default)"
$BINARY_PATH --hostname=localhost --port=4010 breeder list

# Test explicit HTTP prefix
echo "Testing: breeder list (explicit http:// prefix)"
$BINARY_PATH --hostname=http://localhost --port=4010 breeder list

# Test HTTPS prefix with insecure flag (using HTTP port for testing)
echo "Testing: breeder list (HTTPS prefix with --insecure flag)"
$BINARY_PATH --hostname=https://localhost --port=4010 --insecure breeder list || echo "Expected: HTTPS on HTTP port may fail"

# Test HTTPS prefix without insecure flag (should fail on missing certificates)
echo "Testing: breeder list (HTTPS prefix without --insecure flag - should fail)"
$BINARY_PATH --hostname=https://localhost --port=4010 breeder list && echo "❌ Unexpected success - should have failed without certificates" || echo "✅ Expected failure without SSL certificates"

# Test help command shows new --insecure flag
echo "Testing: help shows --insecure flag"
$BINARY_PATH --help | grep -q "insecure" && echo "✅ --insecure flag documented in help" || echo "❌ --insecure flag missing from help"

# Create test YAML files using echo
echo 'name: "Test Breeder"' > test_breeder.yml
echo 'config: >' >> test_breeder.yml
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ godon_cli breeder list
godon_cli --hostname api.example.com --port 9090 breeder list
```

### Configuration Options

```bash
# Connect to a different API server
godon_cli --hostname api.example.com --port 9090 breeder list

# Use HTTPS with SSL verification
godon_cli --hostname https://api.example.com --port 443 breeder list

# Use HTTPS but skip SSL verification (for development/testing)
godon_cli --hostname https://localhost:8443 --insecure breeder list
```

### Breeder Management

#### Create a Breeder
Expand Down Expand Up @@ -116,7 +129,13 @@ The CLI connects to the Godon API using these default settings:
You can override these using command-line flags:

```bash
# Basic configuration
godon_cli --hostname api.example.com --port 9090 --api-version v1 breeder list

# Protocol and SSL options
godon_cli --hostname http://api.example.com --port 80 breeder list # HTTP (explicit)
godon_cli --hostname https://api.example.com --port 443 breeder list # HTTPS (secure)
godon_cli --hostname https://localhost --port 8443 --insecure breeder list # HTTPS (insecure)
```

## API Specification
Expand Down
35 changes: 30 additions & 5 deletions src/godon/client.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## Godon HTTP Client
## Core HTTP client for Godon API

import std/[httpclient, json, uri, strutils]
import std/[httpclient, json, uri, strutils, net]
import types

const
Expand All @@ -13,23 +13,48 @@ type
GodonClient* = ref object
config*: ApiConfig
httpClient*: HttpClient
insecure*: bool

proc newGodonClient*(hostname: string = DefaultHostname,
port: int = DefaultPort,
apiVersion: string = DefaultApiVersion): GodonClient =
apiVersion: string = DefaultApiVersion,
insecure: bool = false): GodonClient =
## Create a new Godon API client
let config = ApiConfig(
hostname: hostname,
port: port,
apiVersion: apiVersion
)

let httpClient = newHttpClient()
GodonClient(config: config, httpClient: httpClient)
# Configure HTTP client with SSL verification settings
var httpClient: HttpClient
if insecure:
# Create insecure SSL context that skips certificate verification
let sslContext = newContext(verifyMode = CVerifyNone)
httpClient = newHttpClient(sslContext = sslContext)
else:
httpClient = newHttpClient()

GodonClient(config: config, httpClient: httpClient, insecure: insecure)

proc baseUrl*(client: GodonClient): string =
## Get the base URL for API requests
result = "http://" & client.config.hostname & ":" & $client.config.port
## Auto-detect protocol if hostname includes https:// or http:// prefix
let scheme = if client.config.hostname.startsWith("https://"):
"https"
elif client.config.hostname.startsWith("http://"):
"http"
else:
"http" # default to HTTP

# Strip protocol prefix from hostname if present
let cleanHost = if client.config.hostname.startsWith("https://") or
client.config.hostname.startsWith("http://"):
client.config.hostname.split("://", 1)[1]
else:
client.config.hostname

result = scheme & "://" & cleanHost & ":" & $client.config.port

proc handleResponse*[T](client: GodonClient; response: Response): ApiResponse[T] =
## Handle HTTP response and convert to ApiResponse
Expand Down
12 changes: 8 additions & 4 deletions src/godon_cli.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Global Options:
--hostname, -h <host> Godon hostname (default: localhost)
--port, -p <port> Godon port (default: 8080)
--api-version, -v <ver> API version (default: v0)
--insecure Skip SSL certificate verification (HTTPS only)
--help, -h Show this help message

Examples:
Expand All @@ -31,11 +32,12 @@ proc writeError(message: string) =
stderr.writeLine("Error: " & message)
quit(1)

proc parseArgs(): (string, string, int, string, seq[string]) =
proc parseArgs(): (string, string, int, string, bool, seq[string]) =
var command = ""
var hostname = "localhost"
var port = 8080
var apiVersion = "v0"
var insecure = false
var args: seq[string] = @[]

var p = initOptParser(commandLineParams())
Expand Down Expand Up @@ -67,6 +69,8 @@ proc parseArgs(): (string, string, int, string, seq[string]) =
of "id":
# Reconstruct as argument for subcommand parsing
args.add("--id=" & val)
of "insecure":
insecure = true
of "help", "h":
writeHelp()
quit(0)
Expand All @@ -80,7 +84,7 @@ proc parseArgs(): (string, string, int, string, seq[string]) =
writeHelp()
quit(0)

(command, hostname, port, apiVersion, args)
(command, hostname, port, apiVersion, insecure, args)

proc handleBreederCommand(client: GodonClient, command: string, args: seq[string]) =
let subCommand = if args.len > 0: args[0] else: ""
Expand Down Expand Up @@ -192,9 +196,9 @@ proc handleBreederCommand(client: GodonClient, command: string, args: seq[string
else:
writeError("Unknown breeder command: " & subCommand)

let (command, hostname, port, apiVersion, args) = parseArgs()
let (command, hostname, port, apiVersion, insecure, args) = parseArgs()

let godonClient = newGodonClient(hostname, port, apiVersion)
let godonClient = newGodonClient(hostname, port, apiVersion, insecure)

case command:
of "breeder":
Expand Down