So this would go something like:
- define a new config type
- create a new config of that type
- use that type on your services
ziti edge create config-type myconfig '{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "data": { "type": "array", "items": [ { "type": "object", "properties": { "port": { "type": "integer" }, "kind": { "type": "string" } }, "required": [ "port", "kind" ] } ] } }, "required": [ "data" ]}'
ziti edge create config myconfig.instance myconfig '{ "data": [ { "port": 1234, "kind": "java" }, { "port": 5678, "kind": "python" }, { "port": 9876, "kind": "javascript" } ]}'
ziti edge create service myconfig.service --configs "myconfig.instance"
Then, in your agent, it would ask for the config type "myconfig", read the json, and decide how to offload data. Without seeing the code it's hard to know for sure if that's what you're after, but that's the thing that comes to my mind
You get the idea pretty well the only difference is how the port forwarding works.
So the main ports that are used are 13337 for code-server to expose the local editor to the end user and the vnc port (can't remember the number but it's another static port). Those are simple since we know at provision time which of those the end user will want. The hard part is the dymanic ports.
Imagine you're working on a react app in the platform, you're going to want to run the app and view the local dev server to see the project as you build it. So the way it currently works is there is a tailscale connection to the agent from the server which basically exposes the entire local network of the pod to the main application server and then we perform application level auth to decide if we will expose the requested port to the user. So if you start your app you can open the local dev server @ https://-<workspace_id>.gigo.dev and when we get that request we can say from your cookies that you do own the workspace in question and permit the traffic to flow.
Are the configs parsed by the ziti system itself or is it a pass through to the edge nodes? Since it's a dynamic schema it seems like I can do whatever I want with the config
This seems to affirm my suspicion that the config is entirely dynamic
You make the config-type first, backed by a schema. Then you make an "instance" of that config type called just config
. You then can associate that instance of a config to your service and your agent woudl be able to get that config when it 'binds' that service.
Config types are parsed for validity, and configs are parsed for validity against the config-type (json schema) but that's the only 'parsing'. If that's what you mean?
I can expand on the reasons but as a simple question, how bad would it be to pass the config info in the name of the service instead of a config? All I need to share is a port and a net type: gigo-agent-<id>-tcp:3000
I mean. It seems reasonable to me. There might be a more idiomatic openziti way to do it but getting "something" working is always a great first step. I still haven't quite had time to digest/appreciate the problem yet. (I should get back to it later) But working code is working code. If that keeps you moving, go for it. Nothing comes to mind immediately as "oh no that's a bad idea".
Ok. I was able to give your post a bit of brainpower and let it sit to try to understand. When that request comes into https://-<workspace_id>.gigo.dev
, you want the user to land at their react app in that case? do I understand that properly? So you need to be able to dynamically send the port to the far side.
Another thing came to mind for this. I think you want to use DialOptions... DialOptions are a blob of data that the dialing (your server) side can send to the terminating (binding) side. You could put json or serialize an int or whatever you want in there. When you dial, you use "DialWithOptions" and set the appata. On the far side when you accept a new connection, you read the appdata with conn.GetAppData()
. It's on you to know if it's json, or protobuf or xml or whatever... But that would allow your server to send a port dynamically.
I think that'd solve the issue for you too.
Oh hell ya! That's so perfect
1 Like
Are JWTs only available once? When I attempt to fetch the identity details a second time i doesn't return one
Yes. The JWT one gets from an identity are used for enrollment and are single use tokens. Once used the enrollment is removed. Identities are secrets and should be treated as such.
Okay thanks, good to know!
Here's my first pass at it. Agent will run on the pods agent instance and will receive the token through the bootstrap process. Once the agent comes online it will initialize and begin listening on the service. The Server will be used by server instances to dial Agents when we go to proxy requests.
nice! I'll give it a look
Nice! As a side note, I see some tests too. If you need it, you can setup a super fast/easy local environment for testing things with ziti edge quickstart
. That'll boot you up an ephemeral OpenZiti overlay network you can play with that's good for local testing. When the process exits it'll clean itself up. We haven't updated our doc to include that yet but it's gonna come soon i expect.
I just built the ziti docker compose into our dev compose. The project has a really dense external dependency set so we just ship a production like compose with the code and that way we can run real tests against things like ziti, nats, etcd, ...
1 Like
Is there anyway to get the network stats of a service
We use the network monitoring to ensure we don't close a pod on someone whos working in a way that we can't see with other metrics
The controller emits metrics. You can ship them with a log shipper or use the prometheus scrape target. Overview | OpenZiti
The CloudZiti offering uses these along with a data lake to produce useful dashboards like this. I suspect that'll have what you need. (i think?)
That looks like it will have everything I need!