/agent/unshare implemented (#967)

This commit is contained in:
Michael Quigley 2025-06-02 16:18:28 -04:00
parent 1aad5ff2b2
commit 0c6dedc01c
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
24 changed files with 424 additions and 20 deletions

View File

@ -35,7 +35,7 @@ func (h *agentRemoteShareHandler) Handle(params agent.RemoteShareParams, princip
logrus.Errorf("error finding agent enrollment for environment '%v' (%v): %v", params.Body.EnvZID, principal.Email, err)
return agent.NewRemoteShareBadGateway()
}
_ = trx.Rollback()
_ = trx.Rollback() // ...or will block share trx on sqlite
acli, aconn, err := agentController.NewAgentClient(ae.Token, cfg.AgentController)
if err != nil {

View File

@ -0,0 +1,55 @@
package controller
import (
"context"
"github.com/go-openapi/runtime/middleware"
"github.com/openziti/zrok/agent/agentGrpc"
"github.com/openziti/zrok/controller/agentController"
"github.com/openziti/zrok/rest_model_zrok"
"github.com/openziti/zrok/rest_server_zrok/operations/agent"
"github.com/sirupsen/logrus"
)
type agentRemoteUnshareHandler struct{}
func newAgentRemoteUnshareHandler() *agentRemoteUnshareHandler {
return &agentRemoteUnshareHandler{}
}
func (h *agentRemoteUnshareHandler) Handle(params agent.RemoteUnshareParams, principal *rest_model_zrok.Principal) middleware.Responder {
trx, err := str.Begin()
if err != nil {
logrus.Errorf("error starting transaction for '%v': %v", principal.Email, err)
return agent.NewRemoteUnshareInternalServerError()
}
defer trx.Rollback()
env, err := str.FindEnvironmentForAccount(params.Body.EnvZID, int(principal.ID), trx)
if err != nil {
logrus.Errorf("error finding environment '%v' for '%v': %v", params.Body.EnvZID, principal.Email, err)
return agent.NewRemoteUnshareUnauthorized()
}
ae, err := str.FindAgentEnrollmentForEnvironment(env.Id, trx)
if err != nil {
logrus.Errorf("error finding agent enrollment for environment '%v' (%v): %v", params.Body.EnvZID, principal.Email, err)
return agent.NewRemoteUnshareBadGateway()
}
_ = trx.Rollback() // ...or will block unshare trx on sqlite
acli, aconn, err := agentController.NewAgentClient(ae.Token, cfg.AgentController)
if err != nil {
logrus.Errorf("error creating agent client for '%v' (%v): %v", params.Body.EnvZID, principal.Email, err)
return agent.NewRemoteUnshareInternalServerError()
}
defer aconn.Close()
req := &agentGrpc.ReleaseShareRequest{Token: params.Body.Token}
_, err = acli.ReleaseShare(context.Background(), req)
if err != nil {
logrus.Errorf("error releasing share '%v' for '%v' (%v): %v", params.Body.Token, params.Body.EnvZID, principal.Email, err)
return agent.NewRemoteUnshareBadGateway()
}
return agent.NewRemoteUnshareOK()
}

View File

@ -69,6 +69,7 @@ func Run(inCfg *config.Config) error {
api.AgentEnrollHandler = newAgentEnrollHandler()
api.AgentPingHandler = newAgentPingHandler()
api.AgentRemoteShareHandler = newAgentRemoteShareHandler()
api.AgentRemoteUnshareHandler = newAgentRemoteUnshareHandler()
api.AgentUnenrollHandler = newAgentUnenrollHandler()
}
api.EnvironmentEnableHandler = newEnableHandler()

View File

@ -281,6 +281,9 @@ swagger:model RemoteUnshareBody
*/
type RemoteUnshareBody struct {
// env z Id
EnvZID string `json:"envZId,omitempty"`
// token
Token string `json:"token,omitempty"`
}

View File

@ -452,6 +452,9 @@ func init() {
"in": "body",
"schema": {
"properties": {
"envZId": {
"type": "string"
},
"token": {
"type": "string"
}
@ -3053,6 +3056,9 @@ func init() {
"in": "body",
"schema": {
"properties": {
"envZId": {
"type": "string"
},
"token": {
"type": "string"
}

View File

@ -78,6 +78,9 @@ func (o *RemoteUnshare) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
// swagger:model RemoteUnshareBody
type RemoteUnshareBody struct {
// env z Id
EnvZID string `json:"envZId,omitempty"`
// token
Token string `json:"token,omitempty"`
}

View File

@ -49,6 +49,7 @@ models/RegenerateAccountTokenRequest.ts
models/RegisterRequest.ts
models/RemoteShare200Response.ts
models/RemoteShareRequest.ts
models/RemoteUnshareRequest.ts
models/RemoveOrganizationMemberRequest.ts
models/ResetPasswordRequest.ts
models/Share.ts

View File

@ -20,6 +20,7 @@ import type {
Ping200Response,
RemoteShare200Response,
RemoteShareRequest,
RemoteUnshareRequest,
} from '../models/index';
import {
Enroll200ResponseFromJSON,
@ -32,6 +33,8 @@ import {
RemoteShare200ResponseToJSON,
RemoteShareRequestFromJSON,
RemoteShareRequestToJSON,
RemoteUnshareRequestFromJSON,
RemoteUnshareRequestToJSON,
} from '../models/index';
export interface EnrollOperationRequest {
@ -46,8 +49,8 @@ export interface RemoteShareOperationRequest {
body?: RemoteShareRequest;
}
export interface RemoteUnshareRequest {
body?: Enroll200Response;
export interface RemoteUnshareOperationRequest {
body?: RemoteUnshareRequest;
}
export interface UnenrollRequest {
@ -154,7 +157,7 @@ export class AgentApi extends runtime.BaseAPI {
/**
*/
async remoteUnshareRaw(requestParameters: RemoteUnshareRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<void>> {
async remoteUnshareRaw(requestParameters: RemoteUnshareOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<void>> {
const queryParameters: any = {};
const headerParameters: runtime.HTTPHeaders = {};
@ -170,7 +173,7 @@ export class AgentApi extends runtime.BaseAPI {
method: 'POST',
headers: headerParameters,
query: queryParameters,
body: Enroll200ResponseToJSON(requestParameters['body']),
body: RemoteUnshareRequestToJSON(requestParameters['body']),
}, initOverrides);
return new runtime.VoidApiResponse(response);
@ -178,7 +181,7 @@ export class AgentApi extends runtime.BaseAPI {
/**
*/
async remoteUnshare(requestParameters: RemoteUnshareRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<void> {
async remoteUnshare(requestParameters: RemoteUnshareOperationRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<void> {
await this.remoteUnshareRaw(requestParameters, initOverrides);
}

View File

@ -0,0 +1,73 @@
/* tslint:disable */
/* eslint-disable */
/**
* zrok
* zrok client access
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
/**
*
* @export
* @interface RemoteUnshareRequest
*/
export interface RemoteUnshareRequest {
/**
*
* @type {string}
* @memberof RemoteUnshareRequest
*/
envZId?: string;
/**
*
* @type {string}
* @memberof RemoteUnshareRequest
*/
token?: string;
}
/**
* Check if a given object implements the RemoteUnshareRequest interface.
*/
export function instanceOfRemoteUnshareRequest(value: object): value is RemoteUnshareRequest {
return true;
}
export function RemoteUnshareRequestFromJSON(json: any): RemoteUnshareRequest {
return RemoteUnshareRequestFromJSONTyped(json, false);
}
export function RemoteUnshareRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): RemoteUnshareRequest {
if (json == null) {
return json;
}
return {
'envZId': json['envZId'] == null ? undefined : json['envZId'],
'token': json['token'] == null ? undefined : json['token'],
};
}
export function RemoteUnshareRequestToJSON(json: any): RemoteUnshareRequest {
return RemoteUnshareRequestToJSONTyped(json, false);
}
export function RemoteUnshareRequestToJSONTyped(value?: RemoteUnshareRequest | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'envZId': value['envZId'],
'token': value['token'],
};
}

View File

@ -42,6 +42,7 @@ export * from './RegenerateAccountTokenRequest';
export * from './RegisterRequest';
export * from './RemoteShare200Response';
export * from './RemoteShareRequest';
export * from './RemoteUnshareRequest';
export * from './RemoveOrganizationMemberRequest';
export * from './ResetPasswordRequest';
export * from './Share';

View File

@ -47,6 +47,7 @@ docs/RegenerateAccountTokenRequest.md
docs/RegisterRequest.md
docs/RemoteShare200Response.md
docs/RemoteShareRequest.md
docs/RemoteUnshareRequest.md
docs/RemoveOrganizationMemberRequest.md
docs/ResetPasswordRequest.md
docs/Share.md
@ -112,6 +113,7 @@ test/test_regenerate_account_token_request.py
test/test_register_request.py
test/test_remote_share200_response.py
test/test_remote_share_request.py
test/test_remote_unshare_request.py
test/test_remove_organization_member_request.py
test/test_reset_password_request.py
test/test_share.py
@ -182,6 +184,7 @@ zrok_api/models/regenerate_account_token_request.py
zrok_api/models/register_request.py
zrok_api/models/remote_share200_response.py
zrok_api/models/remote_share_request.py
zrok_api/models/remote_unshare_request.py
zrok_api/models/remove_organization_member_request.py
zrok_api/models/reset_password_request.py
zrok_api/models/share.py

View File

@ -189,6 +189,7 @@ Class | Method | HTTP request | Description
- [RegisterRequest](docs/RegisterRequest.md)
- [RemoteShare200Response](docs/RemoteShare200Response.md)
- [RemoteShareRequest](docs/RemoteShareRequest.md)
- [RemoteUnshareRequest](docs/RemoteUnshareRequest.md)
- [RemoveOrganizationMemberRequest](docs/RemoveOrganizationMemberRequest.md)
- [ResetPasswordRequest](docs/ResetPasswordRequest.md)
- [Share](docs/Share.md)

View File

@ -254,7 +254,7 @@ Name | Type | Description | Notes
```python
import zrok_api
from zrok_api.models.enroll200_response import Enroll200Response
from zrok_api.models.remote_unshare_request import RemoteUnshareRequest
from zrok_api.rest import ApiException
from pprint import pprint
@ -279,7 +279,7 @@ configuration.api_key['key'] = os.environ["API_KEY"]
with zrok_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = zrok_api.AgentApi(api_client)
body = zrok_api.Enroll200Response() # Enroll200Response | (optional)
body = zrok_api.RemoteUnshareRequest() # RemoteUnshareRequest | (optional)
try:
api_instance.remote_unshare(body=body)
@ -294,7 +294,7 @@ with zrok_api.ApiClient(configuration) as api_client:
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**body** | [**Enroll200Response**](Enroll200Response.md)| | [optional]
**body** | [**RemoteUnshareRequest**](RemoteUnshareRequest.md)| | [optional]
### Return type

View File

@ -0,0 +1,30 @@
# RemoteUnshareRequest
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**env_zid** | **str** | | [optional]
**token** | **str** | | [optional]
## Example
```python
from zrok_api.models.remote_unshare_request import RemoteUnshareRequest
# TODO update the JSON string below
json = "{}"
# create an instance of RemoteUnshareRequest from a JSON string
remote_unshare_request_instance = RemoteUnshareRequest.from_json(json)
# print the JSON string representation of the object
print(RemoteUnshareRequest.to_json())
# convert the object into a dict
remote_unshare_request_dict = remote_unshare_request_instance.to_dict()
# create an instance of RemoteUnshareRequest from a dict
remote_unshare_request_from_dict = RemoteUnshareRequest.from_dict(remote_unshare_request_dict)
```
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -0,0 +1,52 @@
# coding: utf-8
"""
zrok
zrok client access
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from zrok_api.models.remote_unshare_request import RemoteUnshareRequest
class TestRemoteUnshareRequest(unittest.TestCase):
"""RemoteUnshareRequest unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> RemoteUnshareRequest:
"""Test RemoteUnshareRequest
include_optional is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `RemoteUnshareRequest`
"""
model = RemoteUnshareRequest()
if include_optional:
return RemoteUnshareRequest(
env_zid = '',
token = ''
)
else:
return RemoteUnshareRequest(
)
"""
def testRemoteUnshareRequest(self):
"""Test RemoteUnshareRequest"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()

View File

@ -78,6 +78,7 @@ from zrok_api.models.regenerate_account_token_request import RegenerateAccountTo
from zrok_api.models.register_request import RegisterRequest
from zrok_api.models.remote_share200_response import RemoteShare200Response
from zrok_api.models.remote_share_request import RemoteShareRequest
from zrok_api.models.remote_unshare_request import RemoteUnshareRequest
from zrok_api.models.remove_organization_member_request import RemoveOrganizationMemberRequest
from zrok_api.models.reset_password_request import ResetPasswordRequest
from zrok_api.models.share import Share

View File

@ -22,6 +22,7 @@ from zrok_api.models.enroll_request import EnrollRequest
from zrok_api.models.ping200_response import Ping200Response
from zrok_api.models.remote_share200_response import RemoteShare200Response
from zrok_api.models.remote_share_request import RemoteShareRequest
from zrok_api.models.remote_unshare_request import RemoteUnshareRequest
from zrok_api.api_client import ApiClient, RequestSerialized
from zrok_api.api_response import ApiResponse
@ -884,7 +885,7 @@ class AgentApi:
@validate_call
def remote_unshare(
self,
body: Optional[Enroll200Response] = None,
body: Optional[RemoteUnshareRequest] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@ -902,7 +903,7 @@ class AgentApi:
:param body:
:type body: Enroll200Response
:type body: RemoteUnshareRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
@ -953,7 +954,7 @@ class AgentApi:
@validate_call
def remote_unshare_with_http_info(
self,
body: Optional[Enroll200Response] = None,
body: Optional[RemoteUnshareRequest] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@ -971,7 +972,7 @@ class AgentApi:
:param body:
:type body: Enroll200Response
:type body: RemoteUnshareRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
@ -1022,7 +1023,7 @@ class AgentApi:
@validate_call
def remote_unshare_without_preload_content(
self,
body: Optional[Enroll200Response] = None,
body: Optional[RemoteUnshareRequest] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@ -1040,7 +1041,7 @@ class AgentApi:
:param body:
:type body: Enroll200Response
:type body: RemoteUnshareRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of

View File

@ -56,6 +56,7 @@ from zrok_api.models.regenerate_account_token_request import RegenerateAccountTo
from zrok_api.models.register_request import RegisterRequest
from zrok_api.models.remote_share200_response import RemoteShare200Response
from zrok_api.models.remote_share_request import RemoteShareRequest
from zrok_api.models.remote_unshare_request import RemoteUnshareRequest
from zrok_api.models.remove_organization_member_request import RemoveOrganizationMemberRequest
from zrok_api.models.reset_password_request import ResetPasswordRequest
from zrok_api.models.share import Share

View File

@ -0,0 +1,89 @@
# coding: utf-8
"""
zrok
zrok client access
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from typing import Optional, Set
from typing_extensions import Self
class RemoteUnshareRequest(BaseModel):
"""
RemoteUnshareRequest
""" # noqa: E501
env_zid: Optional[StrictStr] = Field(default=None, alias="envZId")
token: Optional[StrictStr] = None
__properties: ClassVar[List[str]] = ["envZId", "token"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of RemoteUnshareRequest from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of RemoteUnshareRequest from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"envZId": obj.get("envZId"),
"token": obj.get("token")
})
return _obj

View File

@ -773,6 +773,8 @@ paths:
in: body
schema:
properties:
envZId:
type: string
token:
type: string
responses:

View File

@ -49,6 +49,7 @@ models/RegenerateAccountTokenRequest.ts
models/RegisterRequest.ts
models/RemoteShare200Response.ts
models/RemoteShareRequest.ts
models/RemoteUnshareRequest.ts
models/RemoveOrganizationMemberRequest.ts
models/ResetPasswordRequest.ts
models/Share.ts

View File

@ -20,6 +20,7 @@ import type {
Ping200Response,
RemoteShare200Response,
RemoteShareRequest,
RemoteUnshareRequest,
} from '../models/index';
import {
Enroll200ResponseFromJSON,
@ -32,6 +33,8 @@ import {
RemoteShare200ResponseToJSON,
RemoteShareRequestFromJSON,
RemoteShareRequestToJSON,
RemoteUnshareRequestFromJSON,
RemoteUnshareRequestToJSON,
} from '../models/index';
export interface EnrollOperationRequest {
@ -46,8 +49,8 @@ export interface RemoteShareOperationRequest {
body?: RemoteShareRequest;
}
export interface RemoteUnshareRequest {
body?: Enroll200Response;
export interface RemoteUnshareOperationRequest {
body?: RemoteUnshareRequest;
}
export interface UnenrollRequest {
@ -154,7 +157,7 @@ export class AgentApi extends runtime.BaseAPI {
/**
*/
async remoteUnshareRaw(requestParameters: RemoteUnshareRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<void>> {
async remoteUnshareRaw(requestParameters: RemoteUnshareOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<void>> {
const queryParameters: any = {};
const headerParameters: runtime.HTTPHeaders = {};
@ -170,7 +173,7 @@ export class AgentApi extends runtime.BaseAPI {
method: 'POST',
headers: headerParameters,
query: queryParameters,
body: Enroll200ResponseToJSON(requestParameters['body']),
body: RemoteUnshareRequestToJSON(requestParameters['body']),
}, initOverrides);
return new runtime.VoidApiResponse(response);
@ -178,7 +181,7 @@ export class AgentApi extends runtime.BaseAPI {
/**
*/
async remoteUnshare(requestParameters: RemoteUnshareRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<void> {
async remoteUnshare(requestParameters: RemoteUnshareOperationRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<void> {
await this.remoteUnshareRaw(requestParameters, initOverrides);
}

View File

@ -0,0 +1,73 @@
/* tslint:disable */
/* eslint-disable */
/**
* zrok
* zrok client access
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
/**
*
* @export
* @interface RemoteUnshareRequest
*/
export interface RemoteUnshareRequest {
/**
*
* @type {string}
* @memberof RemoteUnshareRequest
*/
envZId?: string;
/**
*
* @type {string}
* @memberof RemoteUnshareRequest
*/
token?: string;
}
/**
* Check if a given object implements the RemoteUnshareRequest interface.
*/
export function instanceOfRemoteUnshareRequest(value: object): value is RemoteUnshareRequest {
return true;
}
export function RemoteUnshareRequestFromJSON(json: any): RemoteUnshareRequest {
return RemoteUnshareRequestFromJSONTyped(json, false);
}
export function RemoteUnshareRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): RemoteUnshareRequest {
if (json == null) {
return json;
}
return {
'envZId': json['envZId'] == null ? undefined : json['envZId'],
'token': json['token'] == null ? undefined : json['token'],
};
}
export function RemoteUnshareRequestToJSON(json: any): RemoteUnshareRequest {
return RemoteUnshareRequestToJSONTyped(json, false);
}
export function RemoteUnshareRequestToJSONTyped(value?: RemoteUnshareRequest | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'envZId': value['envZId'],
'token': value['token'],
};
}

View File

@ -42,6 +42,7 @@ export * from './RegenerateAccountTokenRequest';
export * from './RegisterRequest';
export * from './RemoteShare200Response';
export * from './RemoteShareRequest';
export * from './RemoteUnshareRequest';
export * from './RemoveOrganizationMemberRequest';
export * from './ResetPasswordRequest';
export * from './Share';