Monday, January 18, 2016

pmcli v1.1 realeased


I've realeased a new version of the marathon CLI 'pmcli' with the following major updates:

  • Attach to events stream with filter options
  • SSL support
  • Manage Subscriptions
  • Native proxy support
  • User defined timeout to API calls
  • Option to manually reset applications launch delay
  • Bug fixed and code cleaning

This new version, with an updated documentation can be downloaded from mygithub account



Major new funcionalities


Filters

One interesting option in marathon 0.9.0 and above is events stream, where we can watch in real time all events triggered in marathon. This is realized by an http connection never closed by the server where all the events are sent to the client as soon as are generated in marathon. This events are composed by two field: ‘event’ and ‘data’. Event it’s the event type generated and data it’s the content of this event. We can attach to this event stream by typing “pmcli marathon events”

$ pmcli marathon events
event: event_stream_attached {"remoteAddress":"92.186.41.60","eventType":"event_stream_attached","timestamp":"2016-01-18T10:59:34.436Z"} event: status_update_event {"slaveId":"dfa6bede-c570-4e14-898c-5128d8e3da50-S0","taskId":"myapp.90766c83-bdd2-11e5-a8cb-02424144e2f6","taskStatus":"TASK_RUNNING","message":"","appId":"/myapp","host":"ip-172-31-26-90.eu-central-1.compute.internal","ports":[31732],"version":"2016-01-18T10:58:56.514Z","eventType":"status_update_event","timestamp":"2016-01-18T10:59:37.913Z"} 
event: status_update_event 
{"slaveId":"dfa6bede-c570-4e14-898c-5128d8e3da50-S0","taskId":"myapp.90766c83-bdd2-11e5-a8cb-02424144e2f6","taskStatus":"TASK_FINISHED","message":"","appId":"/myapp","host":"ip-172-31-26-90.eu-central-1.compute.internal","ports":[31732],"version":"2016-01-18T10:58:56.514Z","eventType":"status_update_event","timestamp":"2016-01-18T10:59:37.954Z"} [..]

To close the connection the user must supply “Ctrl +C” As we can see in the example, ALL the events are printed to the standard output. We can filter this from pmcli using filters.

filter by event type: e[[comma separated events]] filter by data field : a[[id]:[value]]

For example, it we are only interested in “event_stream_attached” and “status_update_event” events, we can use the syntax:

$ pmcli marathon events e[status_update_event,event_stream_attached] event: event_stream_attached {"remoteAddress":"92.186.41.60","eventType":"event_stream_attached","timestamp":"2016-01-18T11:01:15.065Z"}
event: status_update_event
{"slaveId":"dfa6bede-c570-4e14-898c-5128d8e3da50-S0","taskId":"myapp.cc96ba47-bdd2-11e5-a8cb-02424144e2f6","taskStatus":"TASK_RUNNING","message":"","appId":"/myapp","host":"ip-172-31-26-90.eu-central-1.compute.internal","ports":[31443],"version":"2016-01-18T10:58:56.514Z","eventType":"status_update_event","timestamp":"2016-01-18T11:01:18.681Z"} 
event: status_update_event 
{"slaveId":"dfa6bede-c570-4e14-898c-5128d8e3da50-S0","taskId":"myapp.cc96ba47-bdd2-11e5-a8cb-02424144e2f6","taskStatus":"TASK_FINISHED","message":"","appId":"/myapp","host":"ip-172-31-26-90.eu-central-1.compute.internal","ports":[31443],"version":"2016-01-18T10:58:56.514Z","eventType":"status_update_event","timestamp":"2016-01-18T11:01:18.757Z"}
event: status_update_event
{"slaveId":"dfa6bede-c570-4e14-898c-5128d8e3da50-S0","taskId":"myapp.cf92bc38-bdd2-11e5-a8cb-02424144e2f6","taskStatus":"TASK_RUNNING","message":"","appId":"/myapp","host":"ip-172-31-26-90.eu-central-1.compute.internal","ports":[31858],"version":"2016-01-18T10:58:56.514Z","eventType":"status_update_event","timestamp":"2016-01-18T11:01:24.757Z"} [..]

