Handle merge api component conflicts (#539)

* Handle merge api component conflicts

Added a fixConflictingEnumAllOf() function in generator/api.ts that pre-processes the spec before merging

* Update API pages with v0.62.2

---------

Co-authored-by: netbirddev <dev@netbird.io>
This commit is contained in:
Maycon Santos
2026-01-10 12:16:22 +01:00
committed by GitHub
parent 881fbfcb49
commit aef978f63d
10 changed files with 4450 additions and 336 deletions

View File

@@ -7,13 +7,64 @@ import * as yaml from 'js-yaml';
import { merge } from 'allof-merge' import { merge } from 'allof-merge'
import RequestBodyObject = OpenAPIV3_1.RequestBodyObject; import RequestBodyObject = OpenAPIV3_1.RequestBodyObject;
// Pre-processes the spec to fix allOf with conflicting enums by merging them
function fixConflictingEnumAllOf(obj: any): any {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
return obj.map(item => fixConflictingEnumAllOf(item));
}
// Check if this object has an allOf with conflicting enums
if (obj.allOf && Array.isArray(obj.allOf)) {
const enumSchemas = obj.allOf.filter((s: any) => s.enum);
if (enumSchemas.length > 1) {
// Merge all enums into one combined enum
const combinedEnum = Array.from(new Set(enumSchemas.flatMap((s: any) => s.enum)));
const nonEnumSchemas = obj.allOf.filter((s: any) => !s.enum);
// Merge all properties from enum schemas (type, description, example, etc.)
const mergedEnumSchema: any = { enum: combinedEnum };
for (const s of enumSchemas) {
for (const key of Object.keys(s)) {
if (key !== 'enum' && !mergedEnumSchema[key]) {
mergedEnumSchema[key] = s[key];
}
}
}
if (nonEnumSchemas.length === 0) {
// All schemas had enums, replace allOf with the merged schema
const { allOf, ...rest } = obj;
return { ...rest, ...fixConflictingEnumAllOf(mergedEnumSchema) };
} else {
// Keep non-enum schemas in allOf and add merged enum schema
return {
...obj,
allOf: [...nonEnumSchemas.map((s: any) => fixConflictingEnumAllOf(s)), mergedEnumSchema]
};
}
}
}
// Recursively process all properties
const result: any = {};
for (const key of Object.keys(obj)) {
result[key] = fixConflictingEnumAllOf(obj[key]);
}
return result;
}
export default async function gen(inputFileName: string, outputDir: string) { export default async function gen(inputFileName: string, outputDir: string) {
const specRaw = fs.readFileSync(inputFileName, 'utf8') const specRaw = fs.readFileSync(inputFileName, 'utf8')
const specYaml = yaml.load(specRaw); const specYaml = yaml.load(specRaw);
const fixedSpec = fixConflictingEnumAllOf(specYaml);
const onMergeError = (msg) => { const onMergeError = (msg) => {
throw new Error(msg) throw new Error(msg)
} }
const merged = merge(specYaml, { onMergeError }) const merged = merge(fixedSpec, { onMergeError })
const spec = merged as OpenAPIV3.Document const spec = merged as OpenAPIV3.Document

View File

@@ -180,13 +180,16 @@ echo $response;
"network_range": "100.64.0.0/16", "network_range": "100.64.0.0/16",
"extra": { "extra": {
"peer_approval_enabled": true, "peer_approval_enabled": true,
"user_approval_required": false,
"network_traffic_logs_enabled": true, "network_traffic_logs_enabled": true,
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"ch8i4ug6lnn4g9hqv7m0" "ch8i4ug6lnn4g9hqv7m0"
], ],
"network_traffic_packet_counter_enabled": true "network_traffic_packet_counter_enabled": true
}, },
"lazy_connection_enabled": true "lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
}, },
"domain": "netbird.io", "domain": "netbird.io",
"domain_category": "private", "domain_category": "private",
@@ -220,13 +223,16 @@ echo $response;
"network_range": "string", "network_range": "string",
"extra": { "extra": {
"peer_approval_enabled": "boolean", "peer_approval_enabled": "boolean",
"user_approval_required": "boolean",
"network_traffic_logs_enabled": "boolean", "network_traffic_logs_enabled": "boolean",
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"string" "string"
], ],
"network_traffic_packet_counter_enabled": "boolean" "network_traffic_packet_counter_enabled": "boolean"
}, },
"lazy_connection_enabled": "boolean" "lazy_connection_enabled": "boolean",
"auto_update_version": "string",
"embedded_idp_enabled": "boolean"
}, },
"domain": "string", "domain": "string",
"domain_category": "string", "domain_category": "string",
@@ -504,6 +510,11 @@ echo $response;
(Cloud only) Enables or disables peer approval globally. If enabled, all peers added will be in pending state until approved by an admin. (Cloud only) Enables or disables peer approval globally. If enabled, all peers added will be in pending state until approved by an admin.
</Property>
<Property name="user_approval_required" type="boolean" required={true}>
Enables manual approval for new users joining via domain matching. When enabled, users are blocked with pending approval status until explicitly approved by an admin.
</Property> </Property>
<Property name="network_traffic_logs_enabled" type="boolean" required={true}> <Property name="network_traffic_logs_enabled" type="boolean" required={true}>
@@ -530,6 +541,16 @@ echo $response;
Enables or disables experimental lazy connection Enables or disables experimental lazy connection
</Property>
<Property name="auto_update_version" type="string" required={false}>
Set Clients auto-update version. "latest", "disabled", or a specific version (e.g "0.50.1")
</Property>
<Property name="embedded_idp_enabled" type="boolean" required={false}>
Indicates whether the embedded identity provider (Dex) is enabled for this account. This is a read-only field.
</Property> </Property>
</Properties> </Properties>
@@ -589,13 +610,16 @@ curl -X PUT https://api.netbird.io/api/accounts/{accountId} \
"network_range": "100.64.0.0/16", "network_range": "100.64.0.0/16",
"extra": { "extra": {
"peer_approval_enabled": true, "peer_approval_enabled": true,
"user_approval_required": false,
"network_traffic_logs_enabled": true, "network_traffic_logs_enabled": true,
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"ch8i4ug6lnn4g9hqv7m0" "ch8i4ug6lnn4g9hqv7m0"
], ],
"network_traffic_packet_counter_enabled": true "network_traffic_packet_counter_enabled": true
}, },
"lazy_connection_enabled": true "lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
}, },
"onboarding": { "onboarding": {
"signup_form_pending": true, "signup_form_pending": true,
@@ -624,13 +648,16 @@ let data = JSON.stringify({
"network_range": "100.64.0.0/16", "network_range": "100.64.0.0/16",
"extra": { "extra": {
"peer_approval_enabled": true, "peer_approval_enabled": true,
"user_approval_required": false,
"network_traffic_logs_enabled": true, "network_traffic_logs_enabled": true,
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"ch8i4ug6lnn4g9hqv7m0" "ch8i4ug6lnn4g9hqv7m0"
], ],
"network_traffic_packet_counter_enabled": true "network_traffic_packet_counter_enabled": true
}, },
"lazy_connection_enabled": true "lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
}, },
"onboarding": { "onboarding": {
"signup_form_pending": true, "signup_form_pending": true,
@@ -681,13 +708,16 @@ payload = json.dumps({
"network_range": "100.64.0.0/16", "network_range": "100.64.0.0/16",
"extra": { "extra": {
"peer_approval_enabled": true, "peer_approval_enabled": true,
"user_approval_required": false,
"network_traffic_logs_enabled": true, "network_traffic_logs_enabled": true,
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"ch8i4ug6lnn4g9hqv7m0" "ch8i4ug6lnn4g9hqv7m0"
], ],
"network_traffic_packet_counter_enabled": true "network_traffic_packet_counter_enabled": true
}, },
"lazy_connection_enabled": true "lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
}, },
"onboarding": { "onboarding": {
"signup_form_pending": true, "signup_form_pending": true,
@@ -738,13 +768,16 @@ func main() {
"network_range": "100.64.0.0/16", "network_range": "100.64.0.0/16",
"extra": { "extra": {
"peer_approval_enabled": true, "peer_approval_enabled": true,
"user_approval_required": false,
"network_traffic_logs_enabled": true, "network_traffic_logs_enabled": true,
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"ch8i4ug6lnn4g9hqv7m0" "ch8i4ug6lnn4g9hqv7m0"
], ],
"network_traffic_packet_counter_enabled": true "network_traffic_packet_counter_enabled": true
}, },
"lazy_connection_enabled": true "lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
}, },
"onboarding": { "onboarding": {
"signup_form_pending": true, "signup_form_pending": true,
@@ -813,13 +846,16 @@ request.body = JSON.dump({
"network_range": "100.64.0.0/16", "network_range": "100.64.0.0/16",
"extra": { "extra": {
"peer_approval_enabled": true, "peer_approval_enabled": true,
"user_approval_required": false,
"network_traffic_logs_enabled": true, "network_traffic_logs_enabled": true,
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"ch8i4ug6lnn4g9hqv7m0" "ch8i4ug6lnn4g9hqv7m0"
], ],
"network_traffic_packet_counter_enabled": true "network_traffic_packet_counter_enabled": true
}, },
"lazy_connection_enabled": true "lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
}, },
"onboarding": { "onboarding": {
"signup_form_pending": true, "signup_form_pending": true,
@@ -852,13 +888,16 @@ RequestBody body = RequestBody.create(mediaType, '{
"network_range": "100.64.0.0/16", "network_range": "100.64.0.0/16",
"extra": { "extra": {
"peer_approval_enabled": true, "peer_approval_enabled": true,
"user_approval_required": false,
"network_traffic_logs_enabled": true, "network_traffic_logs_enabled": true,
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"ch8i4ug6lnn4g9hqv7m0" "ch8i4ug6lnn4g9hqv7m0"
], ],
"network_traffic_packet_counter_enabled": true "network_traffic_packet_counter_enabled": true
}, },
"lazy_connection_enabled": true "lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
}, },
"onboarding": { "onboarding": {
"signup_form_pending": true, "signup_form_pending": true,
@@ -907,13 +946,16 @@ curl_setopt_array($curl, array(
"network_range": "100.64.0.0/16", "network_range": "100.64.0.0/16",
"extra": { "extra": {
"peer_approval_enabled": true, "peer_approval_enabled": true,
"user_approval_required": false,
"network_traffic_logs_enabled": true, "network_traffic_logs_enabled": true,
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"ch8i4ug6lnn4g9hqv7m0" "ch8i4ug6lnn4g9hqv7m0"
], ],
"network_traffic_packet_counter_enabled": true "network_traffic_packet_counter_enabled": true
}, },
"lazy_connection_enabled": true "lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
}, },
"onboarding": { "onboarding": {
"signup_form_pending": true, "signup_form_pending": true,
@@ -957,13 +999,16 @@ echo $response;
"network_range": "100.64.0.0/16", "network_range": "100.64.0.0/16",
"extra": { "extra": {
"peer_approval_enabled": true, "peer_approval_enabled": true,
"user_approval_required": false,
"network_traffic_logs_enabled": true, "network_traffic_logs_enabled": true,
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"ch8i4ug6lnn4g9hqv7m0" "ch8i4ug6lnn4g9hqv7m0"
], ],
"network_traffic_packet_counter_enabled": true "network_traffic_packet_counter_enabled": true
}, },
"lazy_connection_enabled": true "lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
}, },
"domain": "netbird.io", "domain": "netbird.io",
"domain_category": "private", "domain_category": "private",
@@ -995,13 +1040,16 @@ echo $response;
"network_range": "string", "network_range": "string",
"extra": { "extra": {
"peer_approval_enabled": "boolean", "peer_approval_enabled": "boolean",
"user_approval_required": "boolean",
"network_traffic_logs_enabled": "boolean", "network_traffic_logs_enabled": "boolean",
"network_traffic_logs_groups": [ "network_traffic_logs_groups": [
"string" "string"
], ],
"network_traffic_packet_counter_enabled": "boolean" "network_traffic_packet_counter_enabled": "boolean"
}, },
"lazy_connection_enabled": "boolean" "lazy_connection_enabled": "boolean",
"auto_update_version": "string",
"embedded_idp_enabled": "boolean"
}, },
"domain": "string", "domain": "string",
"domain_category": "string", "domain_category": "string",

