mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 15:10:23 +00:00
Api updates
This commit is contained in:
parent
1172e0a949
commit
547b335410
14 changed files with 1264 additions and 52 deletions
|
@ -0,0 +1,19 @@
|
|||
package io.xpipe.app.beacon.impl;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.beacon.BeaconClientException;
|
||||
import io.xpipe.beacon.api.ConnectionAddExchange;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ConnectionAddExchangeImpl extends ConnectionAddExchange {
|
||||
|
||||
@Override
|
||||
public Object handle(HttpExchange exchange, Request msg) throws BeaconClientException {
|
||||
var cat = msg.getCategory() != null ? msg.getCategory() : DataStorage.DEFAULT_CATEGORY_UUID;
|
||||
var entry = DataStorage.get().addStoreEntryIfNotPresent(DataStoreEntry.createNew(UUID.randomUUID(), cat, msg.getName(), msg.getData()));
|
||||
return Response.builder().connection(entry.getUuid()).build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package io.xpipe.app.beacon.impl;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import io.xpipe.app.browser.session.BrowserSessionModel;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.beacon.BeaconClientException;
|
||||
import io.xpipe.beacon.api.ConnectionBrowseExchange;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
|
||||
public class ConnectionBrowseExchangeImpl extends ConnectionBrowseExchange {
|
||||
|
||||
@Override
|
||||
public Object handle(HttpExchange exchange, Request msg) throws Exception {
|
||||
var e = DataStorage.get()
|
||||
.getStoreEntryIfPresent(msg.getConnection())
|
||||
.orElseThrow(() -> new BeaconClientException("Unknown connection: " + msg.getConnection()));
|
||||
if (!(e.getStore() instanceof FileSystemStore)) {
|
||||
throw new BeaconClientException("Not a file system connection");
|
||||
}
|
||||
BrowserSessionModel.DEFAULT.openFileSystemSync(e.ref(),msg.getDirectory() != null ? ignored -> msg.getDirectory() : null,null);
|
||||
AppLayoutModel.get().selectBrowser();
|
||||
return Response.builder().build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package io.xpipe.app.beacon.impl;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.util.TerminalLauncher;
|
||||
import io.xpipe.beacon.BeaconClientException;
|
||||
import io.xpipe.beacon.api.ConnectionTerminalExchange;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
|
||||
public class ConnectionTerminalExchangeImpl extends ConnectionTerminalExchange {
|
||||
|
||||
@Override
|
||||
public Object handle(HttpExchange exchange, Request msg) throws Exception {
|
||||
var e = DataStorage.get()
|
||||
.getStoreEntryIfPresent(msg.getConnection())
|
||||
.orElseThrow(() -> new BeaconClientException("Unknown connection: " + msg.getConnection()));
|
||||
if (!(e.getStore() instanceof ShellStore shellStore)) {
|
||||
throw new BeaconClientException("Not a shell connection");
|
||||
}
|
||||
try (var sc = shellStore.control().start()) {
|
||||
TerminalLauncher.open(e,e.getName(),msg.getDirectory(),sc);
|
||||
}
|
||||
return Response.builder().build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package io.xpipe.app.beacon.impl;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.beacon.BeaconClientException;
|
||||
import io.xpipe.beacon.api.ConnectionToggleExchange;
|
||||
import io.xpipe.core.store.SingletonSessionStore;
|
||||
|
||||
public class ConnectionToggleExchangeImpl extends ConnectionToggleExchange {
|
||||
|
||||
@Override
|
||||
public Object handle(HttpExchange exchange, Request msg) throws Exception {
|
||||
var e = DataStorage.get()
|
||||
.getStoreEntryIfPresent(msg.getConnection())
|
||||
.orElseThrow(() -> new BeaconClientException("Unknown connection: " + msg.getConnection()));
|
||||
if (!(e.getStore() instanceof SingletonSessionStore<?> singletonSessionStore)) {
|
||||
throw new BeaconClientException("Not a toggleable connection");
|
||||
}
|
||||
if (msg.isState()) {
|
||||
singletonSessionStore.startSessionIfNeeded();
|
||||
} else {
|
||||
singletonSessionStore.stopSessionIfNeeded();
|
||||
}
|
||||
return Response.builder().build();
|
||||
}
|
||||
}
|
|
@ -80,23 +80,33 @@ public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSess
|
|||
}
|
||||
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
OpenFileSystemModel model;
|
||||
|
||||
try (var b = new BooleanScope(externalBusy != null ? externalBusy : new SimpleBooleanProperty()).start()) {
|
||||
model = new OpenFileSystemModel(this, store, OpenFileSystemModel.SelectionMode.ALL);
|
||||
model.init();
|
||||
// Prevent multiple calls from interfering with each other
|
||||
synchronized (BrowserSessionModel.this) {
|
||||
sessionEntries.add(model);
|
||||
// The tab pane doesn't automatically select new tabs
|
||||
selectedEntry.setValue(model);
|
||||
}
|
||||
}
|
||||
if (path != null) {
|
||||
model.initWithGivenDirectory(FileNames.toDirectory(path.apply(model)));
|
||||
} else {
|
||||
model.initWithDefaultDirectory();
|
||||
}
|
||||
openFileSystemSync(store, path, externalBusy);
|
||||
});
|
||||
}
|
||||
|
||||
public void openFileSystemSync(
|
||||
DataStoreEntryRef<? extends FileSystemStore> store,
|
||||
FailableFunction<OpenFileSystemModel, String, Exception> path,
|
||||
BooleanProperty externalBusy) throws Exception {
|
||||
if (store == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
OpenFileSystemModel model;
|
||||
try (var b = new BooleanScope(externalBusy != null ? externalBusy : new SimpleBooleanProperty()).start()) {
|
||||
model = new OpenFileSystemModel(this, store, OpenFileSystemModel.SelectionMode.ALL);
|
||||
model.init();
|
||||
// Prevent multiple calls from interfering with each other
|
||||
synchronized (BrowserSessionModel.this) {
|
||||
sessionEntries.add(model);
|
||||
// The tab pane doesn't automatically select new tabs
|
||||
selectedEntry.setValue(model);
|
||||
}
|
||||
}
|
||||
if (path != null) {
|
||||
model.initWithGivenDirectory(FileNames.toDirectory(path.apply(model)));
|
||||
} else {
|
||||
model.initWithDefaultDirectory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,6 +135,10 @@ open module io.xpipe.app {
|
|||
ShellExecExchangeImpl,
|
||||
ConnectionQueryExchangeImpl,
|
||||
ConnectionInfoExchangeImpl,
|
||||
ConnectionAddExchangeImpl,
|
||||
ConnectionBrowseExchangeImpl,
|
||||
ConnectionTerminalExchangeImpl,
|
||||
ConnectionToggleExchangeImpl,
|
||||
DaemonOpenExchangeImpl,
|
||||
DaemonFocusExchangeImpl,
|
||||
DaemonStatusExchangeImpl,
|
||||
|
|
|
@ -31,8 +31,10 @@ You can get started by either using this page as an API reference or alternative
|
|||
The XPipe application will start up an HTTP server that can be used to send requests.
|
||||
Note that this server is HTTP-only for now as it runs only on localhost. HTTPS requests are not accepted.
|
||||
|
||||
This allows you to programmatically manage remote systems.
|
||||
To start off, you can query connections based on various filters.
|
||||
You can either call the API directly or use one of the following community-made libraries:
|
||||
- [https://github.com/coandco/python_xpipe_client](https://github.com/coandco/python_xpipe_client)
|
||||
|
||||
To start off with the API, you can query connections based on various filters.
|
||||
With the matched connections, you can start remote shell sessions for each one and run arbitrary commands in them.
|
||||
You get the command exit code and output as a response, allowing you to adapt your control flow based on command outputs.
|
||||
Any kind of passwords and other secrets are automatically provided by XPipe when establishing a shell connection.
|
||||
|
@ -300,7 +302,6 @@ All matching is case insensitive.
|
|||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
|
@ -491,7 +492,6 @@ Queries detailed information about a connection.
|
|||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
|
@ -616,6 +616,697 @@ curl -X POST http://localhost:21721/connection/info \
|
|||
|
||||
</details>
|
||||
|
||||
## Add new connection
|
||||
|
||||
<a id="opIdconnectionAdd"></a>
|
||||
|
||||
`POST /connection/add`
|
||||
|
||||
Creates the new connection in the xpipe vault from raw json data.
|
||||
|
||||
If an equivalent connection already exists, no new one will be added.
|
||||
|
||||
> Body parameter
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my connection",
|
||||
"category": "97458c07-75c0-4f9d-a06e-92d8cdf67c40",
|
||||
"data": {
|
||||
"type": "shellEnvironment",
|
||||
"commands": null,
|
||||
"host": {
|
||||
"storeId": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
},
|
||||
"shell": "pwsh",
|
||||
"elevated": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<h3 id="add-new-connection-parameters">Parameters</h3>
|
||||
|
||||
|Name|In|Type|Required|Description|
|
||||
|---|---|---|---|---|
|
||||
|body|body|[ConnectionAddRequest](#schemaconnectionaddrequest)|true|none|
|
||||
|
||||
> Example responses
|
||||
|
||||
> The request was successful. The connection was added.
|
||||
|
||||
```json
|
||||
{
|
||||
"connection": "36ad9716-a209-4f7f-9814-078d3349280c"
|
||||
}
|
||||
```
|
||||
|
||||
> 400 Response
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "string"
|
||||
}
|
||||
```
|
||||
|
||||
<h3 id="add-new-connection-responses">Responses</h3>
|
||||
|
||||
|Status|Meaning|Description|Schema|
|
||||
|---|---|---|---|
|
||||
|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The request was successful. The connection was added.|[ConnectionAddResponse](#schemaconnectionaddresponse)|
|
||||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
To perform this operation, you must be authenticated by means of one of the following methods:
|
||||
bearerAuth
|
||||
</aside>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Code samples</summary>
|
||||
|
||||
```javascript
|
||||
const inputBody = '{
|
||||
"name": "my connection",
|
||||
"category": "97458c07-75c0-4f9d-a06e-92d8cdf67c40",
|
||||
"data": {
|
||||
"type": "shellEnvironment",
|
||||
"commands": null,
|
||||
"host": {
|
||||
"storeId": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
},
|
||||
"shell": "pwsh",
|
||||
"elevated": false
|
||||
}
|
||||
}';
|
||||
const headers = {
|
||||
'Content-Type':'application/json',
|
||||
'Accept':'application/json',
|
||||
'Authorization':'Bearer {access-token}'
|
||||
};
|
||||
|
||||
fetch('http://localhost:21721/connection/add',
|
||||
{
|
||||
method: 'POST',
|
||||
body: inputBody,
|
||||
headers: headers
|
||||
})
|
||||
.then(function(res) {
|
||||
return res.json();
|
||||
}).then(function(body) {
|
||||
console.log(body);
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
```python
|
||||
import requests
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'Bearer {access-token}'
|
||||
}
|
||||
|
||||
data = """
|
||||
{
|
||||
"name": "my connection",
|
||||
"category": "97458c07-75c0-4f9d-a06e-92d8cdf67c40",
|
||||
"data": {
|
||||
"type": "shellEnvironment",
|
||||
"commands": null,
|
||||
"host": {
|
||||
"storeId": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
},
|
||||
"shell": "pwsh",
|
||||
"elevated": false
|
||||
}
|
||||
}
|
||||
"""
|
||||
r = requests.post('http://localhost:21721/connection/add', headers = headers, data = data)
|
||||
|
||||
print(r.json())
|
||||
|
||||
```
|
||||
|
||||
```java
|
||||
var uri = URI.create("http://localhost:21721/connection/add");
|
||||
var client = HttpClient.newHttpClient();
|
||||
var request = HttpRequest
|
||||
.newBuilder()
|
||||
.uri(uri)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Accept", "application/json")
|
||||
.header("Authorization", "Bearer {access-token}")
|
||||
.POST(HttpRequest.BodyPublishers.ofString("""
|
||||
{
|
||||
"name": "my connection",
|
||||
"category": "97458c07-75c0-4f9d-a06e-92d8cdf67c40",
|
||||
"data": {
|
||||
"type": "shellEnvironment",
|
||||
"commands": null,
|
||||
"host": {
|
||||
"storeId": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
},
|
||||
"shell": "pwsh",
|
||||
"elevated": false
|
||||
}
|
||||
}
|
||||
"""))
|
||||
.build();
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
System.out.println(response.statusCode());
|
||||
System.out.println(response.body());
|
||||
|
||||
```
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
headers := map[string][]string{
|
||||
"Content-Type": []string{"application/json"},
|
||||
"Accept": []string{"application/json"},
|
||||
"Authorization": []string{"Bearer {access-token}"},
|
||||
}
|
||||
|
||||
data := bytes.NewBuffer([]byte{jsonReq})
|
||||
req, err := http.NewRequest("POST", "http://localhost:21721/connection/add", data)
|
||||
req.Header = headers
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
// ...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```shell
|
||||
# You can also use wget
|
||||
curl -X POST http://localhost:21721/connection/add \
|
||||
-H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer {access-token}' \
|
||||
--data '
|
||||
{
|
||||
"name": "my connection",
|
||||
"category": "97458c07-75c0-4f9d-a06e-92d8cdf67c40",
|
||||
"data": {
|
||||
"type": "shellEnvironment",
|
||||
"commands": null,
|
||||
"host": {
|
||||
"storeId": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
},
|
||||
"shell": "pwsh",
|
||||
"elevated": false
|
||||
}
|
||||
}
|
||||
'
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Open connection in file browser
|
||||
|
||||
<a id="opIdconnectionBrowse"></a>
|
||||
|
||||
`POST /connection/browse`
|
||||
|
||||
Creates a new tab in the file browser and opens the specified connections with an optional starting directory.
|
||||
|
||||
> Body parameter
|
||||
|
||||
```json
|
||||
{
|
||||
"connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
}
|
||||
```
|
||||
|
||||
<h3 id="open-connection-in-file-browser-parameters">Parameters</h3>
|
||||
|
||||
|Name|In|Type|Required|Description|
|
||||
|---|---|---|---|---|
|
||||
|body|body|[ConnectionBrowseRequest](#schemaconnectionbrowserequest)|true|none|
|
||||
|
||||
> Example responses
|
||||
|
||||
> 400 Response
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "string"
|
||||
}
|
||||
```
|
||||
|
||||
<h3 id="open-connection-in-file-browser-responses">Responses</h3>
|
||||
|
||||
|Status|Meaning|Description|Schema|
|
||||
|---|---|---|---|
|
||||
|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The request was successful. The connection was opened.|None|
|
||||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
To perform this operation, you must be authenticated by means of one of the following methods:
|
||||
bearerAuth
|
||||
</aside>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Code samples</summary>
|
||||
|
||||
```javascript
|
||||
const inputBody = '{
|
||||
"connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
}';
|
||||
const headers = {
|
||||
'Content-Type':'application/json',
|
||||
'Accept':'application/json',
|
||||
'Authorization':'Bearer {access-token}'
|
||||
};
|
||||
|
||||
fetch('http://localhost:21721/connection/browse',
|
||||
{
|
||||
method: 'POST',
|
||||
body: inputBody,
|
||||
headers: headers
|
||||
})
|
||||
.then(function(res) {
|
||||
return res.json();
|
||||
}).then(function(body) {
|
||||
console.log(body);
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
```python
|
||||
import requests
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'Bearer {access-token}'
|
||||
}
|
||||
|
||||
data = """
|
||||
{
|
||||
"connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
}
|
||||
"""
|
||||
r = requests.post('http://localhost:21721/connection/browse', headers = headers, data = data)
|
||||
|
||||
print(r.json())
|
||||
|
||||
```
|
||||
|
||||
```java
|
||||
var uri = URI.create("http://localhost:21721/connection/browse");
|
||||
var client = HttpClient.newHttpClient();
|
||||
var request = HttpRequest
|
||||
.newBuilder()
|
||||
.uri(uri)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Accept", "application/json")
|
||||
.header("Authorization", "Bearer {access-token}")
|
||||
.POST(HttpRequest.BodyPublishers.ofString("""
|
||||
{
|
||||
"connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
}
|
||||
"""))
|
||||
.build();
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
System.out.println(response.statusCode());
|
||||
System.out.println(response.body());
|
||||
|
||||
```
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
headers := map[string][]string{
|
||||
"Content-Type": []string{"application/json"},
|
||||
"Accept": []string{"application/json"},
|
||||
"Authorization": []string{"Bearer {access-token}"},
|
||||
}
|
||||
|
||||
data := bytes.NewBuffer([]byte{jsonReq})
|
||||
req, err := http.NewRequest("POST", "http://localhost:21721/connection/browse", data)
|
||||
req.Header = headers
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
// ...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```shell
|
||||
# You can also use wget
|
||||
curl -X POST http://localhost:21721/connection/browse \
|
||||
-H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer {access-token}' \
|
||||
--data '
|
||||
{
|
||||
"connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
}
|
||||
'
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Open terminal for shell connection
|
||||
|
||||
<a id="opIdconnectionTerminal"></a>
|
||||
|
||||
`POST /connection/terminal`
|
||||
|
||||
Launches a new terminal session for a connection with an optional specified working directory.
|
||||
|
||||
> Body parameter
|
||||
|
||||
```json
|
||||
{
|
||||
"connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
}
|
||||
```
|
||||
|
||||
<h3 id="open-terminal-for-shell-connection-parameters">Parameters</h3>
|
||||
|
||||
|Name|In|Type|Required|Description|
|
||||
|---|---|---|---|---|
|
||||
|body|body|[ConnectionTerminalRequest](#schemaconnectionterminalrequest)|true|none|
|
||||
|
||||
> Example responses
|
||||
|
||||
> 400 Response
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "string"
|
||||
}
|
||||
```
|
||||
|
||||
<h3 id="open-terminal-for-shell-connection-responses">Responses</h3>
|
||||
|
||||
|Status|Meaning|Description|Schema|
|
||||
|---|---|---|---|
|
||||
|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The request was successful. The connection was opened.|None|
|
||||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
To perform this operation, you must be authenticated by means of one of the following methods:
|
||||
bearerAuth
|
||||
</aside>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Code samples</summary>
|
||||
|
||||
```javascript
|
||||
const inputBody = '{
|
||||
"connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
}';
|
||||
const headers = {
|
||||
'Content-Type':'application/json',
|
||||
'Accept':'application/json',
|
||||
'Authorization':'Bearer {access-token}'
|
||||
};
|
||||
|
||||
fetch('http://localhost:21721/connection/terminal',
|
||||
{
|
||||
method: 'POST',
|
||||
body: inputBody,
|
||||
headers: headers
|
||||
})
|
||||
.then(function(res) {
|
||||
return res.json();
|
||||
}).then(function(body) {
|
||||
console.log(body);
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
```python
|
||||
import requests
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'Bearer {access-token}'
|
||||
}
|
||||
|
||||
data = """
|
||||
{
|
||||
"connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
}
|
||||
"""
|
||||
r = requests.post('http://localhost:21721/connection/terminal', headers = headers, data = data)
|
||||
|
||||
print(r.json())
|
||||
|
||||
```
|
||||
|
||||
```java
|
||||
var uri = URI.create("http://localhost:21721/connection/terminal");
|
||||
var client = HttpClient.newHttpClient();
|
||||
var request = HttpRequest
|
||||
.newBuilder()
|
||||
.uri(uri)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Accept", "application/json")
|
||||
.header("Authorization", "Bearer {access-token}")
|
||||
.POST(HttpRequest.BodyPublishers.ofString("""
|
||||
{
|
||||
"connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
}
|
||||
"""))
|
||||
.build();
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
System.out.println(response.statusCode());
|
||||
System.out.println(response.body());
|
||||
|
||||
```
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
headers := map[string][]string{
|
||||
"Content-Type": []string{"application/json"},
|
||||
"Accept": []string{"application/json"},
|
||||
"Authorization": []string{"Bearer {access-token}"},
|
||||
}
|
||||
|
||||
data := bytes.NewBuffer([]byte{jsonReq})
|
||||
req, err := http.NewRequest("POST", "http://localhost:21721/connection/terminal", data)
|
||||
req.Header = headers
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
// ...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```shell
|
||||
# You can also use wget
|
||||
curl -X POST http://localhost:21721/connection/terminal \
|
||||
-H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer {access-token}' \
|
||||
--data '
|
||||
{
|
||||
"connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
}
|
||||
'
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Toggle state of a connection
|
||||
|
||||
<a id="opIdconnectionToggle"></a>
|
||||
|
||||
`POST /connection/toggle`
|
||||
|
||||
Updates the state of a connection to either start or stop a session.
|
||||
|
||||
This can be used for all kinds of services and tunnels.
|
||||
|
||||
> Body parameter
|
||||
|
||||
```json
|
||||
{
|
||||
"connection": "36ad9716-a209-4f7f-9814-078d3349280c",
|
||||
"state": true
|
||||
}
|
||||
```
|
||||
|
||||
<h3 id="toggle-state-of-a-connection-parameters">Parameters</h3>
|
||||
|
||||
|Name|In|Type|Required|Description|
|
||||
|---|---|---|---|---|
|
||||
|body|body|[ConnectionToggleRequest](#schemaconnectiontogglerequest)|true|none|
|
||||
|
||||
> Example responses
|
||||
|
||||
> 400 Response
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "string"
|
||||
}
|
||||
```
|
||||
|
||||
<h3 id="toggle-state-of-a-connection-responses">Responses</h3>
|
||||
|
||||
|Status|Meaning|Description|Schema|
|
||||
|---|---|---|---|
|
||||
|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The request was successful. The connection state was updated.|None|
|
||||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
To perform this operation, you must be authenticated by means of one of the following methods:
|
||||
bearerAuth
|
||||
</aside>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Code samples</summary>
|
||||
|
||||
```javascript
|
||||
const inputBody = '{
|
||||
"connection": "36ad9716-a209-4f7f-9814-078d3349280c",
|
||||
"state": true
|
||||
}';
|
||||
const headers = {
|
||||
'Content-Type':'application/json',
|
||||
'Accept':'application/json',
|
||||
'Authorization':'Bearer {access-token}'
|
||||
};
|
||||
|
||||
fetch('http://localhost:21721/connection/toggle',
|
||||
{
|
||||
method: 'POST',
|
||||
body: inputBody,
|
||||
headers: headers
|
||||
})
|
||||
.then(function(res) {
|
||||
return res.json();
|
||||
}).then(function(body) {
|
||||
console.log(body);
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
```python
|
||||
import requests
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'Bearer {access-token}'
|
||||
}
|
||||
|
||||
data = """
|
||||
{
|
||||
"connection": "36ad9716-a209-4f7f-9814-078d3349280c",
|
||||
"state": true
|
||||
}
|
||||
"""
|
||||
r = requests.post('http://localhost:21721/connection/toggle', headers = headers, data = data)
|
||||
|
||||
print(r.json())
|
||||
|
||||
```
|
||||
|
||||
```java
|
||||
var uri = URI.create("http://localhost:21721/connection/toggle");
|
||||
var client = HttpClient.newHttpClient();
|
||||
var request = HttpRequest
|
||||
.newBuilder()
|
||||
.uri(uri)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Accept", "application/json")
|
||||
.header("Authorization", "Bearer {access-token}")
|
||||
.POST(HttpRequest.BodyPublishers.ofString("""
|
||||
{
|
||||
"connection": "36ad9716-a209-4f7f-9814-078d3349280c",
|
||||
"state": true
|
||||
}
|
||||
"""))
|
||||
.build();
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
System.out.println(response.statusCode());
|
||||
System.out.println(response.body());
|
||||
|
||||
```
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
headers := map[string][]string{
|
||||
"Content-Type": []string{"application/json"},
|
||||
"Accept": []string{"application/json"},
|
||||
"Authorization": []string{"Bearer {access-token}"},
|
||||
}
|
||||
|
||||
data := bytes.NewBuffer([]byte{jsonReq})
|
||||
req, err := http.NewRequest("POST", "http://localhost:21721/connection/toggle", data)
|
||||
req.Header = headers
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
// ...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```shell
|
||||
# You can also use wget
|
||||
curl -X POST http://localhost:21721/connection/toggle \
|
||||
-H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer {access-token}' \
|
||||
--data '
|
||||
{
|
||||
"connection": "36ad9716-a209-4f7f-9814-078d3349280c",
|
||||
"state": true
|
||||
}
|
||||
'
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Start shell connection
|
||||
|
||||
<a id="opIdshellStart"></a>
|
||||
|
@ -659,7 +1350,6 @@ These errors will be returned with the HTTP return code 500.
|
|||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
|
@ -819,7 +1509,6 @@ If the shell is busy or stuck, you might have to work with timeouts to account f
|
|||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
|
@ -999,7 +1688,6 @@ However, if any other error occurs like the shell not responding or exiting unex
|
|||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
|
@ -1170,7 +1858,6 @@ string
|
|||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
|
@ -1322,7 +2009,6 @@ Reads the entire content of a remote file through an active shell session.
|
|||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
|
@ -1485,7 +2171,6 @@ Writes blob data to a file through an active shell session.
|
|||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
|
@ -1661,7 +2346,6 @@ This can be used to run more complex commands on remote systems.
|
|||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
|
@ -1811,7 +2495,6 @@ Retrieves version information from the daemon
|
|||
|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|[ClientErrorResponse](#schemaclienterrorresponse)|
|
||||
|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None|
|
||||
|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None|
|
||||
|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None|
|
||||
|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|[ServerErrorResponse](#schemaservererrorresponse)|
|
||||
|
||||
<aside class="warning">
|
||||
|
@ -2234,6 +2917,116 @@ undefined
|
|||
|usageCategory|desktop|
|
||||
|usageCategory|group|
|
||||
|
||||
<h2 id="tocS_ConnectionAddRequest">ConnectionAddRequest</h2>
|
||||
|
||||
<a id="schemaconnectionaddrequest"></a>
|
||||
<a id="schema_ConnectionAddRequest"></a>
|
||||
<a id="tocSconnectionaddrequest"></a>
|
||||
<a id="tocsconnectionaddrequest"></a>
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "string",
|
||||
"category": "string",
|
||||
"data": {}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<h3>Properties</h3>
|
||||
|
||||
|Name|Type|Required|Restrictions|Description|
|
||||
|---|---|---|---|---|
|
||||
|name|string|true|none|The connection name|
|
||||
|category|string|false|none|The optional category uuid if you want to add the connection to a certain one. Otherwise the currently selected category will be used.|
|
||||
|data|object|true|none|The raw connection store data. Schemas for connection types are not documented but you can find the connection data of your existing connections in the xpipe vault.|
|
||||
|
||||
<h2 id="tocS_ConnectionAddResponse">ConnectionAddResponse</h2>
|
||||
|
||||
<a id="schemaconnectionaddresponse"></a>
|
||||
<a id="schema_ConnectionAddResponse"></a>
|
||||
<a id="tocSconnectionaddresponse"></a>
|
||||
<a id="tocsconnectionaddresponse"></a>
|
||||
|
||||
```json
|
||||
{
|
||||
"connection": "string"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<h3>Properties</h3>
|
||||
|
||||
|Name|Type|Required|Restrictions|Description|
|
||||
|---|---|---|---|---|
|
||||
|connection|string|true|none|The connection uuid|
|
||||
|
||||
<h2 id="tocS_ConnectionBrowseRequest">ConnectionBrowseRequest</h2>
|
||||
|
||||
<a id="schemaconnectionbrowserequest"></a>
|
||||
<a id="schema_ConnectionBrowseRequest"></a>
|
||||
<a id="tocSconnectionbrowserequest"></a>
|
||||
<a id="tocsconnectionbrowserequest"></a>
|
||||
|
||||
```json
|
||||
{
|
||||
"directory": "string",
|
||||
"connection": "string"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<h3>Properties</h3>
|
||||
|
||||
|Name|Type|Required|Restrictions|Description|
|
||||
|---|---|---|---|---|
|
||||
|directory|string|true|none|The optional directory to browse to|
|
||||
|connection|string|true|none|The connection uuid|
|
||||
|
||||
<h2 id="tocS_ConnectionToggleRequest">ConnectionToggleRequest</h2>
|
||||
|
||||
<a id="schemaconnectiontogglerequest"></a>
|
||||
<a id="schema_ConnectionToggleRequest"></a>
|
||||
<a id="tocSconnectiontogglerequest"></a>
|
||||
<a id="tocsconnectiontogglerequest"></a>
|
||||
|
||||
```json
|
||||
{
|
||||
"state": true,
|
||||
"connection": "string"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<h3>Properties</h3>
|
||||
|
||||
|Name|Type|Required|Restrictions|Description|
|
||||
|---|---|---|---|---|
|
||||
|state|boolean|true|none|The state to switch to|
|
||||
|connection|string|true|none|The connection uuid|
|
||||
|
||||
<h2 id="tocS_ConnectionTerminalRequest">ConnectionTerminalRequest</h2>
|
||||
|
||||
<a id="schemaconnectionterminalrequest"></a>
|
||||
<a id="schema_ConnectionTerminalRequest"></a>
|
||||
<a id="tocSconnectionterminalrequest"></a>
|
||||
<a id="tocsconnectionterminalrequest"></a>
|
||||
|
||||
```json
|
||||
{
|
||||
"directory": "string",
|
||||
"connection": "string"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<h3>Properties</h3>
|
||||
|
||||
|Name|Type|Required|Restrictions|Description|
|
||||
|---|---|---|---|---|
|
||||
|directory|string|true|none|The optional directory to use as the working directory|
|
||||
|connection|string|true|none|The connection uuid|
|
||||
|
||||
<h2 id="tocS_HandshakeRequest">HandshakeRequest</h2>
|
||||
|
||||
<a id="schemahandshakerequest"></a>
|
||||
|
|
|
@ -72,7 +72,7 @@ public abstract class BeaconInterface<T> {
|
|||
|
||||
public abstract String getPath();
|
||||
|
||||
public Object handle(HttpExchange exchange, T body) throws BeaconClientException, BeaconServerException {
|
||||
public Object handle(HttpExchange exchange, T body) throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package io.xpipe.beacon.api;
|
||||
|
||||
import io.xpipe.beacon.BeaconInterface;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ConnectionAddExchange extends BeaconInterface<ConnectionAddExchange.Request> {
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return "/connection/add";
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@Builder
|
||||
@Value
|
||||
public static class Request {
|
||||
@NonNull
|
||||
String name;
|
||||
|
||||
@NonNull
|
||||
DataStore data;
|
||||
|
||||
UUID category;
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@Builder
|
||||
@Value
|
||||
public static class Response {
|
||||
@NonNull
|
||||
UUID connection;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package io.xpipe.beacon.api;
|
||||
|
||||
import io.xpipe.beacon.BeaconInterface;
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ConnectionBrowseExchange extends BeaconInterface<ConnectionBrowseExchange.Request> {
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return "/connection/browse";
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@Builder
|
||||
@Value
|
||||
public static class Request {
|
||||
@NonNull
|
||||
UUID connection;
|
||||
|
||||
String directory;
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@Builder
|
||||
@Value
|
||||
public static class Response {}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package io.xpipe.beacon.api;
|
||||
|
||||
import io.xpipe.beacon.BeaconInterface;
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ConnectionTerminalExchange extends BeaconInterface<ConnectionTerminalExchange.Request> {
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return "/connection/terminal";
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@Builder
|
||||
@Value
|
||||
public static class Request {
|
||||
@NonNull
|
||||
UUID connection;
|
||||
|
||||
String directory;
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@Builder
|
||||
@Value
|
||||
public static class Response {}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package io.xpipe.beacon.api;
|
||||
|
||||
import io.xpipe.beacon.BeaconInterface;
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ConnectionToggleExchange extends BeaconInterface<ConnectionToggleExchange.Request> {
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return "/connection/toggle";
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@Builder
|
||||
@Value
|
||||
public static class Request {
|
||||
@NonNull
|
||||
UUID connection;
|
||||
|
||||
boolean state;
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@Builder
|
||||
@Value
|
||||
public static class Response {}
|
||||
}
|
|
@ -38,6 +38,10 @@ open module io.xpipe.beacon {
|
|||
HandshakeExchange,
|
||||
ConnectionQueryExchange,
|
||||
ConnectionInfoExchange,
|
||||
ConnectionAddExchange,
|
||||
ConnectionBrowseExchange,
|
||||
ConnectionTerminalExchange,
|
||||
ConnectionToggleExchange,
|
||||
AskpassExchange,
|
||||
TerminalWaitExchange,
|
||||
TerminalLaunchExchange,
|
||||
|
|
215
openapi.yaml
215
openapi.yaml
|
@ -10,8 +10,10 @@ info:
|
|||
The XPipe application will start up an HTTP server that can be used to send requests.
|
||||
Note that this server is HTTP-only for now as it runs only on localhost. HTTPS requests are not accepted.
|
||||
|
||||
This allows you to programmatically manage remote systems.
|
||||
To start off, you can query connections based on various filters.
|
||||
You can either call the API directly or use one of the following community-made libraries:
|
||||
- [https://github.com/coandco/python_xpipe_client](https://github.com/coandco/python_xpipe_client)
|
||||
|
||||
To start off with the API, you can query connections based on various filters.
|
||||
With the matched connections, you can start remote shell sessions for each one and run arbitrary commands in them.
|
||||
You get the command exit code and output as a response, allowing you to adapt your control flow based on command outputs.
|
||||
Any kind of passwords and other secrets are automatically provided by XPipe when establishing a shell connection.
|
||||
|
@ -111,8 +113,6 @@ paths:
|
|||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/connection/info:
|
||||
|
@ -151,8 +151,136 @@ paths:
|
|||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/connection/add:
|
||||
post:
|
||||
summary: Add new connection
|
||||
description: |
|
||||
Creates the new connection in the xpipe vault from raw json data.
|
||||
|
||||
If an equivalent connection already exists, no new one will be added.
|
||||
operationId: connectionAdd
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ConnectionAddRequest'
|
||||
examples:
|
||||
simple:
|
||||
summary: Add new pwsh shell environment
|
||||
value: { "name": "my connection", "category": "97458c07-75c0-4f9d-a06e-92d8cdf67c40", "data":
|
||||
{
|
||||
"type": "shellEnvironment",
|
||||
"commands": null,
|
||||
"host": {
|
||||
"storeId": "f0ec68aa-63f5-405c-b178-9a4454556d6b"
|
||||
},
|
||||
"shell": "pwsh",
|
||||
"elevated": false,
|
||||
}
|
||||
}
|
||||
responses:
|
||||
'200':
|
||||
description: The request was successful. The connection was added.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ConnectionAddResponse'
|
||||
examples:
|
||||
standard:
|
||||
summary: Connection information
|
||||
value: { "connection": "36ad9716-a209-4f7f-9814-078d3349280c" }
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/connection/browse:
|
||||
post:
|
||||
summary: Open connection in file browser
|
||||
description: |
|
||||
Creates a new tab in the file browser and opens the specified connections with an optional starting directory.
|
||||
operationId: connectionBrowse
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ConnectionBrowseRequest'
|
||||
examples:
|
||||
simple:
|
||||
summary: Open local file browser
|
||||
value: { "connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b" }
|
||||
responses:
|
||||
'200':
|
||||
description: The request was successful. The connection was opened.
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/connection/terminal:
|
||||
post:
|
||||
summary: Open terminal for shell connection
|
||||
description: |
|
||||
Launches a new terminal session for a connection with an optional specified working directory.
|
||||
operationId: connectionTerminal
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ConnectionTerminalRequest'
|
||||
examples:
|
||||
simple:
|
||||
summary: Open terminal for local shell
|
||||
value: { "connection": "f0ec68aa-63f5-405c-b178-9a4454556d6b" }
|
||||
responses:
|
||||
'200':
|
||||
description: The request was successful. The connection was opened.
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/connection/toggle:
|
||||
post:
|
||||
summary: Toggle state of a connection
|
||||
description: |
|
||||
Updates the state of a connection to either start or stop a session.
|
||||
|
||||
This can be used for all kinds of services and tunnels.
|
||||
operationId: connectionToggle
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ConnectionToggleRequest'
|
||||
examples:
|
||||
simple:
|
||||
summary: Activate connection
|
||||
value: { "connection": "36ad9716-a209-4f7f-9814-078d3349280c", "state": true }
|
||||
responses:
|
||||
'200':
|
||||
description: The request was successful. The connection state was updated.
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/shell/start:
|
||||
|
@ -183,8 +311,6 @@ paths:
|
|||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/shell/stop:
|
||||
|
@ -215,8 +341,6 @@ paths:
|
|||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/shell/exec:
|
||||
|
@ -262,8 +386,6 @@ paths:
|
|||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/fs/blob:
|
||||
|
@ -299,8 +421,6 @@ paths:
|
|||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/fs/read:
|
||||
|
@ -333,8 +453,6 @@ paths:
|
|||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/fs/write:
|
||||
|
@ -362,8 +480,6 @@ paths:
|
|||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/fs/script:
|
||||
|
@ -401,8 +517,6 @@ paths:
|
|||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
/daemon/version:
|
||||
|
@ -423,8 +537,6 @@ paths:
|
|||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
components:
|
||||
|
@ -624,6 +736,65 @@ components:
|
|||
- lastUsed
|
||||
- lastModified
|
||||
- state
|
||||
ConnectionAddRequest:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: The connection name
|
||||
category:
|
||||
type: string
|
||||
description: The optional category uuid if you want to add the connection to a certain one. Otherwise the currently selected category will be used.
|
||||
data:
|
||||
type: object
|
||||
description: The raw connection store data. Schemas for connection types are not documented but you can find the connection data of your existing connections in the xpipe vault.
|
||||
required:
|
||||
- name
|
||||
- data
|
||||
ConnectionAddResponse:
|
||||
type: object
|
||||
properties:
|
||||
connection:
|
||||
type: string
|
||||
description: The connection uuid
|
||||
required:
|
||||
- connection
|
||||
ConnectionBrowseRequest:
|
||||
type: object
|
||||
properties:
|
||||
directory:
|
||||
type: string
|
||||
description: The optional directory to browse to
|
||||
connection:
|
||||
type: string
|
||||
description: The connection uuid
|
||||
required:
|
||||
- directory
|
||||
- connection
|
||||
ConnectionToggleRequest:
|
||||
type: object
|
||||
properties:
|
||||
state:
|
||||
type: boolean
|
||||
description: The state to switch to
|
||||
connection:
|
||||
type: string
|
||||
description: The connection uuid
|
||||
required:
|
||||
- state
|
||||
- connection
|
||||
ConnectionTerminalRequest:
|
||||
type: object
|
||||
properties:
|
||||
directory:
|
||||
type: string
|
||||
description: The optional directory to use as the working directory
|
||||
connection:
|
||||
type: string
|
||||
description: The connection uuid
|
||||
required:
|
||||
- directory
|
||||
- connection
|
||||
HandshakeRequest:
|
||||
type: object
|
||||
properties:
|
||||
|
|
Loading…
Reference in a new issue