SideroLabs.Omni.Api 1.0.11

dotnet add package SideroLabs.Omni.Api --version 1.0.11
                    
NuGet\Install-Package SideroLabs.Omni.Api -Version 1.0.11
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SideroLabs.Omni.Api" Version="1.0.11" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SideroLabs.Omni.Api" Version="1.0.11" />
                    
Directory.Packages.props
<PackageReference Include="SideroLabs.Omni.Api" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SideroLabs.Omni.Api --version 1.0.11
                    
#r "nuget: SideroLabs.Omni.Api, 1.0.11"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SideroLabs.Omni.Api@1.0.11
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SideroLabs.Omni.Api&version=1.0.11
                    
Install as a Cake Addin
#tool nuget:?package=SideroLabs.Omni.Api&version=1.0.11
                    
Install as a Cake Tool

SideroLabs Omni API Client

Codacy Badge NuGet NuGet License GitHub repo size GitHub top language GitHub last commit

A .NET gRPC client library for interacting with the SideroLabs Omni Management API.

This client provides strongly-typed C# interfaces for the Omni gRPC services, with built-in PGP-based authentication and enterprise-ready features.

🏗️ Inspired by: This project is inspired by the official SideroLabs Omni client and follows the same patterns and authentication mechanisms.

📋 Proto Definitions: The gRPC service definitions are based on the official .proto files from the Omni project, which are the definitive source for the Omni API specification.

Features

🔐 Authentic gRPC Implementation

  • Native gRPC client - Direct implementation of Omni's actual gRPC services
  • PGP-based authentication - Uses Omni's standard PGP signature authentication (compatible with go-api-signature)
  • Streaming support - Real-time log streaming and manifest synchronization
  • Type-safe operations - Generated from official Omni proto definitions

🛠️ Omni ManagementService Operations

Based on the actual management.proto from the Omni project:

Configuration Management:

  • GetKubeConfigAsync() - Retrieve kubeconfig for clusters
  • GetTalosConfigAsync() - Retrieve talosconfig for Talos clusters
  • GetOmniConfigAsync() - Retrieve omnictl client configuration

Service Account Management:

  • CreateServiceAccountAsync() - Create new service accounts
  • RenewServiceAccountAsync() - Renew service account credentials
  • ListServiceAccountsAsync() - List all service accounts
  • DestroyServiceAccountAsync() - Delete service accounts

Operational Tasks:

  • StreamMachineLogsAsync() - Stream logs from machines in real-time
  • ValidateConfigAsync() - Validate configuration files
  • KubernetesUpgradePreChecksAsync() - Check if K8s upgrade is safe
  • StreamKubernetesSyncManifestsAsync() - Sync Kubernetes manifests
  • CreateSchematicAsync() - Create schematics for machine provisioning

🛡️ Enterprise Features

  • Read-only mode - Prevent accidental destructive operations
  • Comprehensive logging - Structured logging with Microsoft.Extensions.Logging
  • Proper error handling - gRPC status codes and meaningful error messages
  • Timeout management - Configurable request timeouts
  • Connection pooling - Efficient gRPC channel management

Quick Start

Installation

dotnet add package SideroLabs.Omni.Api

Basic Usage

using SideroLabs.Omni.Api;

// Configure the client
var options = new OmniClientOptions
{
    Endpoint = "https://your-omni-instance.com",
    Identity = "your-username",
    PgpPrivateKey = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n...",
    UseTls = true,
    ValidateCertificate = true
};

// Create the client
using var client = new OmniClient(options);

// Get kubeconfig for a cluster
var kubeconfig = await client.Management.GetKubeConfigAsync(
    serviceAccount: true,
    serviceAccountTtl: TimeSpan.FromHours(24),
    cancellationToken: cancellationToken);

// List service accounts
var serviceAccounts = await client.Management.ListServiceAccountsAsync(cancellationToken);

// Stream machine logs
await foreach (var logEntry in client.Management.StreamMachineLogsAsync(
    "machine-id", 
    follow: true, 
    tailLines: 100, 
    cancellationToken))
{
    Console.WriteLine(Encoding.UTF8.GetString(logEntry));
}

