Skip to content

WIP - Feature/v2 initial modules rest client #11

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

Merged
merged 26 commits into from
Mar 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b0381d9
move existing example into v1 folder and introducing v2 for the new i…
iButcat Mar 9, 2025
352d2ea
follow go structure with pkg, adding payloads, config, services with …
iButcat Mar 9, 2025
05f6c85
introduce testing & uuid.
iButcat Mar 9, 2025
beea62c
add internal for shared component across version that are not necessa…
iButcat Mar 9, 2025
e5c7ab8
add v2 with generic client and xo client for the rest api.
iButcat Mar 9, 2025
d41d2c1
add go-version when using goenv.
iButcat Mar 9, 2025
abd9216
remove go.mod & go.sum, we can compile and run from the root director…
iButcat Mar 11, 2025
71d3f0a
remove value of fallback and instead return an error when the necessa…
iButcat Mar 11, 2025
81e848e
config returns an error if the necessary env aren't available.
iButcat Mar 11, 2025
dfd7c0e
docs for the v2 including example about how to add new service logic,…
iButcat Mar 11, 2025
7814ab3
Remove docs and add them in docs directory instead.
iButcat Mar 11, 2025
49edad2
remove comments and add them in docs instead.
iButcat Mar 11, 2025
7867df9
Add more context for the project, also add the docs directory, how to…
iButcat Mar 11, 2025
e26aa04
fix tests for new added method. Comments out Create, fix later since …
iButcat Mar 11, 2025
c7e3a6f
Add makefile tests, run examples and other good to have for generatin…
iButcat Mar 11, 2025
fb8a842
Add package for go env var, easier for development purpose since it l…
iButcat Mar 11, 2025
48240fb
add path builder instead of concatenate. Can be used in service to bu…
iButcat Mar 11, 2025
44f5164
Add const for rest v0 path and import it in client.
iButcat Mar 11, 2025
361dafc
uses the new path builder.
iButcat Mar 11, 2025
84139e4
fix bad markdown formatting.
iButcat Mar 11, 2025
9d7e3ea
Fix documentation from Cyrille suggestion.
iButcat Mar 15, 2025
a7a091e
upgrade go version following the upgrade of the go.mod to fix the lin…
iButcat Mar 15, 2025
d6d6fcf
fix linter and docs.
iButcat Mar 15, 2025
e923222
tidy to add the dependency in direct instead of undirect.
iButcat Mar 17, 2025
5112df8
fix linter issue, also remove hardcoded vm name in the task polling, …
iButcat Mar 17, 2025
6998431
fix 404 version not found for pipeline.
iButcat Mar 17, 2025
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
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ jobs:
uses: actions/setup-go@v5
with:
# The versions of golangci-lint and setup-go here cross-depend and need to update together.
go-version: '1.23'
go-version: '1.24'
# Either this action or golangci-lint needs to disable the cache
cache: false
- run: go mod tidy
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.63.2
version: v1.64.7
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ dist/
.env
.envrc
.autoenv.zsh

# goenv version file
.go-version
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ linters-settings:
- structtag
run:
timeout: 20m
go: '1.24'
126 changes: 75 additions & 51 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,68 +1,92 @@
SHELL := /bin/bash
PROJECT_NAME := xenorchestra-go-sdk
GO := go
GOFLAGS :=
MOCKGEN_VERSION := 1.6.0

.DEFAULT_GOAL := all
.PHONY: all
all: ## build pipeline
all: mod gen spell lint test

