diff --git a/README.md b/README.md index ae9f04f..59bc89e 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,120 @@ -# Ziti SDK for Python + + ziti logo + -## Installation +# Python SDK for OpenZiti +

+ + Discourse + + + GitHub Stars + + Downloads + + + License + +

-Ziti SDK for Python is distributed via Python Package Index(PyPI) +

+ Getting Started • + Examples • + Support • + Contributing • + License +

-```shell -pip install openziti -``` +ziggy-loves-python + +The Python SDK for [OpenZiti](https://github.com/openziti/ziti) is a library that enables you to integrate zero trust network connectivity into your Python +applications, and establish secure connections with remote network resources over an OpenZiti network. The SDK also +simplifies the process of adding secure, zero-trust network connectivity built into your Python application. It's so +simple that it can be done in just two lines of code! + +OpenZiti is an open-source project that provides secure, zero-trust networking for applications running on any platform. -## Usage +More specifically, the SDK allows you to integrate zero trust at the application level. This means your data is never +exposed outside the application environment providing you with end-to-end encryption for ultimate security. See other +zero trust models [here](https://docs.openziti.io/docs/learn/core-concepts/zero-trust-models/overview). +

+Zero-trust-application-access +

-### Identity Enrollment +## Getting Started +If you don't already have an OpenZiti network running, you can follow our [express install guides](https://docs.openziti.io/docs/learn/quickstarts/network/) +to set up the network that fits your needs. Or, you can try [CloudZiti](https://netfoundry.io/pricing/) for free, check out more [here](https://docs.openziti.io/). -Acquire [Ziti Enrollment Token](https://openziti.github.io/ziti/identities/overview.html) +### Installing the SDK + +The Python SDK for OpenZiti is distributed via the Python Package Index (PyPI) and can be installed using +[`pip`](https://pypi.org/project/openziti/) package manager. ```shell -python -m openziti enroll -j -i +pip install openziti ``` -### Environment Variables +### Using Ziti Python SDK +With just two lines of code, you can turn your plain old web server into a secure, zero-trust embedded application. +Below is an example of just how simple it is to get started. -- `ZITI_IDENTITIES` is a semi-colon-separated list of file paths to Ziti identity configuration JSON files. -- You may increase the log level of the underlying C SDK by setting environment variable `ZITI_LOG=4` (`DEBUG`). +Provide a hostname, and port for your application, a simple monkey patch, and you're ready to go. You don't even need to +know what a monkey patch is! However, if you're interested in what a monkey patch is, expand the block below. +
+ What is Monkey Patching? -### Samples + > Monkey patching allows developers to modify functionality for code even when they may not have access to the + > original source code. Because Python has a dynamic object model allowing developers to modify objects at runtime. + > Monkey patching allows developers to point a function call to any function they want. We can even implement our + > own function that doesn't exist in the source code. + > + > The way this Python SDK uses monkey patching is to override existing functionality in socket handling by the + > [socket module](https://docs.python.org/3/library/socket.html). + > + > Taking a look at the code below, the key lines are the last two. You can see how, for each monkey patched function, + > we're telling that function call on the `sock` object to be directed to the function held in `_patch_methods`. + > Therefore, this SDK can be used on any application that doesn't manage its own sockets. + > ```python + > def __init__(self, **kwargs): + > self.orig_socket = sock.socket + > sock.socket = _patchedSocket(kwargs) + > self.orig_methods = {m: sock.__dict__[m] for m, _ in + > _patch_methods.items()} + > for m_name, _ in _patch_methods.items(): + > sock.__dict__[m_name] = _patch_methods[m_name] + > ``` -We several Python SDK sample programs for clients and servers in [sample/README.md](sample/README.md). +
-## Getting Help +```python +cfg = dict(ztx=openziti.load('/path/to/identity.json'), service="name-of-ziti-service") +openziti.monkeypatch(bindings={('127.0.0.1', 8000): cfg}) +``` +Or try our decorator pattern with a function annotation +```python +@openziti.zitify(bindings={('127.0.0.1', 18080): {'ztx': '/path/to/identity.json', 'service': 'name-of-ziti-service'}}) +def yourFunction(): +``` +## Examples +Try it out yourself with one of our [examples](sample%2FREADME.md) +* [Flazk](sample/flask-of-ziti) +* [Echo Server](sample/ziti-echo-server) +* [HTTP Server](sample/ziti-http-server) +* [Ziti Requests](sample/ziti-requests) +* [Ziti Socket](sample/ziti-socket) +* [Ziti urllib3](sample/ziti-urllib3) +## Support +### Looking for Help? Please use these community resources for getting help. We use GitHub [issues](https://github.com/openziti/ziti-sdk-py/issues) for tracking bugs and feature requests and have limited bandwidth to address them. -- Read the [docs](https://openziti.github.io/ziti/overview.html) +- Read the [offical docs](https://docs.openziti.io/docs/learn/introduction/) - Join our [Developer Community](https://openziti.org) - Participate in discussion on [Discourse](https://openziti.discourse.group/) - -Copyright© 2018-2022. NetFoundry, Inc. +## Contributing +Do you want to get your hands dirty and help make OpenZiti better? Contribute to the OpenZiti open-source project +through bug reports, bug fixes, documentation, etc. Check out our guide on contributing to our projects [here](https://docs.openziti.io/policies/CONTRIBUTING.html). +## License +[Apache 2.0](./LICENSE) diff --git a/images/Ziggy-Loves-Python.svg b/images/Ziggy-Loves-Python.svg new file mode 100644 index 0000000..ecfed0b --- /dev/null +++ b/images/Ziggy-Loves-Python.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/python-flask-text.png b/images/python-flask-text.png new file mode 100644 index 0000000..a13d72e Binary files /dev/null and b/images/python-flask-text.png differ diff --git a/images/python-flask.jpg b/images/python-flask.jpg new file mode 100644 index 0000000..397ea12 Binary files /dev/null and b/images/python-flask.jpg differ diff --git a/images/ziti-logo-dark.svg b/images/ziti-logo-dark.svg new file mode 100644 index 0000000..d308722 --- /dev/null +++ b/images/ziti-logo-dark.svg @@ -0,0 +1 @@ +OPENZITI \ No newline at end of file diff --git a/images/ztaa-model-flazk.png b/images/ztaa-model-flazk.png new file mode 100644 index 0000000..7cd6ea3 Binary files /dev/null and b/images/ztaa-model-flazk.png differ diff --git a/images/ztaa-model-overview.png b/images/ztaa-model-overview.png new file mode 100644 index 0000000..7a95482 Binary files /dev/null and b/images/ztaa-model-overview.png differ diff --git a/sample/README.md b/sample/README.md index 4372a36..99f4576 100644 --- a/sample/README.md +++ b/sample/README.md @@ -1,58 +1,77 @@ -# OpenZiti Python SDK in Action +# Python SDK for OpenZiti Examples -## Sample Setup +## Setup -See [the main README](../README.md) for general setup and environment details. +In order to begin using the examples, you'll need an OpenZiti network. If you don't already have one running, you can follow our [express install guides](https://docs.openziti.io/docs/learn/quickstarts/network/) +to set up the network that fits your needs. You could also use [ZEDS](https://zeds.openziti.org) (Ziti Edge Developer Sandbox) or, you can try cloud Ziti for free, check out more [here](https://docs.openziti.io/). -- install Python requirements +### Installing the SDK +The Python SDK for OpenZiti is distributed via the Python Package Index (PyPI) and can be installed using +[`pip`](https://pypi.org/project/openziti/) package manager. + +```shell +pip install openziti +``` + +### Install Python Requirements +First, you'll need the dependent libraries used in the examples. ```bash cd ./sample pip install -r requirements ``` -- get yourself a Ziti identity from [ZEDS](https://zeds.openziti.org) - - follow enrollment instructions from the site, or better yet enroll with openziti Python module +### Get and Enroll an Identity +You need an [identity](https://docs.openziti.io/docs/learn/core-concepts/identities/overview) to be used by the example +application. If using [ZEDS](https://zeds.openziti.org) you can grab one from there, otherwise you can find all the +information you need for creating and enrolling an identity in the [doc here](https://docs.openziti.io/docs/learn/core-concepts/identities/overview#creating-an-identity). +Alternatively, if you have an identity enrollment token (JWT file), you can perform the enrollment with the Python SDK. ```bash - python -m openziti enroll --jwt= --identity= + python -m openziti enroll --jwt= --identity= ``` - the following instructions assume that Ziti identity is stored in `id.json` file - -- set `ZITI_IDENTITIES` environment variable to location of `id.json` file - +### Environment +The `ZITI_IDENTITIES` environment variable can be used to store the paths to any identity files you have. If you have +more than one identity file, you can use the `;` operator as a delimiter to provide additional identities. ```bash - export ZITI_IDENTITIES= + export ZITI_IDENTITIES= ``` -## Run Samples - -All sample scripts use predefined services in [ZEDS](https://zeds.openziti.org) - -### `flask-of-ziti/helloFlazk.py` - -Shows the use of a decorator function to monkeypatch a Flask server. - -### `h-ziti-p.py` - -Shows the use of Ziti monkeypatching standard socket to intercept network connections -and using Ziti overlay. +There is an optional environment variable `ZITI_LOG` which, by default is set to `1`. This value can be adjusted to +output more or less log information. A `ZITI_LOG` level of `6` will output `TRACE` level logs. -### `http-get.py` +### Network +Your network overlay needs to have a [Service](https://docs.openziti.io/docs/learn/core-concepts/services/overview), +and the proper [Service Configurations](https://docs.openziti.io/docs/learn/core-concepts/config-store/overview), the +documentation for which is linked. -Monkeypatch `requests.get(url)` to fetch a Ziti service with HTTP. +If you happen to be using [ZEDS](https://zeds.openziti.org) you are in luck, these examples will use default services +that are already implemented in the developer sandbox. -### `ziti-echo-server.py` +## Examples +> **Note** +> All but the Flazk example scripts use predefined services in [ZEDS](https://zeds.openziti.org) by default. -Open a socket to listen on the overlay for a particular Ziti service and send all bytes received back to the sender. +### [Flazk](flask-of-ziti) +An example showing the simplicity in integrating zero trust into a web server or API using Flask. This example also +shows how to use the decorator to apply the monkeypatch. +`flask-of-ziti/helloFlazk.py` -### `ziti-http-server.py` +### [Ziti Echo Server](ziti-echo-server) +An example showing how to open a socket to listen on the network overlay for a particular service and send all bytes +received back to the sender. -Monkeypatch `http.server` to listen for requests on the overlay. Respond to clients with a simple JSON document. +### [Ziti HTTP Server](ziti-http-server) +An example showing how to monkeypatch `http.server` to listen for HTTP requests on the network overlay. When a request +is captured, a response with a simple JSON document is sent to clients. -### `ziti-socket-sample.py` +### [Ziti Requests](ziti-requests) +An example showing the use of Ziti monkey patching a standard socket, via the requests module, to intercept network +connections using Ziti overlay. -Shows the use of _raw_ Ziti socket. +### [Ziti Socket](ziti-socket) +An example showing the use of a _raw_ Ziti socket. +### [Ziti urllib3](ziti-urllib3) +An example showing how to monkeypatch `urllib3` to fetch a Ziti service using HTTP. diff --git a/sample/flask-of-ziti/README.md b/sample/flask-of-ziti/README.md new file mode 100644 index 0000000..a88fecb --- /dev/null +++ b/sample/flask-of-ziti/README.md @@ -0,0 +1,36 @@ +# Hello Flazk +This example shows the simplicity in integrating zero trust into a web server or API using Flask. This example also +shows how to use the decorator to apply the monkeypatch. + +This is a perfect example of application to application embedded zero trust. When used in conjunction with the +[Ziti urllib3](../ziti-urllib3) example, both ends of the network are fully app-embedded zero trust applications and therefore +offer complete encryption from app to app, no unencrypted data ever leaves the application environment. +![ztaa-model-flazk.png](..%2F..%2Fimages%2Fztaa-model-flazk.png) + +## Setup :wrench: +Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity +file. + +### Install Python Requirements +If you haven't already installed them, you'll need the dependent libraries used in the examples. + ```bash + pip install -r ../requirements + ``` + +## Running the Example :arrow_forward: +This example accepts two input arguments. +1. The identity file to be used by the SDK tunneler +2. The service to bind to +```shell +python helloFlazk.py +``` + +## Testing the Example :clipboard: +By default, the base url is mapped to our `hello_world()` function. So, if we hit that endpoint we will see the +response from the function which is simply `Have some ziti`. This could be tested with +1. The [Ziti urllib3](../ziti-urllib3) example +2. The [Ziti Requests](../ziti-requests) example +3. A curl command + + curl : +4. Or simply visiting the intercept address in a browser. \ No newline at end of file diff --git a/sample/flask-of-ziti/helloFlazk.py b/sample/flask-of-ziti/helloFlazk.py index 6efd4a2..23d3187 100644 --- a/sample/flask-of-ziti/helloFlazk.py +++ b/sample/flask-of-ziti/helloFlazk.py @@ -1,4 +1,4 @@ -# Copyright (c) NetFoundry Inc. +# Copyright NetFoundry Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,17 +21,21 @@ @openziti.zitify(bindings={ - ('1.2.3.4', '18080'): bind_opts + ('127.0.0.1', 18080): bind_opts }) def runApp(): from waitress import serve - serve(app,host='1.2.3.4',port=18080) + serve(app,host='127.0.0.1',port=18080) @app.route('/') def hello_world(): # put application's code here return 'Have some Ziti!' +@app.route('/json') +def get_json(): + return '{ "name":"Ziti", "message":"Have some JSON Ziti"}' + if __name__ == '__main__': bind_opts['ztx'] = sys.argv[1] diff --git a/sample/flask-of-ziti/requirements.txt b/sample/flask-of-ziti/requirements.txt deleted file mode 100644 index 65d268e..0000000 --- a/sample/flask-of-ziti/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -flask -waitress -openziti \ No newline at end of file diff --git a/sample/http-get.py b/sample/http-get.py deleted file mode 100644 index 0b6a891..0000000 --- a/sample/http-get.py +++ /dev/null @@ -1,17 +0,0 @@ -import sys - -import urllib3 -import openziti - -# to run this sample -# set ZITI_IDENTITIES environment variable to location of your Ziti identity file -# -# python http-get.py -# url should be the intercept address of a ziti service -if __name__ == '__main__': - openziti.monkeypatch() - http = urllib3.PoolManager() - r = http.request('GET', sys.argv[1]) - print("{0} {1}".format(r.status, r.reason)) - print(r.data.decode('utf-8')) - diff --git a/sample/requirements.txt b/sample/requirements.txt index e263c09..e2e016a 100644 --- a/sample/requirements.txt +++ b/sample/requirements.txt @@ -1,2 +1,6 @@ openziti requests +flask +waitress +urllib3 +setuptools \ No newline at end of file diff --git a/sample/ziti-echo-server/README.md b/sample/ziti-echo-server/README.md new file mode 100644 index 0000000..6f1fd8a --- /dev/null +++ b/sample/ziti-echo-server/README.md @@ -0,0 +1,44 @@ +# Ziti Echo Server +This example shows how to open a socket to listen on the network overlay for a particular service and send all bytes +received back to the sender. + +## Setup :wrench: +Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity +file. + +### Install Python Requirements +If you haven't already installed them, you'll need the dependent libraries used in the examples. + ```bash + pip install -r ../requirements + ``` + +## Running the Example :arrow_forward: +This example accepts two input arguments. +1. The identity file to be used by the SDK tunneler to bind to the service +2. The service to bind to +```shell +python ziti-echo-server.py +``` + +## Testing the Example :clipboard: +Netcat can be used to test this however, in order to connect to the service over netcat you'll need an [identity](https://docs.openziti.io/docs/learn/core-concepts/identities/overview) +and a tunneler for the device running the netcat commands. An easy way to set this up is to create an identity that has +dial access on the intended service. Then run a [tunneler](https://docs.openziti.io/docs/reference/tunnelers/) on your +platform, and enroll the identity. + +If we use netcat to connect to the intercept address and send some data, we will see a response of the exact same data +we sent (hence the name, echo server). + +### Example: +```shell +nc +Hello! +``` + +### Example Output: +Using a service called `python.echo.ziti` on port `80` here is what this would look like. +```shell +nc python.echo.ziti 80 +Hello +Hello +``` \ No newline at end of file diff --git a/sample/ziti-echo-server.py b/sample/ziti-echo-server/ziti-echo-server.py similarity index 97% rename from sample/ziti-echo-server.py rename to sample/ziti-echo-server/ziti-echo-server.py index e9d0f67..137032f 100644 --- a/sample/ziti-echo-server.py +++ b/sample/ziti-echo-server/ziti-echo-server.py @@ -1,4 +1,4 @@ -# Copyright (c) NetFoundry Inc. +# Copyright NetFoundry Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/sample/ziti-http-server/README.md b/sample/ziti-http-server/README.md new file mode 100644 index 0000000..e1bf2b5 --- /dev/null +++ b/sample/ziti-http-server/README.md @@ -0,0 +1,36 @@ +# Ziti HTTP Server +This example shows how to listen for HTTP requests on a service + +## Setup :wrench: +Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity +file. + +### Install Python Requirements +If you haven't already installed them, you'll need the dependent libraries used in the examples. + ```bash + pip install -r ../requirements + ``` + +## Running the Example :arrow_forward: +We can test this example with `curl` however, in order to connect to the service over netcat you'll need an [identity](https://docs.openziti.io/docs/learn/core-concepts/identities/overview) +and a tunneler for the device running the curl command. An easy way to set this up is to create an identity that has +dial access on the intended service. Then run a [tunneler](https://docs.openziti.io/docs/reference/tunnelers/) on your +platform, and enroll the identity. + +### Example: +```shell +curl +Hello! +``` + +### Example Output: +Using a service called `python.http.ziti` on port `80` here is what this would look like. +```shell +$ curl http://python.http.ziti:80 +{"msg": "Help! I was zitified!"} +``` +And on the `ziti-http-server` side, we can see the following output showing the identity (`desktop.user`) and some +request metadata. +``` +desktop.user - - [12/Apr/2023 15:03:33] "GET / HTTP/1.1" 200 - +``` \ No newline at end of file diff --git a/sample/ziti-http-server.py b/sample/ziti-http-server/ziti-http-server.py similarity index 94% rename from sample/ziti-http-server.py rename to sample/ziti-http-server/ziti-http-server.py index 357615c..38686a3 100644 --- a/sample/ziti-http-server.py +++ b/sample/ziti-http-server/ziti-http-server.py @@ -1,4 +1,4 @@ -# Copyright (c) NetFoundry Inc. +# Copyright NetFoundry Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ import openziti -hostName = "localhost" -serverPort = 8080 +hostName = "127.0.0.1" +serverPort = 18080 cfg = dict( ztx=sys.argv[1], diff --git a/sample/ziti-requests/README.md b/sample/ziti-requests/README.md new file mode 100644 index 0000000..f742cf4 --- /dev/null +++ b/sample/ziti-requests/README.md @@ -0,0 +1,44 @@ +# Ziti Requests +This example shows the use of Ziti monkey patching a standard socket, via the requests module, to intercept network +connections using a Ziti overlay. + +## Setup :wrench: +Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity +file. + +### Install Python Requirements +If you haven't already installed them, you'll need the dependent libraries used in the examples. + ```bash + pip install -r ../requirements + ``` + +## Running the Example :arrow_forward: +This example accepts one _optional_ input argument. +1. The intercept address to bind to (if none is provided, the `httpbin.ziti` service from ZEDs will be assumed) +```shell +python ziti-requests.py +``` +This example also requires the identity file for binding to the service to be provided in the `ZITI_IDENTITIES` +environment variable. +```shell +export ZITI_IDENTITIES="/path/to/id.json" +``` + +## Testing the Example :clipboard: +One easy way to test this example is with the [Flazk example](../flask-of-ziti). Once that server is spun up and ready +to handle requests, we can run this example, sending a request to the flask server. + +### Example: +After starting up the Flazk example with a service called `python.flask.ziti`... +```shell +export ZITI_IDENTITIES= +python ziti-requests.py python.flask.ziti +``` + +### Example Output: +Using a service called `python.flask.ziti` on port `80` here is what this would look like. +```shell +$ python ziti-requests.py python.flask.ziti +{'Content-Length': '49', 'Content-Type': 'text/html; charset=utf-8', 'Date': 'Wed, 12 Apr 2023 18:56:12 GMT', 'Server': 'waitress'} +{'name': 'Ziti', 'message': 'Have some JSON Ziti'} +``` \ No newline at end of file diff --git a/sample/h-ziti-p.py b/sample/ziti-requests/ziti-requests.py similarity index 72% rename from sample/h-ziti-p.py rename to sample/ziti-requests/ziti-requests.py index 2bfcf9e..62fb022 100644 --- a/sample/h-ziti-p.py +++ b/sample/ziti-requests/ziti-requests.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022. NetFoundry, Inc. +# Copyright NetFoundry Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,12 +11,18 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +import sys import openziti import requests if __name__ == '__main__': + # Use the provided service name or a default service from ZEDS + if len(sys.argv) > 1: + service = sys.argv[1] + else: + service = 'httpbin.ziti' + with openziti.monkeypatch(): - r = requests.get('http://httpbin.ziti/json') + r = requests.get('http://' + service + '/json') print(r.headers) print(r.json()) \ No newline at end of file diff --git a/sample/ziti-socket/README.md b/sample/ziti-socket/README.md new file mode 100644 index 0000000..162e123 --- /dev/null +++ b/sample/ziti-socket/README.md @@ -0,0 +1,52 @@ +# Ziti Socket +This example shows the use of a _raw_ ziti socket. Using a raw socket will enable you to add zero trust to an +application that manages its own sockets. In an application where sockets are managed the decorator can't be used to +easily "zitify" the application. + +## Setup :wrench: +Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity +file. + +### Install Python Requirements +If you haven't already installed them, you'll need the dependent libraries used in the examples. + ```bash + pip install -r ../requirements + ``` + +## Running the Example :arrow_forward: +This example accepts two _optional_ input arguments. +1. The intercept address to bind to (if none is provided, the `httpbin.ziti` service from ZEDs will be assumed) +2. The intercept port to bind to (if none is provided, port `80` will be assumed) +```shell +python ziti-socket.py +``` +This example also requires the identity file for binding to the service to be provided in the `ZITI_IDENTITIES` +environment variable. +```shell +export ZITI_IDENTITIES="/path/to/id.json" +``` + +## Testing the Example :clipboard: +Probably the easiest way to test this example is with the [Flazk example](../flask-of-ziti). Once that server is spun +up and ready to handle requests, we can run this example, sending a request to the flask server. + +### Example: +After starting up the Flazk example... +```shell +python ziti-socket.py python.flask.ziti 80 +``` + +### Example Output: +Using a service called `python.flask.ziti` on port `80` here is what this would look like. +```shell +$ python ziti-socket.py python.flask.ziti 80 +Ziti SDK version = (b'0.31.5', b'ccbc692') +HTTP/1.1 200 OK +Content-Length: 49 +Content-Type: text/html; charset=utf-8 +Date: Mon, 10 Apr 2023 20:43:44 GMT +Server: waitress + +{ "name":"Ziti", "message":"Have some JSON Ziti"} + +``` \ No newline at end of file diff --git a/sample/ziti-socket-sample.py b/sample/ziti-socket/ziti-socket.py similarity index 74% rename from sample/ziti-socket-sample.py rename to sample/ziti-socket/ziti-socket.py index a568d78..5c8d09d 100644 --- a/sample/ziti-socket-sample.py +++ b/sample/ziti-socket/ziti-socket.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022. NetFoundry, Inc. +# Copyright NetFoundry Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,15 +11,25 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import sys import openziti from socket import SOCK_STREAM,SHUT_WR if __name__ == '__main__': + # Use the provided intercept address or a default address from ZEDS + intercept_address = 'httpbin.ziti' + if len(sys.argv) > 1: + intercept_address = sys.argv[1] + # Use the provided port + intercept_port = 80 + if len(sys.argv) > 2: + intercept_port = sys.argv[2] print("Ziti SDK version = {0}".format(openziti.version())) sock = openziti.socket(type = SOCK_STREAM) - sock.connect(('httpbin.ziti', 80)) + sock.connect((intercept_address, + 80)) msg = """GET /json HTTP/1.1\r Accept: */*\r Accept-Encoding: gzip, deflate\r diff --git a/sample/ziti-urllib3/README.md b/sample/ziti-urllib3/README.md new file mode 100644 index 0000000..de53a4b --- /dev/null +++ b/sample/ziti-urllib3/README.md @@ -0,0 +1,43 @@ +# Ziti Urllib3 +This example shows using a "zitified" urllib3 module to send a request to a server. + +## Setup :wrench: +Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity +file. + +### Install Python Requirements +If you haven't already installed them, you'll need the dependent libraries used in the examples. + ```bash + pip install -r ../requirements + ``` + +## Running the Example :arrow_forward: +This example accepts one _optional_ input argument. +1. The intercept address to bind to (if none is provided, the `httpbin.ziti` service from ZEDs will be assumed) +```shell +python ziti-urllib3.py +``` +This example also requires the identity file for binding to the service to be provided in the `ZITI_IDENTITIES` +environment variable. +```shell +export ZITI_IDENTITIES="/path/to/id.json" +``` + +## Testing the Example :clipboard: +One easy way to test this example is with the [Flazk example](../flask-of-ziti). Once that server is spun up and ready +to handle requests, we can run this example, sending a request to the flask server. + +### Example: +After starting up the Flazk example with a service called `python.flask.ziti`... +```shell +export ZITI_IDENTITIES= +python ziti-urllib3.py python.flask.ziti +``` + +### Example Output: +Using a service called `python.flask.ziti` on port `80` here is what this would look like. +```shell +$ python ziti-urllib3.py python.flask.ziti +200 OK +Have some Ziti! +``` \ No newline at end of file diff --git a/sample/ziti-urllib3/ziti-urllib3.py b/sample/ziti-urllib3/ziti-urllib3.py new file mode 100644 index 0000000..8caff2b --- /dev/null +++ b/sample/ziti-urllib3/ziti-urllib3.py @@ -0,0 +1,25 @@ +# Copyright NetFoundry Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import urllib3 +import openziti + +if __name__ == '__main__': + openziti.monkeypatch() + http = urllib3.PoolManager() + r = http.request('GET', sys.argv[1]) + print("{0} {1}".format(r.status, r.reason)) + print(r.data.decode('utf-8')) +