A HTTP API Gateway (aka proxy) for interacting with the AppGate API. The name is a portmanteau for Controller
and kolla
, translated from a discovered rune stone in Gothenburg in Sweden meaning: “to look at the Controller”.
While we, the Customer Reliability Team, have been working with various integration projects which involved AppGate API, we learned that a tool would be handy to rapid prototyping. Eventually “the tool” became more feature rich and we started to believe it is useful for anyone working with AppGate SDP integrations.
From an educational standpoint, Conkolla allows you to:
The AppGate API can be learned and discovered in different ways. One of the common ways is to use the developer tools in a web browser while browsing through the AppGate admin UI, or use existing API Gateway or API Mocker such as postman or prism. However, with Conkolla you get another option to choose from.
Conkolla can be seen as a proxy, sitting between the user and the AppGate Controller:
The user will basically do the following steps when using Conkolla:
Conkolla (64bit) runs on macOS, Windows and linux. Download the binaries:
docker pull mar8x/conkolla-prometheus-ha:latest
docker run -p 4433:4433 mar8x/conkolla-prometheus-ha:latest --authName maraboux --authPassword maraboux
See the example deployment.yaml:
# deploy
kubectl apply -f deployment.yaml
# pfwd to app
kubectl --namespace ${NAMESPACE} port-forward \
$(kubectl get pod --namespace ${NAMESPACE} -l app=conkolla -o template \
--template "") 4433
By default Conkolla serves on https://localhost:4433
with Basic Auth. Different options to launch are available, check with Conkolla --help
for more information.
Keep the window in the background, it will reveal a good part of the interactions between client - Conkolla - Controller, and can be useful to follow the requests & responses, and payloads.
Open a cmd line or powershell, then type Conkolla.exe --authName maraboux --authPassword maraboux
.
chmod +x Conkolla
./Conkolla --authName maraboux --authPassword maraboux
you will see a start message, something like this:
./Conkolla
"copyright": "Cyxtera Technologies 2019 (marx@cyxtera.com)",
"date": "2019-10-29",
"directory": "/go/bin",
"certPath": "templates/cert.pem",
"keyPath": "templates/key.pem",
"url": "https://0.0.0.0:4433",
"tls": true,
"mode": "release",
"version": "6.1.4 (ha:7837)",
"defaultAPIVersion": 10,
"operatingSystem": "linux",
"memoryUsageMBbase2": 68.43773651123047,
"numberGoRoutines": 1,
"systemTime": "10-30-2019 10:22:51",
"systemTimeZone": "UTC",
"basicAuthentication": true,
"conkollaID": "",
"defaultClientConnectionParameters": {
"tcpTimeoutSeconds": 10,
"tlsHandshakeTimeoutSeconds": 7,
"requestTimeoutSeconds": 15,
"keepAliveSeconds": 30,
"maxIdleConnections": 100,
"idleConnTimeoutSeconds": 90,
"expectContinueTimeoutSeconds": 1
}
}
{
"9e94bbba0aaa": [
"127.0.0.1/8",
"172.17.0.2/16"
]
}
At this stage you will need to have a user with admin permission and privileges to read or write AppGate objects. For more information read:
Make sure you know where Conkolla is serving:
https://localhost:4433
Check the examples page for how to connect via command line.
It is recommended to use chrome browser (tested only in chrome/ECMAScript2018 or later). The browser helps user to quickly work against the Controller API. The UI supports
{id}
.You can only update or create one entity (for example an appliance or entitlement) with a single request. Hence you will need to have a single entity in the editor window (for create or update at least). If you need to manipulate multiple entities use the developer mode in chrome and manipulate records with JavaScript. Check the advanced page for details:
Rest calls towards an AppGate Controller are in the form of:
https://{URL}:{PORT}/admin/{RESOURCE or PATH}
where as:
URL
is the Controllers URLPORT
: the port of the admin access, default is 444
RESOURCE or PATH
: the actual rest resourceExample:
https://cc1.packnot.com:444/admin/stats/appliances
Note the separation of the different calls:
proxy call
upstream call
The first one is what the user will use to make calls, where the second is always initiated by Conkolla.
In Conkolla, a you always reference a connection; a connection which you previously logged into. Example, the same rest-call as above, you would specify it by referencing to connection 1
or cc1.packnot.comdev
:
https://localhost:4433/get/1/stats/appliances
https://localhost:4433/get/cc1.packnot.comdev/stats/appliances
From the command line:
curl -k -X POST -H "Accept: application/json" https://localhost:4433/get/1/appliances
Use always method POST
for the proxy call. The upstream HTTP method is included in the proxy call’s path.
Note: you need to drop the /admin
part of the path. Do not specify the /admin
part in the path for the rest call. Conkolla adds it automatically on the upstream call.
Upstream Call Method | Proxy Call Method | Description | Proxy Call Parameters |
---|---|---|---|
GET | POST | Get entitites. | restCall |
POST | POST | Create new entities. | restCall objectData |
PUT | POST | Change entities. | restCall objectData |
DELETE | POST | Delete entities | restCall |
restCall
: the upstream rest call, example: /entitlements/0c32530f-e15b-4720-a261-acae73c3d417
.
objectData
: the payload (JSON data in the body).
Check the examples page.
Either you browse the login form from the UI or get the possible options/fields from a rest call. Note there might be more options from the rest call than on the web login form:
curl -k -H "Accept: application/json" https://localhost:4433/login/
{
"accept_header_suffix": "+json",
"api_version": 11,
"content_type_header": "application/json",
"loginFormFields": {
"controllerURL": "",
"controllerPort": 0,
"username": "",
"password": "",
"otp": "",
"providerName": "",
"apiVersion": 0,
"acceptHeaderSuffix": "",
"contentTypeHeader": "",
"label": "",
"machineId": "",
"hideToken": "",
"skipVerifySSL": "",
"dumpAGResponse": "",
"autoTokenRenewal": "",
"renewToken": "",
"promCollector": "",
"promTargetName": "",
"promLabelExporter": "",
"promLabelEnvironment": "",
"promLabelGroup": "",
"promLabelSite": "",
"promLabelRegion": "",
"promLabelCountry": "",
"promLabelCustomer": "",
"promLabelCostID": ""
},
"pageinfo": "login page"
}
Note that the form data and the JSON data render to the same attributes and some boolean values might be therefore treated as a non-empty value instead as real booleans. Absence signifies false
where presence of any value signifies true
Param | Value | Description |
---|---|---|
label | String:text | Labels a connection with the given text. Allows you to connect many times to same AppGate Controller under different label. Labels allows you also to do bulk rest calls and help you sort and find connections. Any space in the will be replaced with - . |
otp | String:number | if the user account uses MFA, enter the next MFA code here. Supports only built-in MFA. |
acceptHeaderSuffix | +json or +gpg |
Default +json, +gpg is used for downloading backup files. You can change it after login. |
apiVersion | Integer:number | specifies what AppGate API version to indicate in the upstream headers, usually defaults ok.You can change it after login. |
machineID | String:UUIDv4 | A UUIDv4 string to identify Conkolla as a client ID towards AppGate Controller. None or faulty given, Conkolla generates a random one. |
hideToken | String:"true" or "" |
Disables any display/retrieval of the token for the AppGate connection for security reasons. |
dumpAGResponse | String:"true" or "" |
Conkolla will log the the request and response send to the upstream server. Good for debugging or curious people. |
autoTokenRenewal | String:"true" or "" |
Conkolla will renew the token if it will expire in less than 5 minutes from now. Also, you will be able to force renewal of tokens by the /renewtoken call (see below). Auto Renew does not work when using MFA. |
renewToken | String:"true" or "" |
Setting this flag allows you to renew the token for an existing connection with a login request. The fields to identify existing connection are: controllerURL and label . The required field to renew token is: password (and otp if required). |
promCollector | String:"true" or "" |
Setting this flag allows you enable prometheus exporter for the connected collective. It acts like a pull gateway exported, reflecting all metrics of the AppGate collective |
Proxy API to a connected Controller connection follows the scheme:
{HTTPS or HTTP}://{HOST}:{PORT}{UPSTREAM HTTP METHOD}/{CONNECTION}/{UPSTREAM RESTCALL} :: {BODY}
UPSTREAM HTTP METHOD
The method to be used in the upstream rest call:
CONNECTION
: every connection has two references which can be used in Conkolla proxying calls, either
ID
assigned by Conkolla at login time,{ControllerURL}{label}
.UPSTREAM RESTCALL
/admin
in the path.BODY
Proxy Method
: Always use POST
(this covers all upstream calls which are embedded in the proxy rest call).
Path | Method | Description |
---|---|---|
/settings |
GET | Displays Conkolla and runtime information. |
/login |
POST GET | Login form, login JSON params, do login on a Controller. |
/apispec |
GET | Displays the on-board apispec (might be outdated, use the linked from the menu for reference). |
These are related to the AppGate connection and might do rest calls to upstream AppGate Controllers.
Path | Method | Description |
---|---|---|
/agc/{connection}/conf |
GET POST | Display, change the connection settings for a Controller. |
/agc/{connection}/headers |
GET | Download a file containing the headers for upstream calls for this connection |
/agc/{connection}/renewtoken |
GET | Renews the user and entitlement token for this connection. Only supported if no MFA is used and connection is set to ‘Auto renew tokens’ at login time. |
Note: /renewtoken
is currently controlled via a GET
whereas it would be more reasonable with a PUT
– this might change in the future.
Note these calls will always do rest calls to upstream AppGate Controllers.
Path | Method | Description |
---|---|---|
/stats/{connection}/{label} |
GET | Retrieves stats from connected Controller(s). Displaying single stats: /stats/{connection}/ , where connection is a reference for the connection. Display stats of all connected Controllers: /stats/0/ . Display the stats for a certain label: /stats/0/{label} . |
/revoke/{connection}/{label} |
GET | Revokes the tokens for the connection. Revoking single connection: /revoke/{connection}/ , where connection is a reference for the connection. Revoke all connected Controllers: /revoke/0/ . Revoke for all Controllers under a certain label: /revoke/0/{label} . |
/forget/{connection}/{label} |
GET | Revokes and removes the connection. Revoking & remove single connection: /revoke/{connection}/ , where connection is a reference for the connection. Revoke & remove all connected Controllers: /revoke/0/ . Revoke & remove for all Controllers under a certain label: /revoke/0/{label} . |
Note: the /stats
, /revoke
and /forget
are not typical rest resources and will operate on one or many connections. For now we use method GET
while this might change in the future.