kestra-io / kestra-io/plugin-ovhcloud
[plugin-ovhcloud] Domains & Web — Domain registration, DNS zones, and SSL certificates
- Dominant language
- Java
- Stars
- 0
- Forks
- 0
- Avg merge
- 18h 6m
- Merged PRs (30d)
- 1
Description
## Summary
Implement the `domain` sub-plugin for `plugin-ovhcloud`, giving Kestra flows control over OVHcloud domain assets: registrar-level domain management (contacts, nameservers, EPP transfer codes, DNSSEC), DNS zone record CRUD with zone propagation, and SSL/TLS certificate lifecycle via OVHcloud's SSL and SSL Gateway services. Web platform teams can use this plugin to automate domain provisioning, DNS cutover during deployments, and certificate renewal checks.
## Motivation
Domain and SSL operations are notoriously manual and error-prone when done through a UI — especially during migrations or blue/green DNS cutovers under time pressure. Encoding these steps as Kestra tasks makes them auditable, retryable, and safe to run as part of a larger deployment pipeline (e.g. create record → wait → verify → update → clean up old record).
## Context
Part of the OVHcloud plugin EPIC: https://github.com/kestra-io/plugin-ovhcloud/issues/2.
Reference implementation: `plugin-ee-netbox` (DNS record management patterns) and `plugin-gcp` (Cloud DNS tasks). The `networking.dns` sub-plugin (issue #7959) covers DNS zones for networking purposes; this sub-plugin focuses on the registrar and web certificate layers that sit on top of DNS zones. Both share the same OVH `/domain/zone` API — coordinate to avoid duplication (consider a shared `dns` package).
## API Reference
- **Official docs (Domain)**: https://eu.api.ovh.com/console/?section=%2Fdomain&branch=v1
- **Official docs (SSL)**: https://eu.api.ovh.com/console/?section=%2Fssl&branch=v1
- **DNS API guide**: https://help.ovhcloud.com/csm/en-domain-names-api-dns
- **Authentication**: OVH 3-key HMAC for all endpoints
- **Base URL**: `https://eu.api.ovh.com/1.0/`
- **SDK**: `net.minidev:ovh-java-sdk-domain:1.0.17`
## Gradle Dependencies
Add to `build.gradle`:
```groovy
// OVH management plane
implementation 'net.minidev:ovh-java-sdk-core:1.0.17'
implementation 'net.minidev:ovh-java-sdk-domain:1.0.17'
```
> Use the latest stable version available on Maven Central.
## Plugin Structure
- **Repository**: `plugin-ovhcloud`
- **Namespace**: `io.kestra.plugin.ovhcloud`
- **Sub-plugins**: `domain.registrar`, `domain.zone`, `domain.ssl`
## Suggested Tasks
1. **`domain.registrar`** — `ListDomains`, `GetDomain`, `GetAuthInfo` (EPP transfer code), `ListNameservers`, `AddNameserver`, `RemoveNameserver`
2. **`domain.zone`** — `ListZones`, `ListRecords`, `CreateRecord`, `UpdateRecord`, `DeleteRecord`, `RefreshZone`, `ExportZone`, `ImportZone`
3. **`domain.zone`** — `EnableDnssec`, `DisableDnssec`
4. **`domain.ssl`** — `ListCertificates`, `GetCertificate`, `GetCertificateTasks`
5. Add polling trigger `domain.ssl.CertificateExpiryTrigger` (fires N days before certificate expiry)
6. Write unit + integration tests
7. Add `package-info.java` with `@PluginSubGroup(category = PluginSubGroup.PluginCategory.CLOUD)`
8. Add YAML examples and plugin documentation
## YAML Examples
### Example 1 — Update a DNS A record during a blue/green deployment
```yaml
id: dns_cutover
namespace: company.team
inputs:
- id: zone
type: STRING
- id: new_ip
type: STRING
- id: record_id
type: STRING
tasks:
- id: update_record
type: io.kestra.plugin.ovhcloud.domain.zone.UpdateRecord
endpoint: "{{ secret('OVH_ENDPOINT') }}"
applicationKey: "{{ secret('OVH_APP_KEY') }}"
applicationSecret: "{{ secret('OVH_APP_SECRET') }}"
consumerKey: "{{ secret('OVH_CONSUMER_KEY') }}"
zone: "{{ inputs.zone }}"
recordId: "{{ inputs.record_id }}"
target: "{{ inputs.new_ip }}"
ttl: 60
- id: refresh
type: io.kestra.plugin.ovhcloud.domain.zone.RefreshZone
endpoint: "{{ secret('OVH_ENDPOINT') }}"
applicationKey: "{{ secret('OVH_APP_KEY') }}"
applicationSecret: "{{ secret('OVH_APP_SECRET') }}"
consumerKey: "{{ secret('OVH_CONSUMER_KEY') }}"
zone: "{{ inputs.zone }}"
- id: log
type: io.kestra.plugin.core.log.Log
message: "DNS cutover complete — zone {{ inputs.zone }} now points to {{ inputs.new_ip }}"
```
### Example 2 — Export a DNS zone backup before making changes
```yaml
id: zone_backup_before_migration
namespace: company.team
tasks:
- id: export_zone
type: io.kestra.plugin.ovhcloud.domain.zone.ExportZone
endpoint: "{{ secret('OVH_ENDPOINT') }}"
applicationKey: "{{ secret('OVH_APP_KEY') }}"
applicationSecret: "{{ secret('OVH_APP_SECRET') }}"
consumerKey: "{{ secret('OVH_CONSUMER_KEY') }}"
zone: "{{ secret('ZONE_NAME') }}"
- id: store_backup
type: io.kestra.plugin.ovhcloud.storage.objectstorage.Upload
accessKey: "{{ secret('OVH_S3_ACCESS_KEY') }}"
secretKey: "{{ secret('OVH_S3_SECRET_KEY') }}"
region: "gra"
bucket: "dns-backups"
key: "{{ secret('ZONE_NAME') }}/{{ execution.startDate }}.zone"
content: "{{ outputs.export_zone.zoneFile }}"
```
### Example 3 — Alert 30 days before an SSL certificate expires
```yaml
id: ssl_expiry_check
namespace: company.team
triggers:
- id: cert_expiry_watch
type: io.kestra.plugin.ovhcloud.domain.ssl.CertificateExpiryTrigger
endpoint: "{{ secret('OVH_ENDPOINT') }}"
applicationKey: "{{ secret('OVH_APP_KEY') }}"
applicationSecret: "{{ secret('OVH_APP_SECRET') }}"
consumerKey: "{{ secret('OVH_CONSUMER_KEY') }}"
daysBeforeExpiry: 30
interval: P1D
tasks:
- id: notify
type: io.kestra.plugin.core.log.Log
message: "Certificate {{ trigger.serviceName }} expires on {{ trigger.expiryDate }} ({{ trigger.daysRemaining }} days left)"
```
## Acceptance Criteria
- [ ] Registrar `ListDomains`, `GetDomain`, `GetAuthInfo`, `ListNameservers`, `AddNameserver` tasks
- [ ] DNS zone `ListRecords`, `CreateRecord`, `UpdateRecord`, `DeleteRecord`, `RefreshZone`, `ExportZone`, `ImportZone` tasks
- [ ] DNSSEC `EnableDnssec`, `DisableDnssec` tasks
- [ ] SSL `ListCertificates`, `GetCertificate` tasks
- [ ] At least one polling trigger (`CertificateExpiryTrigger`)
- [ ] All `Property` fields support Kestra expression language
- [ ] Unit + integration tests pass (`./gradlew test`)
- [ ] `package-info.java` with `@PluginSubGroup`
- [ ] Build passes with `./gradlew build`
---
## Repository Setup Checklist
> The repository is shared with other sub-plugins — scaffold once from the EPIC (https://github.com/kestra-io/plugin-ovhcloud/issues/2). Skip if already done.
### 1. Scaffold the repository
Create the repository using the Kestra plugin scaffold tool:
https://github.com/kestra-io/plugins-devtools#kestra-plugin-scaffold
### 2. Add to Sanity check page
Add this plugin to the [Sanity check Notion page](https://www.notion.so/kestra-io/32736907f7b580cbb00dc7c061e624b1?v=32736907f7b58002ac2b000ccc63d8a2).
### 3. Run scoped Terraform apply
Run the following from `infra/terraform/github`:
```bash
terraform apply \
-target='github_repository.repo["plugin-ovhcloud"]' \
-target='github_issue_labels.plugins["plugin-ovhcloud"]' \
-target='github_repository_ruleset.branch["plugin-ovhcloud"]'
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the plugin scaffold and the OVHcloud Domain, SSL, and DNS API references, then inspect the existing plugin-ovhcloud repository and its build.gradle. Define the registrar, zone, SSL, trigger, tests, package-info.java, YAML examples, and documentation scope while coordinating shared DNS work with issue #7959. Done means all listed acceptance criteria pass, including ./gradlew test and ./gradlew build.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- cloud, networking, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100