up
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/template",
|
||||
"author": "StellaOps",
|
||||
"classifications": ["StellaOps", "Plugin", "Connector"],
|
||||
"identity": "StellaOps.Plugin.Connector",
|
||||
"name": "StellaOps Connector Plugin",
|
||||
"shortName": "stellaops-plugin-connector",
|
||||
"description": "A template for creating StellaOps connector plugins (e.g., VEX, advisory, or feed connectors)",
|
||||
"tags": {
|
||||
"language": "C#",
|
||||
"type": "project"
|
||||
},
|
||||
"sourceName": "MyConnector",
|
||||
"preferNameDirectory": true,
|
||||
"symbols": {
|
||||
"connectorName": {
|
||||
"type": "parameter",
|
||||
"datatype": "text",
|
||||
"description": "The name of the connector (e.g., 'Acme' for AcmeConnector)",
|
||||
"defaultValue": "MyConnector",
|
||||
"replaces": "MyConnector",
|
||||
"fileRename": "MyConnector"
|
||||
},
|
||||
"connectorId": {
|
||||
"type": "parameter",
|
||||
"datatype": "text",
|
||||
"description": "The unique connector identifier (e.g., 'acme-vex')",
|
||||
"defaultValue": "my-connector",
|
||||
"replaces": "my-connector"
|
||||
},
|
||||
"namespace": {
|
||||
"type": "parameter",
|
||||
"datatype": "text",
|
||||
"description": "The root namespace for the plugin",
|
||||
"defaultValue": "StellaOps.Plugin.MyConnector",
|
||||
"replaces": "StellaOps.Plugin.MyConnector"
|
||||
},
|
||||
"pluginVersion": {
|
||||
"type": "parameter",
|
||||
"datatype": "text",
|
||||
"description": "The initial plugin version",
|
||||
"defaultValue": "1.0.0",
|
||||
"replaces": "1.0.0-template"
|
||||
}
|
||||
},
|
||||
"postActions": [
|
||||
{
|
||||
"description": "Restore NuGet packages required by this project",
|
||||
"manualInstructions": [{ "text": "Run 'dotnet restore'" }],
|
||||
"actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
|
||||
"continueOnError": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.DependencyInjection;
|
||||
using StellaOps.DependencyInjection.Validation;
|
||||
|
||||
namespace StellaOps.Plugin.MyConnector;
|
||||
|
||||
/// <summary>
|
||||
/// Registers MyConnector services with the dependency injection container.
|
||||
/// </summary>
|
||||
public sealed class MyConnectorDependencyInjectionRoutine : IDependencyInjectionRoutine
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IServiceCollection Register(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
// Register options with fail-fast validation
|
||||
services.AddOptionsWithValidation<MyConnectorOptions, MyConnectorOptionsValidator>(
|
||||
MyConnectorOptions.SectionName);
|
||||
|
||||
// Register the connector plugin
|
||||
services.AddSingleton<IConnectorPlugin, MyConnectorPlugin>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
105
templates/stellaops-plugin-connector/MyConnector.cs
Normal file
105
templates/stellaops-plugin-connector/MyConnector.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Plugin;
|
||||
|
||||
namespace StellaOps.Plugin.MyConnector;
|
||||
|
||||
/// <summary>
|
||||
/// Connector implementation for MyConnector.
|
||||
/// </summary>
|
||||
public sealed class MyConnector : IFeedConnector
|
||||
{
|
||||
private readonly ILogger<MyConnector> _logger;
|
||||
private readonly MyConnectorOptions _options;
|
||||
|
||||
public MyConnector(ILogger<MyConnector> logger, MyConnectorOptions options)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this connector.
|
||||
/// </summary>
|
||||
public string Id => "my-connector";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display name for this connector.
|
||||
/// </summary>
|
||||
public string DisplayName => "My Connector";
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<FetchResult> FetchAsync(FetchContext context, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_logger.LogInformation("Fetching data from {ConnectorId}...", Id);
|
||||
|
||||
// TODO: Implement your fetch logic here
|
||||
// Example: Download data from an external source
|
||||
await Task.Delay(100, cancellationToken); // Placeholder
|
||||
|
||||
return new FetchResult(
|
||||
Success: true,
|
||||
Data: Array.Empty<byte>(),
|
||||
ContentType: "application/json",
|
||||
ETag: null);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ParseResult> ParseAsync(byte[] data, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_logger.LogInformation("Parsing data from {ConnectorId}...", Id);
|
||||
|
||||
// TODO: Implement your parsing logic here
|
||||
await Task.Yield();
|
||||
|
||||
return new ParseResult(
|
||||
Success: true,
|
||||
Items: Array.Empty<object>(),
|
||||
Errors: Array.Empty<string>());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<MapResult> MapAsync(object item, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_logger.LogInformation("Mapping item from {ConnectorId}...", Id);
|
||||
|
||||
// TODO: Implement your mapping logic here
|
||||
await Task.Yield();
|
||||
|
||||
return new MapResult(
|
||||
Success: true,
|
||||
MappedItem: item,
|
||||
Errors: Array.Empty<string>());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Result of a fetch operation.
|
||||
/// </summary>
|
||||
public sealed record FetchResult(
|
||||
bool Success,
|
||||
byte[] Data,
|
||||
string? ContentType,
|
||||
string? ETag);
|
||||
|
||||
/// <summary>
|
||||
/// Result of a parse operation.
|
||||
/// </summary>
|
||||
public sealed record ParseResult(
|
||||
bool Success,
|
||||
IReadOnlyList<object> Items,
|
||||
IReadOnlyList<string> Errors);
|
||||
|
||||
/// <summary>
|
||||
/// Result of a map operation.
|
||||
/// </summary>
|
||||
public sealed record MapResult(
|
||||
bool Success,
|
||||
object? MappedItem,
|
||||
IReadOnlyList<string> Errors);
|
||||
|
||||
/// <summary>
|
||||
/// Context for fetch operations.
|
||||
/// </summary>
|
||||
public sealed record FetchContext(
|
||||
string? LastETag = null,
|
||||
DateTimeOffset? LastFetchTime = null);
|
||||
42
templates/stellaops-plugin-connector/MyConnectorOptions.cs
Normal file
42
templates/stellaops-plugin-connector/MyConnectorOptions.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace StellaOps.Plugin.MyConnector;
|
||||
|
||||
/// <summary>
|
||||
/// Configuration options for the MyConnector plugin.
|
||||
/// </summary>
|
||||
public sealed class MyConnectorOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// The configuration section name.
|
||||
/// </summary>
|
||||
public const string SectionName = "Plugins:MyConnector";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the base URL for the connector's data source.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string BaseUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the API key for authentication.
|
||||
/// </summary>
|
||||
public string? ApiKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the request timeout in seconds. Default is 30.
|
||||
/// </summary>
|
||||
[Range(1, 300)]
|
||||
public int TimeoutSeconds { get; set; } = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of retry attempts. Default is 3.
|
||||
/// </summary>
|
||||
[Range(0, 10)]
|
||||
public int MaxRetries { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to enable verbose logging.
|
||||
/// </summary>
|
||||
public bool EnableVerboseLogging { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.DependencyInjection.Validation;
|
||||
|
||||
namespace StellaOps.Plugin.MyConnector;
|
||||
|
||||
/// <summary>
|
||||
/// Validates <see cref="MyConnectorOptions"/> configuration.
|
||||
/// </summary>
|
||||
public sealed class MyConnectorOptionsValidator : OptionsValidatorBase<MyConnectorOptions>
|
||||
{
|
||||
protected override string SectionPrefix => MyConnectorOptions.SectionName;
|
||||
|
||||
protected override void ValidateOptions(MyConnectorOptions options, ValidationContext context)
|
||||
{
|
||||
context
|
||||
.RequireNotEmpty(options.BaseUrl, nameof(options.BaseUrl))
|
||||
.RequirePositive(options.TimeoutSeconds, nameof(options.TimeoutSeconds))
|
||||
.RequireInRange(options.MaxRetries, nameof(options.MaxRetries), 0, 10);
|
||||
|
||||
// Validate URL format
|
||||
if (!string.IsNullOrWhiteSpace(options.BaseUrl) &&
|
||||
!Uri.TryCreate(options.BaseUrl, UriKind.Absolute, out _))
|
||||
{
|
||||
context.AddError(nameof(options.BaseUrl), "must be a valid absolute URL.");
|
||||
}
|
||||
}
|
||||
}
|
||||
33
templates/stellaops-plugin-connector/MyConnectorPlugin.cs
Normal file
33
templates/stellaops-plugin-connector/MyConnectorPlugin.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Plugin;
|
||||
using StellaOps.Plugin.Versioning;
|
||||
|
||||
// Declare plugin version for compatibility checking
|
||||
[assembly: StellaPluginVersion("1.0.0-template", MinimumHostVersion = "1.0.0")]
|
||||
|
||||
namespace StellaOps.Plugin.MyConnector;
|
||||
|
||||
/// <summary>
|
||||
/// Plugin entry point for the MyConnector connector.
|
||||
/// </summary>
|
||||
public sealed class MyConnectorPlugin : IConnectorPlugin
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Name => "MyConnector";
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsAvailable(IServiceProvider services)
|
||||
{
|
||||
// Add availability checks here (e.g., required configuration present)
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IFeedConnector Create(IServiceProvider services)
|
||||
{
|
||||
var logger = services.GetRequiredService<ILogger<MyConnector>>();
|
||||
var options = services.GetRequiredService<Microsoft.Extensions.Options.IOptions<MyConnectorOptions>>();
|
||||
return new MyConnector(logger, options.Value);
|
||||
}
|
||||
}
|
||||
47
templates/stellaops-plugin-connector/README.md
Normal file
47
templates/stellaops-plugin-connector/README.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# MyConnector Plugin
|
||||
|
||||
A StellaOps connector plugin template.
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. Update the `MyConnectorOptions.cs` with your connector-specific configuration
|
||||
2. Implement the fetch, parse, and map logic in `MyConnector.cs`
|
||||
3. Update the plugin metadata in `MyConnectorPlugin.cs`
|
||||
4. Build and sign your plugin
|
||||
|
||||
## Configuration
|
||||
|
||||
Add the following to your `appsettings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"Plugins": {
|
||||
"MyConnector": {
|
||||
"BaseUrl": "https://api.example.com",
|
||||
"ApiKey": "your-api-key",
|
||||
"TimeoutSeconds": 30,
|
||||
"MaxRetries": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
dotnet build -c Release
|
||||
```
|
||||
|
||||
## Signing
|
||||
|
||||
For production use, sign your plugin with Cosign:
|
||||
|
||||
```bash
|
||||
cosign sign --key $COSIGN_KEY bin/Release/net10.0/StellaOps.Plugin.MyConnector.dll
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
dotnet test
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.0.0-template</Version>
|
||||
<Description>StellaOps MyConnector Plugin</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Reference StellaOps plugin infrastructure -->
|
||||
<!-- Adjust paths based on your repository structure -->
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\__Libraries\StellaOps.Plugin\StellaOps.Plugin.csproj" />
|
||||
<ProjectReference Include="..\..\src\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user