Files
git.stella-ops.org/docs/10_PLUGIN_SDK_GUIDE.md
master 5fd4032c7c
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Add channel test providers for Email, Slack, Teams, and Webhook
- Implemented EmailChannelTestProvider to generate email preview payloads.
- Implemented SlackChannelTestProvider to create Slack message previews.
- Implemented TeamsChannelTestProvider for generating Teams Adaptive Card previews.
- Implemented WebhookChannelTestProvider to create webhook payloads.
- Added INotifyChannelTestProvider interface for channel-specific preview generation.
- Created ChannelTestPreviewContracts for request and response models.
- Developed NotifyChannelTestService to handle test send requests and generate previews.
- Added rate limit policies for test sends and delivery history.
- Implemented unit tests for service registration and binding.
- Updated project files to include necessary dependencies and configurations.
2025-10-19 23:29:34 +03:00

220 lines
7.3 KiB
Markdown
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#10 · Plugin SDK Guide — **StellaOps**
*(v1.5  11Jul2025 · template install, no reload, IoC)*
---
##0Audience & Scope
Guidance for developers who extend StellaOps with schedule jobs, scanner adapters, TLS providers, notification channels, etc. Everything here is OSS; commercial variants simply ship additional signed plugins.
---
##1Prerequisites
| Tool | Min Version |
| ----------------------- | ----------------------------------------------------------------- |
| .NET SDK | {{ dotnet }} |
| **StellaOps templates** | install once via `bash dotnet new install StellaOps.Templates::*` |
| **Cosign** | 2.3+ — used to sign DLLs |
| xUnit | 2.6 |
| Docker CLI | only if your plugin shells out to containers |
---
##2Repository & Build Output
Every plugin is hosted in **`git.stellaops.org`**.
At publish time it must copy its signed artefacts to:
~~~text
src/backend/Stella.Ops.Plugin.Binaries/<MyPlugin>/
├── MyPlugin.dll
└── MyPlugin.dll.sig
~~~
The backend scans this folder on startup, verifies the **Cosign** signature, confirms the `[StellaPluginVersion]` gate, then loads the DLL inside an **isolated AssemblyLoadContext** to avoid dependency clashes
---
##3Project Scaffold
Generate with the installed template:
~~~bash
dotnet new stellaops-plugin-schedule \
-n MyPlugin.Schedule \
--output src
~~~
Result:
~~~text
src/
├─ MyPlugin.Schedule/
│ ├─ MyJob.cs
│ └─ MyPlugin.Schedule.csproj
└─ tests/
└─ MyPlugin.Schedule.Tests/
~~~
---
##4MSBuild Wiring
Add this to **`MyPlugin.Schedule.csproj`** so the signed DLL + `.sig` land in the canonical plugin folder:
~~~xml
<PropertyGroup>
<StellaPluginOut>$(SolutionDir)src/backend/Stella.Ops.Plugin.Binaries/$(MSBuildProjectName)</StellaPluginOut>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\StellaOps.Common\StellaOps.Common.csproj"
PrivateAssets="all" />
</ItemGroup>
<Target Name="CopyStellaPlugin" AfterTargets="Publish">
<MakeDir Directories="$(StellaPluginOut)" />
<Copy SourceFiles="$(PublishDir)$(AssemblyName).dll;$(PublishDir)$(AssemblyName).dll.sig"
DestinationFolder="$(StellaPluginOut)" />
</Target>
~~~
---
##5DependencyInjection Entrypoint
Backend autodiscovers restarttime bindings through two mechanisms:
1. **Service binding metadata** for simple contracts.
2. **`IDependencyInjectionRoutine`** implementations when you need full control.
###5.1Service binding metadata
Annotate implementations with `[ServiceBinding]` to declare their lifetime and service contract.
The loader honours scoped lifetimes and will register the service before executing any custom DI routines.
~~~csharp
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
[ServiceBinding(typeof(IJob), ServiceLifetime.Scoped, RegisterAsSelf = true)]
public sealed class MyJob : IJob
{
// IJob dependencies can now use scoped services (Mongo sessions, etc.)
}
~~~
Use `RegisterAsSelf = true` when you also want to resolve the concrete type.
Set `ReplaceExisting = true` to override default descriptors if the host already provides one.
###5.2Dependency injection routines
For advanced scenarios continue to expose a routine:
~~~csharp
namespace StellaOps.DependencyInjection;
public sealed class IoCConfigurator : IDependencyInjectionRoutine
{
public IServiceCollection Register(IServiceCollection services, IConfiguration cfg)
{
services.AddSingleton<IJob, MyJob>(); // schedule job
services.Configure<MyPluginOptions>(cfg.GetSection("Plugins:MyPlugin"));
return services;
}
}
~~~
---
##6Schedule Plugins
###6.1 Minimal Job
~~~csharp
using StellaOps.Scheduling; // contract
[StellaPluginVersion("2.0.0")]
public sealed class MyJob : IJob
{
public async Task ExecuteAsync(CancellationToken ct)
{
Console.WriteLine("Hello from plugin!");
await Task.Delay(500, ct);
}
}
~~~
###6.2 Cron Registration
```csharp
services.AddCronJob<MyJob>("0 15 * * *"); // everyday
```
15:00
Cron syntax follows Hangfire rules 
##7Scanner Adapters
Implement IScannerRunner.
Register inside Configure:
```csharp
services.AddScanner<MyAltScanner>("alt"); // backend
```
selects by --engine alt
If the engine needs a sidecar container, include a Dockerfile in your repo and document resource expectations.
##8Packaging & Signing
```bash
dotnet publish -c Release -p:PublishSingleFile=true -o out
cosign sign --key $COSIGN_KEY out/MyPlugin.Schedule.dll # sign binary only
sha256sum out/MyPlugin.Schedule.dll > out/.sha256 # optional checksum
zip MyPlugin.zip out/* README.md
```
Unsigned DLLs are refused when StellaOps:Security:DisableUnsigned=false.
##9Deployment
```bash
docker cp MyPlugin.zip <backend>:/opt/plugins/ && docker restart <backend>
```
Check /health "plugins":["MyPlugin.Schedule@2.0.0"].
(Hotreload was removed to keep the core process simple and memorysafe.)
##10Configuration Patterns
| Need | Pattern |
| ------------ | --------------------------------------------------------- |
| Settings | Plugins:MyPlugin:* in appsettings.json. |
| Secrets | Redis secure:<plugin>:<key> (encrypted per TLS provider). |
| Dynamic cron | Implement ICronConfigurable; UI exposes editor. |
##11Testing & CI
| Layer | Tool | Gate |
| ----------- | -------------------------- | ------------------- |
| Unit | xUnit + Moq | ≥50% lines |
| Integration | Testcontainers run in CI | Job completes <5s |
| Style | dotnet | format 0 warnings |
Use the prebaked workflow in StellaOps.Templates as starting point.
##12Publishing to the Community Marketplace
Tag Git release pluginvX.Y.Z and attach the signed ZIP.
Submit a PR to stellaops/community-plugins.json with metadata & git URL.
On merge, the plugin shows up in the UI Marketplace.
##13Common Pitfalls
| Symptom | Root cause | Fix |
| ------------------- | -------------------------- | ------------------------------------------- |
| NotDetected | .sig missing | cosign sign |
| VersionGateMismatch | Backend 2.1 vs plugin 2.0 | Recompile / bump attribute |
| FileLoadException | Duplicate | StellaOps.Common Ensure PrivateAssets="all" |
| Redis | timeouts Large writes | Batch or use Mongo |