diff --git a/.gitignore b/.gitignore index 29d31af3..743dab8a 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,6 @@ notes/ docs/public docs/resources/_gen/ docs/.hugo_build.lock -test/integration/clab-* \ No newline at end of file +test/integration/clab-* +docs/content/docs/advanced/rest-api-documentation/.openapi-generator +docs/content/docs/advanced/rest-api-documentation/.openapi-generator-ignore diff --git a/docs/content/docs/Apis/DefaultApi.md b/docs/content/docs/Apis/DefaultApi.md new file mode 100644 index 00000000..513f6da6 --- /dev/null +++ b/docs/content/docs/Apis/DefaultApi.md @@ -0,0 +1,2 @@ +# DefaultApi + diff --git a/docs/content/docs/advanced/openapi-generator-config.yaml b/docs/content/docs/advanced/openapi-generator-config.yaml new file mode 100644 index 00000000..5f041408 --- /dev/null +++ b/docs/content/docs/advanced/openapi-generator-config.yaml @@ -0,0 +1,9 @@ +# docker run --rm -v ${PWD}:/local openapitools/openapi-generator-cli generate -c /local/docs/content/docs/advanced/openapi-generator-config.yaml + +generatorName: markdown +inputSpec: /local/internal/apiserver/openapi.yaml +outputDir: /local/docs/content/docs/advanced/rest-api-documentation +templateDir: /local/docs/content/docs/advanced/openapi-templates/markdown-documentation +files: + README.mustache: + destinationFilename: _index.md \ No newline at end of file diff --git a/docs/content/docs/advanced/openapi-templates/markdown-documentation/README.mustache b/docs/content/docs/advanced/openapi-templates/markdown-documentation/README.mustache new file mode 100644 index 00000000..7b3df486 --- /dev/null +++ b/docs/content/docs/advanced/openapi-templates/markdown-documentation/README.mustache @@ -0,0 +1,69 @@ +--- +title: "REST API interface" +linkTitle: "REST API interface" +weight: 3 +description: > + This document describes the REST API exposed by the gNMIc Operator, including the available endpoints, request formats, and usage examples. +--- + +{{#generateApiDocs}} + +## Documentation for API Endpoints + +All URIs are relative to *{{{basePath}}}:8082* + +| Class | Method | HTTP request | Description | +|------------ | ------------- | ------------- | -------------| +{{#apiInfo}}{{#apis}}{{#operations}}| {{#operation}}*{{#lambda.lowercase}}{{classname}}{{/lambda.lowercase}}* | [**{{operationId}}**](/docs/advanced/rest-api-documentation/apis/{{#lambda.lowercase}}{{classname}}{{/lambda.lowercase}}) | **{{httpMethod}}** {{path}} | {{{summary}}}{{^summary}}{{{notes}}}{{/summary}} | +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} +{{/generateApiDocs}} + +{{#generateModelDocs}} + +## Documentation for Models + +{{#modelPackage}} +{{#models}}{{#model}} - [{{#lambda.lowercase}}{{{classname}}}{{/lambda.lowercase}}](/docs/advanced/rest-api-documentation/models/{{#lambda.lowercase}}{{{classFilename}}}{{/lambda.lowercase}}/) +{{/model}}{{/models}} +{{/modelPackage}} +{{^modelPackage}} +No model defined in this package +{{/modelPackage}} +{{/generateModelDocs}} + +{{! TODO: optional documentation for authorization? }} +## Documentation for Authorization + +For a detailed explanation on how to configure the required secrets within the gNMIc Operator, refer to [TargetSource > Push mode](/docs/user-guide/targetsource/push/). + +{{^authMethods}} +All endpoints do not require authorization. +{{/authMethods}} +{{#authMethods}} +{{#last}} + Authentication schemes defined for the API: +{{/last}} +{{/authMethods}} +{{#authMethods}} + +### {{name}} + +{{#isApiKey}}- **Type**: API key +- **API key parameter name**: {{keyParamName}} +- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}} +{{/isApiKey}} +{{#isBasicBasic}}- **Type**: HTTP basic authentication +{{/isBasicBasic}} +{{#isBasicBearer}}- **Type**: HTTP Bearer Token authentication{{#bearerFormat}} ({{{.}}}){{/bearerFormat}} +{{/isBasicBearer}} +{{#isHttpSignature}}- **Type**: HTTP signature authentication +{{/isHttpSignature}} +{{#isOAuth}}- **Type**: OAuth +- **Flow**: {{flow}} +- **Authorization URL**: {{authorizationUrl}} +- **Scopes**: {{^scopes}}N/A{{/scopes}} +{{#scopes}} - {{scope}}: {{description}} +{{/scopes}} +{{/isOAuth}} + +{{/authMethods}} \ No newline at end of file diff --git a/docs/content/docs/advanced/openapi-templates/markdown-documentation/api.mustache b/docs/content/docs/advanced/openapi-templates/markdown-documentation/api.mustache new file mode 100644 index 00000000..8a75a8a9 --- /dev/null +++ b/docs/content/docs/advanced/openapi-templates/markdown-documentation/api.mustache @@ -0,0 +1,50 @@ +--- +title: "Routes" +linkTitle: "Routes" +weight: 4 +description: > + Available HTTP routes on the gNMIc Operator API interface. +--- + +# {{#lambda.lowercase}}{{classname}}{{/lambda.lowercase}}{{#description}} + {{.}}{{/description}} + +All URIs are relative to *{{basePath}}:8082* + +| Method | HTTP request | Description | +|------------- | ------------- | -------------| +{{#operations}}{{#operation}}| **{{operationId}}** | **{{httpMethod}}** {{path}} | {{summary}} | +{{/operation}}{{/operations}} + +{{#operations}} +{{#operation}} + +# **{{operationId}}** +> {{#returnType}}{{.}} {{/returnType}}{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}) + +{{summary}}{{#notes}} + + {{.}}{{/notes}} + +### Parameters +{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}} +|Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------|{{/-last}}{{/allParams}} +{{#allParams}}| **{{paramName}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isFile}}**{{dataType}}**{{/isFile}}{{^isFile}}{{#generateModelDocs}}[**{{dataType}}**](/docs/advanced/rest-api-documentation/models/{{#lambda.lowercase}}{{baseType}}{{/lambda.lowercase}}/){{/generateModelDocs}}{{^generateModelDocs}}**{{dataType}}**{{/generateModelDocs}}{{/isFile}}{{/isPrimitiveType}}| {{description}} |{{^required}} [optional]{{/required}}{{#defaultValue}} [default to {{.}}]{{/defaultValue}}{{#allowableValues}} [enum: {{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}]{{/allowableValues}} | +{{/allParams}} + +### Return type + +{{#returnType}}{{#returnTypeIsPrimitive}}**{{returnType}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{#generateModelDocs}}[**{{returnType}}**](/docs/advanced/rest-api-documentation/models/{{#lambda.lowercase}}{{returnBaseType}}{{/lambda.lowercase}}/){{/generateModelDocs}}{{^generateModelDocs}}**{{returnType}}**{{/generateModelDocs}}{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}null (empty response body){{/returnType}} + +### Authorization + +{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{name}}](/docs/advanced/rest-api-documentation/#{{name}}){{^-last}}, {{/-last}}{{/authMethods}} + +### HTTP request headers + +- **Content-Type**: {{#consumes}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}} +- **Accept**: {{#produces}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}} + +{{/operation}} +{{/operations}} \ No newline at end of file diff --git a/docs/content/docs/advanced/openapi-templates/markdown-documentation/model.mustache b/docs/content/docs/advanced/openapi-templates/markdown-documentation/model.mustache new file mode 100644 index 00000000..3ee88fd2 --- /dev/null +++ b/docs/content/docs/advanced/openapi-templates/markdown-documentation/model.mustache @@ -0,0 +1,29 @@ +--- +title: "Model" +linkTitle: "Model" +weight: 4 +description: > + Documentation for OpenAPI models and their schema-defined properties. +--- + +{{#models}} +{{#model}} +# {{#lambda}}{{{classname}}}{{/lambda}} +{{#description}} +{{{description}}} +{{/description}} + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +{{#parent}} +{{#parentVars}} +| **{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{#lambda.lowercase}}{{complexType}}{{/lambda.lowercase}}.md){{/isPrimitiveType}} | {{{description}}} | {{^required}}[optional] {{/required}}{{#readOnly}}[readonly] {{/readOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}} | +{{/parentVars}} +{{/parent}} +{{#vars}}| **{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{#lambda.lowercase}}{{complexType}}{{/lambda.lowercase}}.md){{/isPrimitiveType}} | {{{description}}} | {{^required}}[optional] {{/required}}{{#readOnly}}[readonly] {{/readOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}} | +{{/vars}} + + {{/model}} +{{/models}} \ No newline at end of file diff --git a/docs/content/docs/advanced/rest-api-documentation.md b/docs/content/docs/advanced/rest-api-documentation.md new file mode 100644 index 00000000..edba35f0 --- /dev/null +++ b/docs/content/docs/advanced/rest-api-documentation.md @@ -0,0 +1,33 @@ +--- +title: "Documentation for gNMIc Operator REST API" +linkTitle: "REST API interface" +weight: 3 +description: > + Documentation of REST API interface according to openAPI standard. +--- + + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost* + +| Class | Method | HTTP request | Description | +|------------ | ------------- | ------------- | -------------| +| *DefaultApi* | [**applyTargets**](../Apis/DefaultApi.md#applyTargets) | **POST** /api/v1/:namespace/target-source/:name/applyTargets | Interface for real-time target updates, usually using a webhook. Targets are applied in the gNMIc Operator. | +*DefaultApi* | [**getClusterPlan**](../Apis/DefaultApi.md#getClusterPlan) | **GET** /clusters/:namespace/:name/plan | Get cluster plan. | + + + +## Documentation for Models + + - [Target](../Models/Target.md) + + + +## Documentation for Authorization + + +### bearerAuth + +- **Type**: HTTP Bearer Token authentication + diff --git a/docs/content/docs/advanced/rest-api-documentation/Apis/DefaultApi.md b/docs/content/docs/advanced/rest-api-documentation/Apis/DefaultApi.md new file mode 100644 index 00000000..ec3b4c08 --- /dev/null +++ b/docs/content/docs/advanced/rest-api-documentation/Apis/DefaultApi.md @@ -0,0 +1,65 @@ +--- +title: "Routes" +linkTitle: "Routes" +weight: 4 +description: > + Available HTTP routes on the gNMIc Operator API interface. +--- + +# defaultapi + +All URIs are relative to *http://localhost:8082* + +| Method | HTTP request | Description | +|------------- | ------------- | -------------| +| **applyTargets** | **POST** /api/v1/:namespace/target-source/:name/applyTargets | Interface for real-time target updates, usually using a webhook. Targets are applied in the gNMIc Operator. | +| **getClusterPlan** | **GET** /clusters/:namespace/:name/plan | Get cluster plan. | + + + +# **applyTargets** +> List applyTargets(Target) + +Interface for real-time target updates, usually using a webhook. Targets are applied in the gNMIc Operator. + +### Parameters + +|Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **Target** | [**List**](/docs/advanced/rest-api-documentation/models/target/)| Target must be passed as a list, multiple targets possible. | | + +### Return type + +[**List**](/docs/advanced/rest-api-documentation/models/target/) + +### Authorization + +[signature](/docs/advanced/rest-api-documentation/#signature), [bearerAuth](/docs/advanced/rest-api-documentation/#bearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + + +# **getClusterPlan** +> getClusterPlan() + +Get cluster plan. + +### Parameters +This endpoint does not need any parameter. + +### Return type + +null (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + diff --git a/docs/content/docs/advanced/rest-api-documentation/Models/Target.md b/docs/content/docs/advanced/rest-api-documentation/Models/Target.md new file mode 100644 index 00000000..58c08caa --- /dev/null +++ b/docs/content/docs/advanced/rest-api-documentation/Models/Target.md @@ -0,0 +1,22 @@ +--- +title: "Model" +linkTitle: "Model" +weight: 4 +description: > + Documentation for OpenAPI models and their schema-defined properties. +--- + +# Target +Network device to be monitored. Properties not marked as optional must be in JSON body. + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **name** | **String** | Name of device to be monitored. | [default to null] | +| **address** | **String** | IPv4/IPv6 address or hostname. | [default to null] | +| **port** | **Integer** | gNMIc port. | [optional] [default to null] | +| **targetProfile** | **String** | TargetProfile applied to apply to this router. | [optional] [default to null] | +| **labels** | [**List**](map.md) | Input of labels as key:value pair. | [optional] [default to null] | +| **operation** | **String** | Either `created`, `updated` or `deleted`. `created` and `updated` are identical and both apply the target. | [default to null] | + diff --git a/docs/content/docs/advanced/rest-api-documentation/_index.md b/docs/content/docs/advanced/rest-api-documentation/_index.md new file mode 100644 index 00000000..93b2d678 --- /dev/null +++ b/docs/content/docs/advanced/rest-api-documentation/_index.md @@ -0,0 +1,42 @@ +--- +title: "REST API interface" +linkTitle: "REST API interface" +weight: 3 +description: > + This document describes the REST API exposed by the gNMIc Operator, including the available endpoints, request formats, and usage examples. +--- + + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost:8082* + +| Class | Method | HTTP request | Description | +|------------ | ------------- | ------------- | -------------| +| *defaultapi* | [**applyTargets**](/docs/advanced/rest-api-documentation/apis/defaultapi) | **POST** /api/v1/:namespace/target-source/:name/applyTargets | Interface for real-time target updates, usually using a webhook. Targets are applied in the gNMIc Operator. | +*defaultapi* | [**getClusterPlan**](/docs/advanced/rest-api-documentation/apis/defaultapi) | **GET** /clusters/:namespace/:name/plan | Get cluster plan. | + + + +## Documentation for Models + + - [target](/docs/advanced/rest-api-documentation/models/target/) + + + +## Documentation for Authorization + +For a detailed explanation on how to configure the required secrets within the gNMIc Operator, refer to [TargetSource > Push mode](/docs/user-guide/targetsource/push/). + + +### bearerAuth + +- **Type**: HTTP Bearer Token authentication + + +### signature + +- **Type**: API key +- **API key parameter name**: X-Hook-Signature +- **Location**: HTTP header + diff --git a/docs/content/docs/examples/NetBox/Export Template/_index.md b/docs/content/docs/examples/NetBox/Export Template/_index.md index 2cc48b3b..fd481841 100644 --- a/docs/content/docs/examples/NetBox/Export Template/_index.md +++ b/docs/content/docs/examples/NetBox/Export Template/_index.md @@ -1,6 +1,6 @@ --- -title: "NetBox (Export Template)" -linkTitle: "NetBox Export Template" +title: "Pull with Export Template" +linkTitle: "Pull with Export Template" weight: 1 description: > Discover targets from NetBox using HTTP provider with NetBox Export Template @@ -12,14 +12,14 @@ Export Templates offer powerful filtering, transformation, and formatting direct ## Overview -An **Export Template** is a Jinja2 template defined in NetBox that: +An **Export Template** is a Jinja2 template that: 1. **Queries** NetBox's internal database (devices, interfaces, etc.) 2. **Filters** results based on custom criteria -3. **Transforms** data into your desired output format (JSON, YAML, CSV, etc.) -4. **Returns** the formatted output via a custom REST API endpoint +3. **Transforms** data into your desired output format +4. **Returns** the formatted output via REST API endpoint -When used with gNMIc's HTTP provider, the operator simply fetches the rendered JSON template and parses the result — no additional gNMIc Operator transformation needed if done correctly. +When used with gNMIc's HTTP provider, the operator fetches the rendered JSON template and parses the result with no further transformation needed by the gNMIc Operator. --- diff --git a/docs/content/docs/examples/NetBox/REST API/_index.md b/docs/content/docs/examples/NetBox/REST API/_index.md index 18111d75..fcbd990a 100644 --- a/docs/content/docs/examples/NetBox/REST API/_index.md +++ b/docs/content/docs/examples/NetBox/REST API/_index.md @@ -1,6 +1,6 @@ --- -title: "NetBox (REST API)" -linkTitle: "NetBox REST" +title: "Pull with REST API" +linkTitle: "Pull with REST API" weight: 2 description: > Discover targets from NetBox using the HTTP provider and NetBox REST API diff --git a/docs/content/docs/examples/NetBox/webhook/_index.md b/docs/content/docs/examples/NetBox/webhook/_index.md new file mode 100644 index 00000000..b8b11467 --- /dev/null +++ b/docs/content/docs/examples/NetBox/webhook/_index.md @@ -0,0 +1,134 @@ +--- +title: "Push mode with webhook" +linkTitle: "Push mode with webhook" +weight: 2 +description: > + Configure a webhook in NetBox to update targets in the gNMIc Operator in real time. +--- + +## Netbox Webhook Configuration + +This tutorial walks through configuring a webhook in NetBox to push real-time target updates to the gNMIc Operator. The workflow includes the following steps: + +1. Apply TargetSource +2. Create Kubernetes Secrets +3. Configure Webhook +4. Create Event Rule +5. Verification + +### Prerequisites + +- Kubernetes cluster with gNMIc Operator installed +- `kubectl` access to your cluster +- Running NetBox instance +- Network connectivity from NetBox to the gNMIc Operator API endpoint + +--- + +### 1. Apply TargetSource + +Apply the TargetSource manifest: `kubectl apply -f netbox.yaml -n default` + +- `enabled` must be set to `true`, otherwise updates are rejected. +- Bearer authentication and signature verification are enabled. + +```yaml +# netbox.yaml +apiVersion: operator.gnmic.dev/v1alpha1 +kind: TargetSource +metadata: + name: netbox +spec: + provider: + http: + push: + enabled: true + auth: + bearer: + tokenSecretRef: + name: gnmic-api-auth + key: bearer-token + signature: + secretRef: + name: gnmic-signature + key: signature + targetLabels: + integrationtest: http + targetProfile: default +``` + +> Namespace is `default`, the name of the TargetSource is `netbox`. These values will be in the URL in step 3. + +### 2. Create Kubernetes Secrets + +Bearer authentication and signature verification both require Kubernetes secrets. Ensure that the secrets: + +- Are created in the same namespace as the TargetSource (`default` in this example). +- Use `name` and `key` values that match the TargetSource spec. + +```bash +kubectl create secret generic gnmic-api-auth --from-literal=bearer-token=thisIsASecureToken -n default +kubectl create secret generic gnmic-signature --from-literal=signature=SecretSignature -n default +``` + +### 3. Configure Webhook + +Next, configure a webhook in NetBox. The webhook is triggered by device events (for example, updates) and sends an HTTP POST request to the gNMIc Operator. + +In NetBox, go to `Operations > Webhooks` and create a webhook with the following settings: + +- *Name*: GNMIc operator push +- *URL*: `http://gnmic-controller-manager-api.gnmic-system.svc.cluster.local:8082/api/v1/default/target-source/netbox/applyTargets` + - Depending on your environment, the cluster address may instead be `http://localhost:8082/` or `http://servername:8082/`. + - URL contains the namespace `default` and TargetSource name `netbox`. +- *HTTP method*: POST +- *HTTP content type*: application/json +- *SSL Verification*: true +- *Additional headers:* `Authorization: Bearer thisIsASecureToken` +- *Body Template*: + + ```json + [ + { + "name": "{{ data.name }}", + "address": "{{ data.primary_ip4.address.split('/')[0] }}", + "operation": "{{ event }}", + "targetProfile": "{{ data.custom_fields.target_profile | default('', true) }}", + "port": {{ data.custom_fields.gnmic_port | default(57400, true) }}, + "labels": [ + { + "key": "vendor", + "value": "{{ data.device_type.manufacturer.name }}" + } + ] + } + ] + ``` + +- *Secret*: `SecretSignature` + +### 4. Create Event Rule + +The webhook requires a trigger, configured as an event rule under `Operations > Event Rules`. + +- *Name*: gNMIc Operator push target change +- *Object types*: DCIM > Device +- *Event types*: "Object Created", "Object Updated", "Object Deleted" +- *Action type*: Webhook +- *Webhook*: gNMIc Operator push + +--- + +### 5. Verification + +Updating a device in NetBox should now trigger the webhook. Verify this with the following commands: + +```bash +kubectl get targets +kubectl get targets -o yaml + +# Check logs of incoming POST requests: +kubectl logs -n gnmic-system deploy/gnmic-controller-manager -f +``` + +Every incoming POST request is logged, including rejected requests. If no POST requests appear in the logs, the webhook request is not reaching the gNMIc Operator. diff --git a/docs/content/docs/user-guide/targetsource/providers/http.md b/docs/content/docs/user-guide/targetsource/providers/http.md index de0f3b6b..99bc1b2d 100644 --- a/docs/content/docs/user-guide/targetsource/providers/http.md +++ b/docs/content/docs/user-guide/targetsource/providers/http.md @@ -6,8 +6,6 @@ description: > The HTTP provider discovers targets from an HTTP endpoint returning JSON, or receives webhook-based updates when push mode is enabled. --- -The HTTP provider discovers targets from an HTTP endpoint returning JSON, or receives webhook-based updates when push mode is enabled. - ## Basic Configuration ```yaml @@ -16,7 +14,6 @@ kind: TargetSource metadata: name: targetsource-1 spec: - provider: provider: http: url: http://inventory-service:8080/targets diff --git a/docs/content/docs/user-guide/targetsource/push.md b/docs/content/docs/user-guide/targetsource/push.md new file mode 100644 index 00000000..9fa35fdf --- /dev/null +++ b/docs/content/docs/user-guide/targetsource/push.md @@ -0,0 +1,113 @@ +--- +title: "Push mode" +linkTitle: "Push mode" +weight: 4 +description: > + Enables REST API interface that accepts real-time target updates. +--- + +## Basic configuration + +This CR enables the push interface with no authentication. + +```yaml +apiVersion: operator.gnmic.dev/v1alpha1 +kind: TargetSource +metadata: + name: targetsource-1 +spec: + provider: + http: + push: + enabled: true +``` + +## Spec Fields + +| Field | Type | Required | Default | Description | +|-------|------|----------|---------|-------------| +| `push` | object | No | - | Push interface config | +| `enabled` | bool | Yes | False | Whether the push interface is active | +| `auth` | object | No | - | Bearer token authentication | +| `signature` | object | No | - | HTTP body verification using HMAC | +| `algorithm` | string | No | sha512 | Algorithm for signature verification(`sha256`or`sha512`) | + +## Address + +The REST API endpoint runs on `http://cluster-address:8082/api/v1/:namespace/target-source/:name/applyTargets`. + +- `cluster-address`: Adress of your cluster, localhost during development. +- `:namespace`: Namespace the TargetSource is created in. +- `:name`: Name of the TargetSource. + +See [Push mode with webhook](/docs/examples/netbox/webhook) for an example on how to configure the URL. + +## REST API + +Refer to the [REST API documentation](/docs/advanced/rest-api-documentation/) for the expected request schema and payload format. + +Any system or script capable of sending HTTP POST requests can integrate with this interface. + +## Security + +The API supports Bearer Token authentication and X-Hook-Signature, both are optional and turned off by default. They can be used in combination and are enabled by adding them to the specification. + +An example configuration of both is documented in the [Netbox webhook](/docs/examples/netbox/webhook) example. + +### Bearer Authentication + +Bearer authentication compares a token stored in Kubernetes with the one sent in the HTTP header. The Kubernetes secret is referenced as `tokenSecretRef`. + +```yaml +apiVersion: operator.gnmic.dev/v1alpha1 +kind: TargetSource +metadata: + name: targetsource-1 +spec: + provider: + http: + push: + enabled: true + auth: + bearer: + tokenSecretRef: + name: gnmic-api-auth # secret name + key: bearer-token # secret key +``` + +This requires the [creation](https://kubernetes.ltd/docs/reference/kubectl/generated/kubectl_create/kubectl_create_secret_generic/) of an Opaque Kuberentes secret: + +- Must be in the same namespace the gNMIc controller runs in. +- `name`: refers to the secret name +- `key`: key of the secret +- Example: `kubectl create secret generic gnmic-api-auth --from-literal=bearer-token=Secret...` + +#### Authorization Header + +HTTP request must contain the Bearer token in the header in the format: + +```yaml +Authorization: Bearer Secret... +``` + +### Signature + +Signature verification requires an Opaque Kubernetes secret that stores the shared key (see Bearer Authentication). For each request, the HMAC generated from the request body and shared key must be provided in the `X-Hook-Signature` header. + +```yaml +spec: + provider: + http: + push: + enabled: true + auth: + signature: + algorithm: sha512 + secretRef: + name: gnmic-signature + key: signature +``` + +#### Reverse Proxy + +In order to have a secure setup, the HTTP post requests must be sent using TLS. The REST API interface does not support HTTPS, at least not directly. It is recommended to terminate the TLS connection at the reverse proxy and forward a plain HTTP request to the gNMIc Operator.