File diff suppressed because it is too large Load Diff

View File

@@ -7,15 +7,15 @@ export const title = 'Groups'
<Row> <Row>
<Col> <Col>
Returns a list of all groups Returns a list of all groups
### Query Parameters ### Query Parameters
<Properties> <Properties>
<Property name="name" type="string" required={false}> <Property name="name" type="string" required={false}>
Filter groups by name Filter groups by name (exact match)
</Property> </Property>
</Properties> </Properties>
</Col> </Col>
<Col sticky> <Col sticky>
<CodeGroup title="Request" tag="GET" label="/api/groups"> <CodeGroup title="Request" tag="GET" label="/api/groups">
@@ -251,7 +251,7 @@ echo $response;
ID of the resource ID of the resource
</Property> </Property>
<Property name="type" type="string" required={true} enumList={["host","subnet","domain"]}> <Property name="type" type="string" required={true} enumList={["host","subnet","domain","peer"]}>
Network resource type based of the address Network resource type based of the address
@@ -811,7 +811,7 @@ echo $response;
ID of the resource ID of the resource
</Property> </Property>
<Property name="type" type="string" required={true} enumList={["host","subnet","domain"]}> <Property name="type" type="string" required={true} enumList={["host","subnet","domain","peer"]}>
Network resource type based of the address Network resource type based of the address

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,418 @@
export const title = 'Instance'
## Get Instance Status {{ tag: 'GET' , label: '/api/instance' }}
<Row>
<Col>
Returns the instance status including whether initial setup is required. This endpoint does not require authentication.
</Col>
<Col sticky>
<CodeGroup title="Request" tag="GET" label="/api/instance">
```bash {{ title: 'cURL' }}
curl -X GET https://api.netbird.io/api/instance \
-H 'Accept: application/json' \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'get',
maxBodyLength: Infinity,
url: '/api/instance',
headers: {
'Accept': 'application/json',
'Authorization': 'Token <TOKEN>'
}
};
axios(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
```
```python
import requests
import json
url = "https://api.netbird.io/api/instance"
headers = {
'Accept': 'application/json',
'Authorization': 'Token <TOKEN>'
}
response = requests.request("GET", url, headers=headers)
print(response.text)
```
```go
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://api.netbird.io/api/instance"
method := "GET"
client := &http.Client {
}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
return
{
req.Header.Add("Accept", "application/json")
req.Header.Add("Authorization", "Token <TOKEN>")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
```
```ruby
require "uri"
require "json"
require "net/http"
url = URI("https://api.netbird.io/api/instance")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Accept"] = "application/json"
request["Authorization"] = "Token <TOKEN>"
response = https.request(request)
puts response.read_body
```
```java
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
Request request = new Request.Builder()
.url("https://api.netbird.io/api/instance")
.method("GET")
.addHeader("Accept", "application/json")
.addHeader("Authorization: Token <TOKEN>")
.build();
Response response = client.newCall(request).execute();
```
```php
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.netbird.io/api/instance',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Authorization: Token <TOKEN>'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
```
</CodeGroup>
<CodeGroup title="Response">
```json {{ title: 'Example' }}
{
"setup_required": true
}
```
```json {{ title: 'Schema' }}
{
"setup_required": "boolean"
}
```
</CodeGroup>
</Col>
</Row>
---
## Setup Instance {{ tag: 'POST' , label: '/api/setup' }}
<Row>
<Col>
Creates the initial admin user for the instance. This endpoint does not require authentication but only works when setup is required (no accounts exist and embedded IDP is enabled).
### Request-Body Parameters
<Properties><Property name="email" type="string" required={true}>
Email address for the admin user
</Property>
<Property name="password" type="string" required={true} minLen={8}>
Password for the admin user (minimum 8 characters)
</Property>
<Property name="name" type="string" required={true}>
Display name for the admin user (defaults to email if not provided)
</Property>
</Properties>
</Col>
<Col sticky>
<CodeGroup title="Request" tag="POST" label="/api/setup">
```bash {{ title: 'cURL' }}
curl -X POST https://api.netbird.io/api/setup \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Authorization: Token <TOKEN>' \
--data-raw '{
"email": "admin@example.com",
"password": "securepassword123",
"name": "Admin User"
}'
```
```js
const axios = require('axios');
let data = JSON.stringify({
"email": "admin@example.com",
"password": "securepassword123",
"name": "Admin User"
});
let config = {
method: 'post',
maxBodyLength: Infinity,
url: '/api/setup',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Token <TOKEN>'
},
data : data
};
axios(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
```
```python
import requests
import json
url = "https://api.netbird.io/api/setup"
payload = json.dumps({
"email": "admin@example.com",
"password": "securepassword123",
"name": "Admin User"
})
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Token <TOKEN>'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
```
```go
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://api.netbird.io/api/setup"
method := "POST"
payload := strings.NewReader(`{
"email": "admin@example.com",
"password": "securepassword123",
"name": "Admin User"
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
{
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
req.Header.Add("Authorization", "Token <TOKEN>")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
```
```ruby
require "uri"
require "json"
require "net/http"
url = URI("https://api.netbird.io/api/setup")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["Accept"] = "application/json"
request["Authorization"] = "Token <TOKEN>"
request.body = JSON.dump({
"email": "admin@example.com",
"password": "securepassword123",
"name": "Admin User"
})
response = https.request(request)
puts response.read_body
```
```java
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, '{
"email": "admin@example.com",
"password": "securepassword123",
"name": "Admin User"
}');
Request request = new Request.Builder()
.url("https://api.netbird.io/api/setup")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.addHeader("Authorization: Token <TOKEN>")
.build();
Response response = client.newCall(request).execute();
```
```php
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.netbird.io/api/setup',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{
"email": "admin@example.com",
"password": "securepassword123",
"name": "Admin User"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Accept: application/json',
'Authorization: Token <TOKEN>'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
```
</CodeGroup>
<CodeGroup title="Response">
```json {{ title: 'Example' }}
{
"user_id": "abc123def456",
"email": "admin@example.com"
}
```
```json {{ title: 'Schema' }}
{
"user_id": "string",
"email": "string"
}
```
</CodeGroup>
</Col>
</Row>
---

View File

@@ -176,6 +176,7 @@ echo $response;
{ {
"id": "chacbco6lnnbn6cg5s90", "id": "chacbco6lnnbn6cg5s90",
"name": "stage-host-1", "name": "stage-host-1",
"created_at": "2023-05-05T09:00:35.477782Z",
"ip": "10.64.0.1", "ip": "10.64.0.1",
"connection_ip": "35.64.0.1", "connection_ip": "35.64.0.1",
"connected": true, "connected": true,
@@ -203,6 +204,10 @@ echo $response;
"last_login": "2023-05-05T09:00:35.477782Z", "last_login": "2023-05-05T09:00:35.477782Z",
"inactivity_expiration_enabled": false, "inactivity_expiration_enabled": false,
"approval_required": true, "approval_required": true,
"disapproval_reason": {
"description": "(Cloud only) Reason why the peer requires approval",
"type": "string"
},
"country_code": "DE", "country_code": "DE",
"city_name": "Berlin", "city_name": "Berlin",
"serial_number": "C02XJ0J0JGH7", "serial_number": "C02XJ0J0JGH7",
@@ -210,6 +215,18 @@ echo $response;
"stage-host-1" "stage-host-1"
], ],
"ephemeral": false, "ephemeral": false,
"local_flags": {
"rosenpass_enabled": true,
"rosenpass_permissive": false,
"server_ssh_allowed": true,
"disable_client_routes": false,
"disable_server_routes": false,
"disable_dns": false,
"disable_firewall": false,
"block_lan_access": false,
"block_inbound": false,
"lazy_connection_enabled": false
},
"accessible_peers_count": 5 "accessible_peers_count": 5
} }
] ]
@@ -219,6 +236,7 @@ echo $response;
{ {
"id": "string", "id": "string",
"name": "string", "name": "string",
"created_at": "string",
"ip": "string", "ip": "string",
"connection_ip": "string", "connection_ip": "string",
"connected": "boolean", "connected": "boolean",
@@ -246,6 +264,7 @@ echo $response;
"last_login": "string", "last_login": "string",
"inactivity_expiration_enabled": "boolean", "inactivity_expiration_enabled": "boolean",
"approval_required": "boolean", "approval_required": "boolean",
"disapproval_reason": "string",
"country_code": "string", "country_code": "string",
"city_name": "string", "city_name": "string",
"serial_number": "string", "serial_number": "string",
@@ -253,6 +272,18 @@ echo $response;
"string" "string"
], ],
"ephemeral": "boolean", "ephemeral": "boolean",
"local_flags": {
"rosenpass_enabled": "boolean",
"rosenpass_permissive": "boolean",
"server_ssh_allowed": "boolean",
"disable_client_routes": "boolean",
"disable_server_routes": "boolean",
"disable_dns": "boolean",
"disable_firewall": "boolean",
"block_lan_access": "boolean",
"block_inbound": "boolean",
"lazy_connection_enabled": "boolean"
},
"accessible_peers_count": "integer" "accessible_peers_count": "integer"
} }
] ]
@@ -435,6 +466,7 @@ echo $response;
{ {
"id": "chacbco6lnnbn6cg5s90", "id": "chacbco6lnnbn6cg5s90",
"name": "stage-host-1", "name": "stage-host-1",
"created_at": "2023-05-05T09:00:35.477782Z",
"ip": "10.64.0.1", "ip": "10.64.0.1",
"connection_ip": "35.64.0.1", "connection_ip": "35.64.0.1",
"connected": true, "connected": true,
@@ -462,19 +494,36 @@ echo $response;
"last_login": "2023-05-05T09:00:35.477782Z", "last_login": "2023-05-05T09:00:35.477782Z",
"inactivity_expiration_enabled": false, "inactivity_expiration_enabled": false,
"approval_required": true, "approval_required": true,
"disapproval_reason": {
"description": "(Cloud only) Reason why the peer requires approval",
"type": "string"
},
"country_code": "DE", "country_code": "DE",
"city_name": "Berlin", "city_name": "Berlin",
"serial_number": "C02XJ0J0JGH7", "serial_number": "C02XJ0J0JGH7",
"extra_dns_labels": [ "extra_dns_labels": [
"stage-host-1" "stage-host-1"
], ],
"ephemeral": false "ephemeral": false,
"local_flags": {
"rosenpass_enabled": true,
"rosenpass_permissive": false,
"server_ssh_allowed": true,
"disable_client_routes": false,
"disable_server_routes": false,
"disable_dns": false,
"disable_firewall": false,
"block_lan_access": false,
"block_inbound": false,
"lazy_connection_enabled": false
}
} }
``` ```
```json {{ title: 'Schema' }} ```json {{ title: 'Schema' }}
{ {
"id": "string", "id": "string",
"name": "string", "name": "string",
"created_at": "string",
"ip": "string", "ip": "string",
"connection_ip": "string", "connection_ip": "string",
"connected": "boolean", "connected": "boolean",
@@ -502,13 +551,26 @@ echo $response;
"last_login": "string", "last_login": "string",
"inactivity_expiration_enabled": "boolean", "inactivity_expiration_enabled": "boolean",
"approval_required": "boolean", "approval_required": "boolean",
"disapproval_reason": "string",
"country_code": "string", "country_code": "string",
"city_name": "string", "city_name": "string",
"serial_number": "string", "serial_number": "string",
"extra_dns_labels": [ "extra_dns_labels": [
"string" "string"
], ],
"ephemeral": "boolean" "ephemeral": "boolean",
"local_flags": {
"rosenpass_enabled": "boolean",
"rosenpass_permissive": "boolean",
"server_ssh_allowed": "boolean",
"disable_client_routes": "boolean",
"disable_server_routes": "boolean",
"disable_dns": "boolean",
"disable_firewall": "boolean",
"block_lan_access": "boolean",
"block_inbound": "boolean",
"lazy_connection_enabled": "boolean"
}
} }
``` ```
</CodeGroup> </CodeGroup>
@@ -787,6 +849,7 @@ echo $response;
{ {
"id": "chacbco6lnnbn6cg5s90", "id": "chacbco6lnnbn6cg5s90",
"name": "stage-host-1", "name": "stage-host-1",
"created_at": "2023-05-05T09:00:35.477782Z",
"ip": "10.64.0.1", "ip": "10.64.0.1",
"connection_ip": "35.64.0.1", "connection_ip": "35.64.0.1",
"connected": true, "connected": true,
@@ -814,19 +877,36 @@ echo $response;
"last_login": "2023-05-05T09:00:35.477782Z", "last_login": "2023-05-05T09:00:35.477782Z",
"inactivity_expiration_enabled": false, "inactivity_expiration_enabled": false,
"approval_required": true, "approval_required": true,
"disapproval_reason": {
"description": "(Cloud only) Reason why the peer requires approval",
"type": "string"
},
"country_code": "DE", "country_code": "DE",
"city_name": "Berlin", "city_name": "Berlin",
"serial_number": "C02XJ0J0JGH7", "serial_number": "C02XJ0J0JGH7",
"extra_dns_labels": [ "extra_dns_labels": [
"stage-host-1" "stage-host-1"
], ],
"ephemeral": false "ephemeral": false,
"local_flags": {
"rosenpass_enabled": true,
"rosenpass_permissive": false,
"server_ssh_allowed": true,
"disable_client_routes": false,
"disable_server_routes": false,
"disable_dns": false,
"disable_firewall": false,
"block_lan_access": false,
"block_inbound": false,
"lazy_connection_enabled": false
}
} }
``` ```
```json {{ title: 'Schema' }} ```json {{ title: 'Schema' }}
{ {
"id": "string", "id": "string",
"name": "string", "name": "string",
"created_at": "string",
"ip": "string", "ip": "string",
"connection_ip": "string", "connection_ip": "string",
"connected": "boolean", "connected": "boolean",
@@ -854,13 +934,26 @@ echo $response;
"last_login": "string", "last_login": "string",
"inactivity_expiration_enabled": "boolean", "inactivity_expiration_enabled": "boolean",
"approval_required": "boolean", "approval_required": "boolean",
"disapproval_reason": "string",
"country_code": "string", "country_code": "string",
"city_name": "string", "city_name": "string",
"serial_number": "string", "serial_number": "string",
"extra_dns_labels": [ "extra_dns_labels": [
"string" "string"
], ],
"ephemeral": "boolean" "ephemeral": "boolean",
"local_flags": {
"rosenpass_enabled": "boolean",
"rosenpass_permissive": "boolean",
"server_ssh_allowed": "boolean",
"disable_client_routes": "boolean",
"disable_server_routes": "boolean",
"disable_dns": "boolean",
"disable_firewall": "boolean",
"block_lan_access": "boolean",
"block_inbound": "boolean",
"lazy_connection_enabled": "boolean"
}
} }
``` ```
</CodeGroup> </CodeGroup>
@@ -1242,3 +1335,271 @@ echo $response;
</Row> </Row>
--- ---
## Create a Temporary Access Peer {{ tag: 'POST' , label: '/api/peers/{peerId}/temporary-access' }}
<Row>
<Col>
Creates a temporary access peer that can be used to access this peer and this peer only. The temporary access peer and its access policies will be automatically deleted after it disconnects.
### Path Parameters
<Properties>
<Property name="peerId" type="string" required={true}>
The unique identifier of a peer
</Property>
</Properties>
### Request-Body Parameters
<Properties><Property name="name" type="string" required={true}>
Peer's hostname
</Property>
<Property name="wg_pub_key" type="string" required={true}>
Peer's WireGuard public key
</Property>
<Property name="rules" type="string[]" required={true}>
List of temporary access rules
</Property>
</Properties>
</Col>
<Col sticky>
<CodeGroup title="Request" tag="POST" label="/api/peers/{peerId}/temporary-access">
```bash {{ title: 'cURL' }}
curl -X POST https://api.netbird.io/api/peers/{peerId}/temporary-access \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Authorization: Token <TOKEN>' \
--data-raw '{
"name": "temp-host-1",
"wg_pub_key": "n0r3pL4c3h0ld3rK3y==",
"rules": [
"tcp/80"
]
}'
```
```js
const axios = require('axios');
let data = JSON.stringify({
"name": "temp-host-1",
"wg_pub_key": "n0r3pL4c3h0ld3rK3y==",
"rules": [
"tcp/80"
]
});
let config = {
method: 'post',
maxBodyLength: Infinity,
url: '/api/peers/{peerId}/temporary-access',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Token <TOKEN>'
},
data : data
};
axios(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
```
```python
import requests
import json
url = "https://api.netbird.io/api/peers/{peerId}/temporary-access"
payload = json.dumps({
"name": "temp-host-1",
"wg_pub_key": "n0r3pL4c3h0ld3rK3y==",
"rules": [
"tcp/80"
]
})
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Token <TOKEN>'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
```
```go
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://api.netbird.io/api/peers/{peerId}/temporary-access"
method := "POST"
payload := strings.NewReader(`{
"name": "temp-host-1",
"wg_pub_key": "n0r3pL4c3h0ld3rK3y==",
"rules": [
"tcp/80"
]
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
{
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
req.Header.Add("Authorization", "Token <TOKEN>")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
```
```ruby
require "uri"
require "json"
require "net/http"
url = URI("https://api.netbird.io/api/peers/{peerId}/temporary-access")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["Accept"] = "application/json"
request["Authorization"] = "Token <TOKEN>"
request.body = JSON.dump({
"name": "temp-host-1",
"wg_pub_key": "n0r3pL4c3h0ld3rK3y==",
"rules": [
"tcp/80"
]
})
response = https.request(request)
puts response.read_body
```
```java
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, '{
"name": "temp-host-1",
"wg_pub_key": "n0r3pL4c3h0ld3rK3y==",
"rules": [
"tcp/80"
]
}');
Request request = new Request.Builder()
.url("https://api.netbird.io/api/peers/{peerId}/temporary-access")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.addHeader("Authorization: Token <TOKEN>")
.build();
Response response = client.newCall(request).execute();
```
```php
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.netbird.io/api/peers/{peerId}/temporary-access',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{
"name": "temp-host-1",
"wg_pub_key": "n0r3pL4c3h0ld3rK3y==",
"rules": [
"tcp/80"
]
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Accept: application/json',
'Authorization: Token <TOKEN>'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
```
</CodeGroup>
<CodeGroup title="Response">
```json {{ title: 'Example' }}
{
"name": "temp-host-1",
"id": "chacbco6lnnbn6cg5s90",
"rules": [
"tcp/80"
]
}
```
```json {{ title: 'Schema' }}
{
"name": "string",
"id": "string",
"rules": [
"string"
]
}
```
</CodeGroup>
</Col>
</Row>
---

View File

@@ -186,6 +186,13 @@ echo $response;
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
{ {
@@ -245,6 +252,13 @@ echo $response;
"end": "integer" "end": "integer"
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"string"
]
},
"id": "string", "id": "string",
"sources": [ "sources": [
{ {
@@ -345,7 +359,7 @@ echo $response;
Define if the rule is applicable in both directions, sources, and destinations. Define if the rule is applicable in both directions, sources, and destinations.
</Property> </Property>
<Property name="protocol" type="string" required={true} enumList={["all","tcp","udp","icmp"]}> <Property name="protocol" type="string" required={true} enumList={["all","tcp","udp","icmp","netbird-ssh"]}>
Policy rule type of the traffic Policy rule type of the traffic
@@ -376,6 +390,11 @@ echo $response;
</Properties> </Properties>
</details> </details>
</Property>
<Property name="authorized_groups" type="object" required={false}>
Map of user group ids to a list of local users
</Property> </Property>
<Property name="id" type="string" required={false}> <Property name="id" type="string" required={false}>
@@ -398,7 +417,7 @@ echo $response;
ID of the resource ID of the resource
</Property> </Property>
<Property name="type" type="string" required={true} enumList={["host","subnet","domain"]}> <Property name="type" type="string" required={true} enumList={["host","subnet","domain","peer"]}>
Network resource type based of the address Network resource type based of the address
@@ -425,7 +444,7 @@ echo $response;
ID of the resource ID of the resource
</Property> </Property>
<Property name="type" type="string" required={true} enumList={["host","subnet","domain"]}> <Property name="type" type="string" required={true} enumList={["host","subnet","domain","peer"]}>
Network resource type based of the address Network resource type based of the address
@@ -478,6 +497,13 @@ curl -X POST https://api.netbird.io/api/policies \
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -524,6 +550,13 @@ let data = JSON.stringify({
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -592,6 +625,13 @@ payload = json.dumps({
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -660,6 +700,13 @@ func main() {
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -746,6 +793,13 @@ request.body = JSON.dump({
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -796,6 +850,13 @@ RequestBody body = RequestBody.create(mediaType, '{
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -862,6 +923,13 @@ curl_setopt_array($curl, array(
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -923,6 +991,13 @@ echo $response;
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
{ {
@@ -980,6 +1055,13 @@ echo $response;
"end": "integer" "end": "integer"
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"string"
]
},
"id": "string", "id": "string",
"sources": [ "sources": [
{ {
@@ -1211,6 +1293,13 @@ echo $response;
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
{ {
@@ -1268,6 +1357,13 @@ echo $response;
"end": "integer" "end": "integer"
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"string"
]
},
"id": "string", "id": "string",
"sources": [ "sources": [
{ {
@@ -1375,7 +1471,7 @@ echo $response;
Define if the rule is applicable in both directions, sources, and destinations. Define if the rule is applicable in both directions, sources, and destinations.
</Property> </Property>
<Property name="protocol" type="string" required={true} enumList={["all","tcp","udp","icmp"]}> <Property name="protocol" type="string" required={true} enumList={["all","tcp","udp","icmp","netbird-ssh"]}>
Policy rule type of the traffic Policy rule type of the traffic
@@ -1406,6 +1502,11 @@ echo $response;
</Properties> </Properties>
</details> </details>
</Property>
<Property name="authorized_groups" type="object" required={false}>
Map of user group ids to a list of local users
</Property> </Property>
<Property name="id" type="string" required={false}> <Property name="id" type="string" required={false}>
@@ -1428,7 +1529,7 @@ echo $response;
ID of the resource ID of the resource
</Property> </Property>
<Property name="type" type="string" required={true} enumList={["host","subnet","domain"]}> <Property name="type" type="string" required={true} enumList={["host","subnet","domain","peer"]}>
Network resource type based of the address Network resource type based of the address
@@ -1455,7 +1556,7 @@ echo $response;
ID of the resource ID of the resource
</Property> </Property>
<Property name="type" type="string" required={true} enumList={["host","subnet","domain"]}> <Property name="type" type="string" required={true} enumList={["host","subnet","domain","peer"]}>
Network resource type based of the address Network resource type based of the address
@@ -1508,6 +1609,13 @@ curl -X PUT https://api.netbird.io/api/policies/{policyId} \
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -1554,6 +1662,13 @@ let data = JSON.stringify({
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -1622,6 +1737,13 @@ payload = json.dumps({
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -1690,6 +1812,13 @@ func main() {
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -1776,6 +1905,13 @@ request.body = JSON.dump({
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -1826,6 +1962,13 @@ RequestBody body = RequestBody.create(mediaType, '{
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -1892,6 +2035,13 @@ curl_setopt_array($curl, array(
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
"ch8i4ug6lnn4g9hqv797" "ch8i4ug6lnn4g9hqv797"
@@ -1953,6 +2103,13 @@ echo $response;
"end": 320 "end": 320
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"group1"
]
},
"id": "ch8i4ug6lnn4g9hqv7mg", "id": "ch8i4ug6lnn4g9hqv7mg",
"sources": [ "sources": [
{ {
@@ -2010,6 +2167,13 @@ echo $response;
"end": "integer" "end": "integer"
} }
], ],
"authorized_groups": {
"description": "Map of user group ids to a list of local users",
"type": "object",
"additionalProperties": [
"string"
]
},
"id": "string", "id": "string",
"sources": [ "sources": [
{ {

View File

@@ -183,7 +183,8 @@ echo $response;
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
} }
] ]
``` ```
@@ -211,7 +212,8 @@ echo $response;
"keep_route": "boolean", "keep_route": "boolean",
"access_control_groups": [ "access_control_groups": [
"string" "string"
] ],
"skip_auto_apply": "boolean"
} }
] ]
``` ```
@@ -291,6 +293,11 @@ echo $response;
Access control group identifier associated with route. Access control group identifier associated with route.
</Property>
<Property name="skip_auto_apply" type="boolean" required={false}>
Indicate if this exit node route (0.0.0.0/0) should skip auto-application for client routing
</Property> </Property>
</Properties> </Properties>
@@ -324,7 +331,8 @@ curl -X POST https://api.netbird.io/api/routes \
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}' }'
``` ```
@@ -350,7 +358,8 @@ let data = JSON.stringify({
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}); });
let config = { let config = {
method: 'post', method: 'post',
@@ -398,7 +407,8 @@ payload = json.dumps({
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}) })
headers = { headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -446,7 +456,8 @@ func main() {
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}`) }`)
client := &http.Client { client := &http.Client {
} }
@@ -512,7 +523,8 @@ request.body = JSON.dump({
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}) })
response = https.request(request) response = https.request(request)
puts response.read_body puts response.read_body
@@ -542,7 +554,8 @@ RequestBody body = RequestBody.create(mediaType, '{
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}'); }');
Request request = new Request.Builder() Request request = new Request.Builder()
.url("https://api.netbird.io/api/routes") .url("https://api.netbird.io/api/routes")
@@ -588,7 +601,8 @@ curl_setopt_array($curl, array(
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}', }',
CURLOPT_HTTPHEADER => array( CURLOPT_HTTPHEADER => array(
'Content-Type: application/json', 'Content-Type: application/json',
@@ -630,7 +644,8 @@ echo $response;
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
} }
``` ```
```json {{ title: 'Schema' }} ```json {{ title: 'Schema' }}
@@ -656,7 +671,8 @@ echo $response;
"keep_route": "boolean", "keep_route": "boolean",
"access_control_groups": [ "access_control_groups": [
"string" "string"
] ],
"skip_auto_apply": "boolean"
} }
``` ```
</CodeGroup> </CodeGroup>
@@ -856,7 +872,8 @@ echo $response;
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
} }
``` ```
```json {{ title: 'Schema' }} ```json {{ title: 'Schema' }}
@@ -882,7 +899,8 @@ echo $response;
"keep_route": "boolean", "keep_route": "boolean",
"access_control_groups": [ "access_control_groups": [
"string" "string"
] ],
"skip_auto_apply": "boolean"
} }
``` ```
</CodeGroup> </CodeGroup>
@@ -969,6 +987,11 @@ echo $response;
Access control group identifier associated with route. Access control group identifier associated with route.
</Property>
<Property name="skip_auto_apply" type="boolean" required={false}>
Indicate if this exit node route (0.0.0.0/0) should skip auto-application for client routing
</Property> </Property>
</Properties> </Properties>
@@ -1002,7 +1025,8 @@ curl -X PUT https://api.netbird.io/api/routes/{routeId} \
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}' }'
``` ```
@@ -1028,7 +1052,8 @@ let data = JSON.stringify({
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}); });
let config = { let config = {
method: 'put', method: 'put',
@@ -1076,7 +1101,8 @@ payload = json.dumps({
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}) })
headers = { headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -1124,7 +1150,8 @@ func main() {
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}`) }`)
client := &http.Client { client := &http.Client {
} }
@@ -1190,7 +1217,8 @@ request.body = JSON.dump({
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}) })
response = https.request(request) response = https.request(request)
puts response.read_body puts response.read_body
@@ -1220,7 +1248,8 @@ RequestBody body = RequestBody.create(mediaType, '{
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}'); }');
Request request = new Request.Builder() Request request = new Request.Builder()
.url("https://api.netbird.io/api/routes/{routeId}") .url("https://api.netbird.io/api/routes/{routeId}")
@@ -1266,7 +1295,8 @@ curl_setopt_array($curl, array(
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
}', }',
CURLOPT_HTTPHEADER => array( CURLOPT_HTTPHEADER => array(
'Content-Type: application/json', 'Content-Type: application/json',
@@ -1308,7 +1338,8 @@ echo $response;
"keep_route": true, "keep_route": true,
"access_control_groups": [ "access_control_groups": [
"chacbco6lnnbn6cg5s91" "chacbco6lnnbn6cg5s91"
] ],
"skip_auto_apply": false
} }
``` ```
```json {{ title: 'Schema' }} ```json {{ title: 'Schema' }}
@@ -1334,7 +1365,8 @@ echo $response;
"keep_route": "boolean", "keep_route": "boolean",
"access_control_groups": [ "access_control_groups": [
"string" "string"
] ],
"skip_auto_apply": "boolean"
} }
``` ```
</CodeGroup> </CodeGroup>

View File

@@ -172,6 +172,7 @@ echo $response;
{ {
"id": "google-oauth2|277474792786460067937", "id": "google-oauth2|277474792786460067937",
"email": "demo@netbird.io", "email": "demo@netbird.io",
"password": "super_secure_password",
"name": "Tom Schulz", "name": "Tom Schulz",
"role": "admin", "role": "admin",
"status": "active", "status": "active",
@@ -182,7 +183,9 @@ echo $response;
"is_current": true, "is_current": true,
"is_service_user": false, "is_service_user": false,
"is_blocked": false, "is_blocked": false,
"pending_approval": false,
"issued": "api", "issued": "api",
"idp_id": "okta-abc123",
"permissions": { "permissions": {
"is_restricted": { "is_restricted": {
"type": "boolean", "type": "boolean",
@@ -211,6 +214,7 @@ echo $response;
{ {
"id": "string", "id": "string",
"email": "string", "email": "string",
"password": "string",
"name": "string", "name": "string",
"role": "string", "role": "string",
"status": "string", "status": "string",
@@ -221,7 +225,9 @@ echo $response;
"is_current": "boolean", "is_current": "boolean",
"is_service_user": "boolean", "is_service_user": "boolean",
"is_blocked": "boolean", "is_blocked": "boolean",
"pending_approval": "boolean",
"issued": "string", "issued": "string",
"idp_id": "string",
"permissions": { "permissions": {
"is_restricted": "boolean", "is_restricted": "boolean",
"modules": { "modules": {
@@ -521,6 +527,7 @@ echo $response;
{ {
"id": "google-oauth2|277474792786460067937", "id": "google-oauth2|277474792786460067937",
"email": "demo@netbird.io", "email": "demo@netbird.io",
"password": "super_secure_password",
"name": "Tom Schulz", "name": "Tom Schulz",
"role": "admin", "role": "admin",
"status": "active", "status": "active",
@@ -531,7 +538,9 @@ echo $response;
"is_current": true, "is_current": true,
"is_service_user": false, "is_service_user": false,
"is_blocked": false, "is_blocked": false,
"pending_approval": false,
"issued": "api", "issued": "api",
"idp_id": "okta-abc123",
"permissions": { "permissions": {
"is_restricted": { "is_restricted": {
"type": "boolean", "type": "boolean",
@@ -558,6 +567,7 @@ echo $response;
{ {
"id": "string", "id": "string",
"email": "string", "email": "string",
"password": "string",
"name": "string", "name": "string",
"role": "string", "role": "string",
"status": "string", "status": "string",
@@ -568,7 +578,9 @@ echo $response;
"is_current": "boolean", "is_current": "boolean",
"is_service_user": "boolean", "is_service_user": "boolean",
"is_blocked": "boolean", "is_blocked": "boolean",
"pending_approval": "boolean",
"issued": "string", "issued": "string",
"idp_id": "string",
"permissions": { "permissions": {
"is_restricted": "boolean", "is_restricted": "boolean",
"modules": { "modules": {
@@ -851,6 +863,7 @@ echo $response;
{ {
"id": "google-oauth2|277474792786460067937", "id": "google-oauth2|277474792786460067937",
"email": "demo@netbird.io", "email": "demo@netbird.io",
"password": "super_secure_password",
"name": "Tom Schulz", "name": "Tom Schulz",
"role": "admin", "role": "admin",
"status": "active", "status": "active",
@@ -861,7 +874,9 @@ echo $response;
"is_current": true, "is_current": true,
"is_service_user": false, "is_service_user": false,
"is_blocked": false, "is_blocked": false,
"pending_approval": false,
"issued": "api", "issued": "api",
"idp_id": "okta-abc123",
"permissions": { "permissions": {
"is_restricted": { "is_restricted": {
"type": "boolean", "type": "boolean",
@@ -888,6 +903,7 @@ echo $response;
{ {
"id": "string", "id": "string",
"email": "string", "email": "string",
"password": "string",
"name": "string", "name": "string",
"role": "string", "role": "string",
"status": "string", "status": "string",
@@ -898,7 +914,9 @@ echo $response;
"is_current": "boolean", "is_current": "boolean",
"is_service_user": "boolean", "is_service_user": "boolean",
"is_blocked": "boolean", "is_blocked": "boolean",
"pending_approval": "boolean",
"issued": "string", "issued": "string",
"idp_id": "string",
"permissions": { "permissions": {
"is_restricted": "boolean", "is_restricted": "boolean",
"modules": { "modules": {
@@ -1264,6 +1282,430 @@ echo $response;
--- ---
## Approve user {{ tag: 'POST' , label: '/api/users/{userId}/approve' }}
<Row>
<Col>
Approve a user that is pending approval
### Path Parameters
<Properties>
<Property name="userId" type="string" required={true}>
The unique identifier of a user
</Property>
</Properties>
</Col>
<Col sticky>
<CodeGroup title="Request" tag="POST" label="/api/users/{userId}/approve">
```bash {{ title: 'cURL' }}
curl -X POST https://api.netbird.io/api/users/{userId}/approve \
-H 'Accept: application/json' \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'post',
maxBodyLength: Infinity,
url: '/api/users/{userId}/approve',
headers: {
'Accept': 'application/json',
'Authorization': 'Token <TOKEN>'
}
};
axios(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
```
```python
import requests
import json
url = "https://api.netbird.io/api/users/{userId}/approve"
headers = {
'Accept': 'application/json',
'Authorization': 'Token <TOKEN>'
}
response = requests.request("POST", url, headers=headers)
print(response.text)
```
```go
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://api.netbird.io/api/users/{userId}/approve"
method := "POST"
client := &http.Client {
}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
return
{
req.Header.Add("Accept", "application/json")
req.Header.Add("Authorization", "Token <TOKEN>")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
```
```ruby
require "uri"
require "json"
require "net/http"
url = URI("https://api.netbird.io/api/users/{userId}/approve")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Accept"] = "application/json"
request["Authorization"] = "Token <TOKEN>"
response = https.request(request)
puts response.read_body
```
```java
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
Request request = new Request.Builder()
.url("https://api.netbird.io/api/users/{userId}/approve")
.method("POST")
.addHeader("Accept", "application/json")
.addHeader("Authorization: Token <TOKEN>")
.build();
Response response = client.newCall(request).execute();
```
```php
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.netbird.io/api/users/{userId}/approve',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Authorization: Token <TOKEN>'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
```
</CodeGroup>
<CodeGroup title="Response">
```json {{ title: 'Example' }}
{
"id": "google-oauth2|277474792786460067937",
"email": "demo@netbird.io",
"password": "super_secure_password",
"name": "Tom Schulz",
"role": "admin",
"status": "active",
"last_login": "2023-05-05T09:00:35.477782Z",
"auto_groups": [
"ch8i4ug6lnn4g9hqv7m0"
],
"is_current": true,
"is_service_user": false,
"is_blocked": false,
"pending_approval": false,
"issued": "api",
"idp_id": "okta-abc123",
"permissions": {
"is_restricted": {
"type": "boolean",
"description": "Indicates whether this User's Peers view is restricted"
},
"modules": {
"networks": {
"read": true,
"create": false,
"update": false,
"delete": false
},
"peers": {
"read": false,
"create": false,
"update": false,
"delete": false
}
}
}
}
```
```json {{ title: 'Schema' }}
{
"id": "string",
"email": "string",
"password": "string",
"name": "string",
"role": "string",
"status": "string",
"last_login": "string",
"auto_groups": [
"string"
],
"is_current": "boolean",
"is_service_user": "boolean",
"is_blocked": "boolean",
"pending_approval": "boolean",
"issued": "string",
"idp_id": "string",
"permissions": {
"is_restricted": "boolean",
"modules": {
"type": "object",
"additionalProperties": {
"type": "object",
"additionalProperties": "boolean",
"propertyNames": "string"
},
"propertyNames": "string",
"example": {
"networks": {
"read": true,
"create": false,
"update": false,
"delete": false
},
"peers": {
"read": false,
"create": false,
"update": false,
"delete": false
}
}
}
}
}
```
</CodeGroup>
</Col>
</Row>
---
## Reject user {{ tag: 'DELETE' , label: '/api/users/{userId}/reject' }}
<Row>
<Col>
Reject a user that is pending approval by removing them from the account
### Path Parameters
<Properties>
<Property name="userId" type="string" required={true}>
The unique identifier of a user
</Property>
</Properties>
</Col>
<Col sticky>
<CodeGroup title="Request" tag="DELETE" label="/api/users/{userId}/reject">
```bash {{ title: 'cURL' }}
curl -X DELETE https://api.netbird.io/api/users/{userId}/reject \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'delete',
maxBodyLength: Infinity,
url: '/api/users/{userId}/reject',
headers: {
'Authorization': 'Token <TOKEN>'
}
};
axios(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
```
```python
import requests
import json
url = "https://api.netbird.io/api/users/{userId}/reject"
headers = {
'Authorization': 'Token <TOKEN>'
}
response = requests.request("DELETE", url, headers=headers)
print(response.text)
```
```go
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://api.netbird.io/api/users/{userId}/reject"
method := "DELETE"
client := &http.Client {
}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
return
{
req.Header.Add("Authorization", "Token <TOKEN>")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
```
```ruby
require "uri"
require "json"
require "net/http"
url = URI("https://api.netbird.io/api/users/{userId}/reject")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Authorization"] = "Token <TOKEN>"
response = https.request(request)
puts response.read_body
```
```java
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
Request request = new Request.Builder()
.url("https://api.netbird.io/api/users/{userId}/reject")
.method("DELETE")
.addHeader("Authorization: Token <TOKEN>")
.build();
Response response = client.newCall(request).execute();
```
```php
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.netbird.io/api/users/{userId}/reject',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => array(
'Authorization: Token <TOKEN>'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
```
</CodeGroup>
</Col>
</Row>
---
## Retrieve current user {{ tag: 'GET' , label: '/api/users/current' }} ## Retrieve current user {{ tag: 'GET' , label: '/api/users/current' }}
<Row> <Row>
@@ -1425,6 +1867,7 @@ echo $response;
{ {
"id": "google-oauth2|277474792786460067937", "id": "google-oauth2|277474792786460067937",
"email": "demo@netbird.io", "email": "demo@netbird.io",
"password": "super_secure_password",
"name": "Tom Schulz", "name": "Tom Schulz",
"role": "admin", "role": "admin",
"status": "active", "status": "active",
@@ -1435,7 +1878,9 @@ echo $response;
"is_current": true, "is_current": true,
"is_service_user": false, "is_service_user": false,
"is_blocked": false, "is_blocked": false,
"pending_approval": false,
"issued": "api", "issued": "api",
"idp_id": "okta-abc123",
"permissions": { "permissions": {
"is_restricted": { "is_restricted": {
"type": "boolean", "type": "boolean",
@@ -1462,6 +1907,7 @@ echo $response;
{ {
"id": "string", "id": "string",
"email": "string", "email": "string",
"password": "string",
"name": "string", "name": "string",
"role": "string", "role": "string",
"status": "string", "status": "string",
@@ -1472,7 +1918,9 @@ echo $response;
"is_current": "boolean", "is_current": "boolean",
"is_service_user": "boolean", "is_service_user": "boolean",
"is_blocked": "boolean", "is_blocked": "boolean",
"pending_approval": "boolean",
"issued": "string", "issued": "string",
"idp_id": "string",
"permissions": { "permissions": {
"is_restricted": "boolean", "is_restricted": "boolean",
"modules": { "modules": {