Authentication Setup

The client uses PGP-based authentication as required by Omni, implementing the same signature mechanism as the official Go client:

var options = new OmniClientOptions
{
    Endpoint = "https://omni.example.com",
    Identity = "your-omni-username",
    PgpPrivateKey = File.ReadAllText("path/to/private-key.asc"),
    Logger = logger
};

Or load from a base64-encoded key file (compatible with Omni's key format):

var options = new OmniClientOptions
{
    Endpoint = "https://omni.example.com",
    PgpKeyFilePath = "path/to/key-file.json" // Contains base64-encoded JSON
};

Read-Only Mode

Enable read-only mode for safe production use:

var options = new OmniClientOptions
{
    Endpoint = "https://omni.example.com",
    Identity = "readonly-user", 
    PgpPrivateKey = "...",
    IsReadOnly = true // Prevents destructive operations
};

Advanced Usage

Service Account Management

// Create a service account
var publicKeyId = await client.Management.CreateServiceAccountAsync(
    armoredPgpPublicKey: pgpPublicKey,
    useUserRole: true,
    cancellationToken: cancellationToken);

// Renew service account
await client.Management.RenewServiceAccountAsync(
    name: "service-account-name",
    armoredPgpPublicKey: newPgpPublicKey,
    cancellationToken: cancellationToken);

Kubernetes Operations

// Check if Kubernetes upgrade is safe
var (canUpgrade, reason) = await client.Management.KubernetesUpgradePreChecksAsync(
    newVersion: "v1.29.0",
    cancellationToken: cancellationToken);

// Sync Kubernetes manifests
await foreach (var syncResult in client.Management.StreamKubernetesSyncManifestsAsync(
    dryRun: true,
    cancellationToken: cancellationToken))
{
    Console.WriteLine($"Synced: {syncResult.Path}");
}

Machine Provisioning

// Create a schematic for machine provisioning
var (schematicId, pxeUrl) = await client.Management.CreateSchematicAsync(
    extensions: new[] { "siderolabs/iscsi-tools", "siderolabs/util-linux-tools" },
    extraKernelArgs: new[] { "console=ttyS0" },
    metaValues: new Dictionary<uint, string> { { 0x0a, "rack-1" } },
    cancellationToken: cancellationToken);

Configuration

OmniClientOptions

Property Description Default
Endpoint Omni gRPC endpoint URL Required
Identity Username for PGP authentication Required
PgpPrivateKey PGP private key (armored format) Optional
PgpKeyFilePath Path to PGP key file Optional
TimeoutSeconds Request timeout in seconds 30
UseTls Enable TLS encryption true
ValidateCertificate Validate server certificates true
IsReadOnly Enable read-only mode false
Logger Microsoft.Extensions.Logging logger NullLogger

Dependency Injection

services.AddOmniClient(options =>
{
    options.Endpoint = "https://omni.example.com";
    options.Identity = "api-user";
    options.PgpPrivateKey = Environment.GetEnvironmentVariable("OMNI_PGP_KEY");
});

// Inject and use
public class MyService
{
    private readonly IOmniClient _omniClient;

    public MyService(IOmniClient omniClient)
    {
        _omniClient = omniClient;
    }

    public async Task<string> GetKubeConfigAsync()
    {
        return await _omniClient.Management.GetKubeConfigAsync();
    }
}

Architecture

This client is built around the actual Omni gRPC services as defined in the official Omni proto files:

OmniClient
└── Management (IManagementService)
    ├── Configuration Operations (kubeconfig, talosconfig, omniconfig)
    ├── Service Account Management (create, renew, list, destroy)
    ├── Machine Operations (logs streaming)
    ├── Kubernetes Operations (upgrade checks, manifest sync)
    └── Provisioning (schematic creation)

Note: This client implements only the gRPC services that Omni actually provides. It does not include cluster CRUD operations, as these are handled through different mechanisms in the Omni architecture.

Compatibility

This .NET client is designed to be fully compatible with:

  • Official Omni instances - Works with any Omni deployment
  • Authentication system - Uses the same PGP signature mechanism as the Go client
  • gRPC protocol - Based on the same .proto definitions
  • API versioning - Stays in sync with Omni's API evolution

Requirements

  • .NET 9.0 or later
  • gRPC support (included)
  • Valid Omni instance with gRPC endpoint
  • PGP key pair for authentication

Error Handling

The client provides comprehensive error handling:

try
{
    var result = await client.Management.GetKubeConfigAsync();
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.Unauthenticated)
{
    // Handle authentication errors
    logger.LogError("Authentication failed: {Message}", ex.Message);
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.PermissionDenied)
{
    // Handle authorization errors
    logger.LogError("Permission denied: {Message}", ex.Message);
}
catch (ReadOnlyModeException ex)
{
    // Handle read-only mode violations
    logger.LogWarning("Operation blocked in read-only mode: {Operation}", ex.Operation);
}

Development & Publishing

Building and Testing

# Build the solution
dotnet build

# Run unit tests
dotnet test

# Create NuGet package
dotnet pack --configuration Release

Automated Release Process

The project includes an automated release script that handles version management, testing, tagging, NuGet publishing with symbols, and GitHub release creation:

# Using PowerShell
.\Release.ps1

# Common options
.\Release.ps1 -Force              # Force release with uncommitted changes
.\Release.ps1 -SkipTests          # Skip unit tests (not recommended)
.\Release.ps1 -Publish            # Automatically publish to NuGet with symbols
.\Release.ps1 -Publish -SkipSymbols        # Publish without symbols
.\Release.ps1 -CreateGitHubRelease         # Create GitHub release with changelog
.\Release.ps1 -Publish -CreateGitHubRelease # Full release pipeline

Setup for NuGet Publishing:

  1. Get your API key from nuget.org/account/apikeys
  2. Create a file named nuget_key.txt in the solution root
  3. Add your API key to the file (first line only)
  4. Run .\Release.ps1 - it will prompt whether to publish if tests pass

Setup for GitHub Releases:

  1. Install GitHub CLI: winget install GitHub.cli or visit cli.github.com
  2. Authenticate: gh auth login
  3. Run .\Release.ps1 -CreateGitHubRelease to create releases with automated changelogs

The Release.ps1 script will:

  • ✅ Validate prerequisites and git repository status
  • ✅ Get version using NerdBank GitVersioning (nbgv)
  • ✅ Restore NuGet packages
  • ✅ Build solution in Release mode
  • ✅ Run unit tests (unless -SkipTests is specified)
  • ✅ Create Git tag with current version
  • ✅ Push tag to origin
  • ✅ Optionally pack and publish NuGet package with symbols
  • ✅ Generate changelog from git commits since last release
  • ✅ Create GitHub release with automated release notes
  • ✅ Provide next steps for manual tasks

Version Management: The script uses NerdBank GitVersioning to automatically determine the version. It will:

  • Try to use global nbgv tool
  • Fall back to local nbgv tool
  • Attempt to install nbgv if not found
  • Use fallback versioning from version.json if nbgv is unavailable

Example Usage:

# Standard release process with symbols and GitHub release
.\Release.ps1 -CreateGitHubRelease

# Full automated release pipeline
.\Release.ps1 -Publish -CreateGitHubRelease

# Emergency release (skip tests and force with uncommitted changes)
.\Release.ps1 -Force -SkipTests -Publish

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

Development Guidelines:

  • Follow the patterns established in the official Omni client
  • Keep the .proto definitions in sync with the upstream source
  • Maintain compatibility with the official authentication mechanisms

License

MIT License - see LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.11 160 9/19/2025
1.0.10 157 9/19/2025
1.0.9 165 9/19/2025
1.0.8 162 9/19/2025
1.0.7 161 9/19/2025
0.1.4-alpha 117 9/5/2025

Client implementation for SideroLabs Omni Management API via gRPC