Also we can filter by data field. Suppose we are only interested in “myapp” events, so the syntax would be:

$ pmcli -f jsonpp marathon events a[appId:/myapp2] 
event: status_update_event 
{  
  "timestamp": "2016-01-18T12:48:40.036Z",   
  "eventType": "status_update_event",   
  "taskStatus": "TASK_RUNNING",  
  "host": "ip-172-31-17-20.eu-central-1.compute.internal",  
  "version": "2016-01-18T12:48:39.274Z",  
  "taskId": "myapp2.cc540e36-bde1-11e5-89c2-024270636925",  
  "appId": "/myapp2",  
  "message": "",  
  "slaveId": "ecae0a10-70fa-48e3-94ea-ee6bed1c5ca2-S0",  
  "ports": [    31541  ]
}


Right now only one level in json output file can be filtered. Support for more json levels filtering support and use of logical operands with this filters is my actual objective for the next version of pmcli.

Events stream output support the four different output type: json, jsonpp, human and raw.


$ pmcli -f jsonpp marathon events a[appId:/myapp2]
event: status_update_event
{ 
   "timestamp": "2016-01-18T12:21:18.512Z",
   "eventType": "status_update_event",
   "taskStatus": "TASK_RUNNING",
   "host": "ip-172-31-17-20.eu-central-1.compute.internal",
   "version": "2016-01-18T12:21:18.175Z",
   "taskId": "myapp2.f9eba497-bddd-11e5-a8a6-024270636925",
   "appId": "/myapp2",
   "message": "",
   "slaveId": "ecae0a10-70fa-48e3-94ea-ee6bed1c5ca2-S0",
   "ports": [    31862  ]
}

Subscriptions

Another interesting marathon's functionality it's to send events to specific URL to advise system's about applications changes. This allow us to dynamically reconfigure our systems very time a change occurs within applications in marathon. For example a "scale" event can talk to a front end proxy to reconfigure for the new web servers in marathon.

This URL can be now manage from pmcli if marathon daemon is working with callback support  

$ pmcli subs register http://proxyp_ip/events 
{ "eventType": "subscribe_event",
"clientIp": "92.186.41.60",
"timestamp": "2016-01-18T12:29:46.693Z",
"callbackUrl": "http://proxyp_ip/events"}

$ pmcli subs list
{ "callbackUrls": [ "http://proxyp_ip/events" ]}

$ pmcli subs unregister http://proxyp_ip/events 
Do you really want to unregister 'http://proxyp_ip/events' ? (y/N)y{ "eventType": "unsubscribe_event",
"clientIp": "92.186.41.60",
"timestamp": "2016-01-18T12:30:15.628Z",
"callbackUrl": "http://proxyp_ip/events"}

SSL

Due to security reason it's very important our connection to marathon works with an encrypted and authenticated sessions

With pmcli v1.1 now it's possible to connect to protected marathon instances using '-S' switch. Also we can supply a certificate for the connection. 

 $ pmcli -S -C certificate.pem app list
This can be also realized from config file.

We can use SSL without certificate verification with '-N' argument, but this is not recommended for security implications. Also remember to change marathon port, by default plain http uses 8080 and ssl uses 8443.

Proxy support

As marathon api uses a RESTful API, connections from environments using proxy filtering needs to know where is this proxy. From Linux systems it's possible to define it with http_proxy and https_proxy, but pmcli now uses it's own proxy configuration. This can be done from arguments or from configuration file

$ pmcli -x http://[proxy]:[port] -X https://[ssl proxy]:[port] app list

TO DO


  • Option to filter event stream with keys with more than 2 levels depth
  • Unicode support
  • Share it from a docker container
  • Test it with python 3.x
  • Test it in other platform different than linux


I'm opened to any suggestion

No comments:

Post a Comment