.PHONY: precommit
precommit: ## validate the branch before commit
precommit: all vuln
# Colors
BLUE := \033[0;34m
GREEN := \033[0;32m
YELLOW := \033[0;33m
RED := \033[0;31m
NC := \033[0m # No Color

.PHONY: ci
ci: ## CI build pipeline
ci: precommit diff
.PHONY: all
all: mod test lint

.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
@echo "$(BLUE)Makefile for $(PROJECT_NAME)$(NC)"
@echo ""
@echo "$(YELLOW)Usage:$(NC)"
@echo " make $(GREEN)<target>$(NC)"
@echo ""
@echo "$(YELLOW)Targets:$(NC)"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " $(GREEN)%-15s$(NC) %s\n", $$1, $$2}'

.PHONY: mod
mod: ## go mod tidy
$(call print-target)
go mod tidy
mod:
@echo "$(BLUE)Running go mod tidy...$(NC)"
$(GO) mod tidy

.PHONY: test
test:
@echo "$(BLUE)Running tests...$(NC)"
$(GO) test -race -covermode=atomic -coverprofile=coverage.out ./...
$(GO) tool cover -html=coverage.out -o coverage.html
@echo "$(GREEN)Coverage report generated at coverage.html$(NC)"

.PHONY: gen
gen: ## go generate
$(call print-target)
go generate ./...
.PHONY: test-v1
test-v1:
@echo "$(BLUE)Running v1 client tests...$(NC)"
$(GO) test -race ./client/...

.PHONY: spell
spell: ## misspell
$(call print-target)
misspell -error -locale=US -w **.md
.PHONY: test-v2
test-v2:
@echo "$(BLUE)Running v2 client tests...$(NC)"
$(GO) test -race ./v2/... ./pkg/... ./internal/...

.PHONY: lint
lint: ## golangci-lint
$(call print-target)
lint:
@echo "$(BLUE)Running linter...$(NC)"
golangci-lint run

.PHONY: vuln
vuln: ## govulncheck
$(call print-target)
govulncheck ./...
.PHONY: install-mockgen
install-mockgen:
@echo "$(BLUE)Installing mockgen v$(MOCKGEN_VERSION)...$(NC)"
$(GO) install github.com/golang/mock/mockgen@v$(MOCKGEN_VERSION)

.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: mock
mock: install-mockgen
@echo "$(BLUE)Generating mocks...$(NC)"
$(GO) generate ./...

.PHONY: run-example-v1
run-example-v1:
@echo "$(BLUE)Running v1 example...$(NC)"
$(GO) run ./examples/v1/user_demo.go

.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
.PHONY: run-example-v2
run-example-v2:
@echo "$(BLUE)Running v2 example...$(NC)"
$(GO) run ./examples/v2/user_demo.go

.PHONY: run-examples
run-examples: run-example-v1 run-example-v2
@echo "$(GREEN)All examples executed successfully$(NC)"

.PHONY: clean
clean:
@echo "$(BLUE)Cleaning build artifacts...$(NC)"
rm -f coverage.out coverage.html
$(GO) clean -cache -testcache

define print-target
@printf "Executing target: \033[36m$@\033[0m\n"
endef
.PHONY: vuln
vuln:
@echo "$(BLUE)Checking for vulnerabilities...$(NC)"
govulncheck ./...

.PHONY: precommit
precommit:
@echo "$(BLUE)Running pre-commit checks...$(NC)"
pre-commit run --all-files
@echo "$(GREEN)Pre-commit checks passed!$(NC)"
50 changes: 46 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,68 @@
# <p align="center">Golang client for XenOrchestra API</p>

This is a Golang module for the [XenOrchestra](https://github.com/vatesfr/xen-orchestra) JSON-RPC API.
This is a Golang module for the [XenOrchestra](https://github.com/vatesfr/xen-orchestra) API. It provides two client implementations:

It is used in the [terraform-provider-xenorchestra](https://github.com/vatesfr/terraform-provider-xenorchestra) Terraform provider.
- **v1**: Uses the JSON-RPC API (legacy)
- **v2**: Uses the REST API (WIP, should be used in parallel with v1 for missing endpoints, until v2 is fully released)

## 📚 Documentation

TODO
### v1 Documentation

The v1 client uses the JSON-RPC API and is primarily used in the [terraform-provider-xenorchestra](https://github.com/vatesfr/terraform-provider-xenorchestra) Terraform provider.

### v2 Documentation

The v2 client uses the REST API and provides a more modern, type-safe interface. Comprehensive documentation is available in the `docs/v2` directory:

- [Overview](docs/v2/01-overview.md) - Introduction and key features
- [Architecture](docs/v2/02-architecture.md) - Design patterns and components
- [Migration Guide](docs/v2/03-migration-guide.md) - How to migrate from v1 to v2
- [Service Implementation Guide](docs/v2/04-service-implementation.md) - How to add new services

## 🧑🏻‍💻 Usage

```shell
go get github.com/vatesfr/xenorchestra-go-sdk
```

See [examples](https://github.com/vatesfr/xenorchestra-go-sdk/tree/main/examples).
### Examples

The SDK includes examples for both v1 and v2 clients:

- [v1 Examples](examples/v1) - Examples using the JSON-RPC API
- [v2 Examples](examples/v2) - Examples using the REST API

## 🍰 Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.

### Development

This project includes a Makefile to help with common development tasks:

```shell
# Run tests
make test

# Run specific client tests
make test-v1
make test-v2

# Run linter
make lint

# Generate mocks
make mock

# Run examples
make example-v1
make example-v2

# See all available commands
make help
```

## License

MIT License
85 changes: 85 additions & 0 deletions docs/v2/01-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Xen Orchestra Go SDK v2

## Overview

The Xen Orchestra Go SDK v2 provides a modern, type-safe interface to interact with the Xen Orchestra API. This version moves from the JSON-RPC API used in v1 to a REST API implementation, offering significant improvements in usability, maintainability, and type safety.

## Key Features

- **REST API Support**: Uses Xen Orchestra's modern REST API
- **Type Safety**: Leverages Go generics for type-safe API interactions
- **Method Chaining**: Improved API ergonomics with `client.VM().Create()` pattern
- **Context Support**: All operations support context for better timeout and cancellation handling
- **UUID Support**: Native UUID type support instead of string IDs
- **Structured Logging**: Built-in logging with configurable verbosity levels
- **Interface-Based Design**: Clean interfaces for better testability and mocking
- **Go Mocking**: Mocking is supported for all interfaces by adding the `//go:generate mockgen` tag in the interface file

## Installation

```bash
go get github.com/vatesfr/xenorchestra-go-sdk/v2
```

## Quick Start

```go
package main

import (
"context"
"fmt"
"time"

"github.com/vatesfr/xenorchestra-go-sdk/pkg/config"
v2 "github.com/vatesfr/xenorchestra-go-sdk/v2"
)

func main() {
// Create a context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()

// Initialize configuration
cfg, err := config.New()
if err != nil {
panic(err)
}

// Create client
client, err := v2.New(cfg)
if err != nil {
panic(err)
}

// List all VMs
vms, err := client.VM().List(ctx)
if err != nil {
panic(err)
}

// Display VMs
fmt.Printf("Found %d VMs\n", len(vms))
for i, vm := range vms {
fmt.Printf("%d. %s (ID: %s, Power: %s)\n", i+1, vm.NameLabel, vm.ID, vm.PowerState)
}
}
```

## Environment Variables

The SDK uses the following environment variables for configuration:

- `XOA_URL`: URL of the Xen Orchestra server
- `XOA_USER`: Username for authentication
- `XOA_PASSWORD`: Password for authentication
- `XOA_INSECURE`: Set to "true" to skip TLS certificate verification
- `XOA_DEVELOPMENT`: Set to "true" to enable development mode with additional logging
- `XOA_RETRY_MODE`: Retry strategy ("none" or "backoff")
- `XOA_RETRY_MAX_TIME`: Maximum time to wait between retries (default: 5 minutes)

## Next Steps

- [Architecture Guide](02-architecture.md) - Learn about the design patterns used in the SDK
- [Migration Guide](03-migration-guide.md) - Migrate from v1 to v2
- [Service Implementation Guide](04-service-implementation.md) - Learn how to add new services
Loading
Loading