psytricks


Namepsytricks JSON
Version 2.1.6 PyPI version JSON
download
home_page
SummaryPowerShell Python Citrix Tricks.
upload_time2023-07-20 13:32:16
maintainer
docs_urlNone
authorNiko Ehrenfeuchter
requires_python>=3.9,<4.0
licenseGPL-3.0-or-later
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # PSytricks

![PyPI](https://img.shields.io/pypi/v/psytricks)
![PyPI - License](https://img.shields.io/pypi/l/psytricks)
![pdoc](https://img.shields.io/badge/docs-pdoc-brightgreen.svg)
![black](https://img.shields.io/badge/code%20style-black-000000.svg)

`P`ower`S`hell P`y`thon Ci`tri`x Tri`cks` - pun intended.

![logo](https://raw.githubusercontent.com/imcf/psytricks/main/resources/images/logo.png)

This package provides an abstraction layer allowing Python code to interact with
a [Citrix Virtual Apps and Desktops (CVAD)][www_cvad] stack, i.e. to fetch
status information and trigger actions on machines and sessions. Since CVAD only
provides a *PowerShell Snap-In* to do so, a core component written in `Windows
PowerShell` (note: **not** `PowerShell Core` as snap-ins are not supported
there) is required.

PSyTricks ships with two options for the PowerShell layer:

* A wrapper script that is launched as a suprocess from the Python code. It
  doesn't require any further setup beyond the package installation but
  performance, well, slow.
* A (zero-authentication) `REST` (see the note below on this) service providing
  several `GET` and `POST` endpoints to request status information or perform
  actions. Performance is *much* better compared to the wrapper script, but
  obviously this requires the code to be running as a service in an appropriate
  permission context.

NOTE: this `RESTful` claim is actually not entirely true. Or basically not at
all, it would be better called an `HTTP-JSON-RPC-API`. We'll still be using the
term `REST` for it as this is basically what people nowadays think of when they
are coming across this label. Sorry, [Roy T. Fielding][www_rtf].

## 🤯 Are you serious?

Calling PowerShell as a subprocess from within Python? 😳

To convert results to JSON and pass them back, just to parse it again in Python.
Really? 🧐

Or, not sure if that's any better, implementing an HTTP REST API in plain
PowerShell?!? 🫣

### ✅ Yes. We. Are

*And the package name was chosen to reflect this.*

To be very clear: performance of the wrapper script is abysmal, but this is *not
at all* an issue for us. Abysmal, as in: for every wrapped call a full (new)
PowerShell process needs to be instantiated, usually taking something like 1-2
seconds. ⏳

The REST interface provides a much better performance, at the cost of some
additional setup. If you're happy to take on this approach, the package offers a
very smooth ride. 🎢🎡

## 🛠🚧 Installation

### Prerequisites

As mentioned above, the *Citrix Broker PowerShell Snap-In* is required to be
installed on the machine that will run the wrapper script, since its commands
are being used to communicate with the CVAD stack. This is also the reason why
this package will work on ***Windows PowerShell only*** as snap-ins are not
supported on other PowerShell editions. Please note this also implies that the
latest usable PowerShell version is 5.1 as newer ones have dropped support for
snap-ins (but that's a different problem that Citrix will have to solve at some
point).

To install the snap-in, look for an MSI package like this in the `Delivery
Controller` or `XenDesktop` installation media and install it as usual:

* `Broker_PowerShellSnapIn_x64.msi`

### Installing the 🐍 package

In case you're planning to use `psytricks` via the subprocess approach
(discouraged but less components to set up), you will have to install the
package itself on the Windows machine having the above mentioned *Snap-In*
installed. For the `REST` approach (recommended) only the PowerShell service
described in the section below has to run on that machine - the Python package
can be installed on any computer that is able to talk to the `REST` service.

For installing `psytricks` please create and activate a `venv`, then run:

```bash
pip install psytricks
```

NOTE: this will also register the `psytricks` CLI tool although that one is
mostly meant for testing and demonstration purposes, otherwise the `*-Broker*`
commands provided by the PowerShell snap-in could be used directly.

### Setting up the REST service

The easiest way for installing the REST service is to use [WinSW (Windows
Service Wrapper)][www_winsw] but you may choose anything you like to launch the
server process like NSSM, Scheduled Tasks 📅, homegrown dark magic 🪄🔮 or
others.

To go with **WinSW** simply download the bundled version provided with each
[PSyTricks release][www_releases]. Just look for the `.zip` asset having `REST`
and `WinSW` in its name.

Unzip the downloaded file to the desired target location, e.g.
`%PROGRAMDATA%\PSyTricks`, then copy / rename `restricks-server.example.xml` to
`restricks-server.xml` and open it in an editor.

Adapt the entries in the `<serviceaccount>` section to match your requirements
and make sure to update the hostname passed via the `-AdminAddress` parameter in
the `<startarguments>` section. It needs to point to your Citrix Delivery
Controller, just in case that's not obvious.

Next step is to install and start the service:

```PowerShell
cd C:\ProgramData\PSyTricks
restricks-server.exe isntall
Start-Service RESTricksServer
```

In case the service doesn't start up, check the Windows Event Log and the `.log`
files created by WinSW in the service directory.

Once the service has started, you can monitor its actions by live-watching the
log file:

```PowerShell
Get-Content -Wait C:\ProgramData\PSyTricks\restricks-server.log
```

Tada! That's it, the service is now ready to take HTTP requests (from
`localhost`)! 🎉

Please be aware that the REST interface doesn't do **any authentication** on
purpose, meaning everything / everyone that can access it will be able to run
all requests! We're using it in combination with an SSH tunnel but essentially
anything that controls who / what can access the service will do the job.

## 🎪 What does it provide?

To interact with CVAD, a wrapper object needs to be
instantiated and instructed how to communicate with the stack.

### Using the REST service - *recommended*

After setting up the REST service as described above and making sure to be able
to connect to it (firewall rules, ssh tunnel, ...), a
`psytricks.wrapper.ResTricksWrapper` object can be used while passing the URL
under which the REST service is reachable, e.g.

```Python
from psytricks.wrapper import ResTricksWrapper

wrapper = ResTricksWrapper(base_url="http://localhost:8080/")
```

### Using the subprocess wrapper - *use with caution*

(This is only recommended for testing or if for some reason you don't want /
can't set up the REST service.)

To create a wrapper object using the subprocess variant, a
`psytricks.wrapper.PSyTricksWrapper` with the address of the *Delivery
Controller* to connect to has to be instantiated, for example:

```Python
from psytricks.wrapper import PSyTricksWrapper

wrapper = PSyTricksWrapper(deliverycontroller="cdc01.vdi.example.xy")
```

### Fetching status information

The wrapper object can then be used to e.g. retrieve information on the machines
controlled ("brokered") by Citrix:

```Python
machines = wrapper.get_machine_status()

for machine in machines:
    print(f"[{machine["DNSName"]}] is in power state '{machine["PowerState"]}'")
print(f"Got status details on {len(machines)} machines.")
```

### Performing actions

To restart a machine, use something like this:

```Python
wrapper.perform_poweraction(machine="vm23.vdi.example.xy", action="restart")
```

For placing a machine in *Maintenance Mode* use:

```Python
wrapper.set_maintenance(machine="vm42.vdi.example.xy", disable=False)
```

[www_cvad]: https://docs.citrix.com/en-us/citrix-virtual-apps-desktops
[www_winsw]: https://github.com/winsw/winsw
[www_releases]: https://github.com/imcf/psytricks/releases
[www_rtf]: https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "psytricks",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.9,<4.0",
    "maintainer_email": "",
    "keywords": "",
    "author": "Niko Ehrenfeuchter",
    "author_email": "nikolaus.ehrenfeuchter@unibas.ch",
    "download_url": "https://files.pythonhosted.org/packages/75/c6/44de2a09cf4cbdfbbf373e7d66624dd11c7163d2a246fdf88b0b09b8d585/psytricks-2.1.6.tar.gz",
    "platform": null,
    "description": "# PSytricks\n\n![PyPI](https://img.shields.io/pypi/v/psytricks)\n![PyPI - License](https://img.shields.io/pypi/l/psytricks)\n![pdoc](https://img.shields.io/badge/docs-pdoc-brightgreen.svg)\n![black](https://img.shields.io/badge/code%20style-black-000000.svg)\n\n`P`ower`S`hell P`y`thon Ci`tri`x Tri`cks` - pun intended.\n\n![logo](https://raw.githubusercontent.com/imcf/psytricks/main/resources/images/logo.png)\n\nThis package provides an abstraction layer allowing Python code to interact with\na [Citrix Virtual Apps and Desktops (CVAD)][www_cvad] stack, i.e. to fetch\nstatus information and trigger actions on machines and sessions. Since CVAD only\nprovides a *PowerShell Snap-In* to do so, a core component written in `Windows\nPowerShell` (note: **not** `PowerShell Core` as snap-ins are not supported\nthere) is required.\n\nPSyTricks ships with two options for the PowerShell layer:\n\n* A wrapper script that is launched as a suprocess from the Python code. It\n  doesn't require any further setup beyond the package installation but\n  performance, well, slow.\n* A (zero-authentication) `REST` (see the note below on this) service providing\n  several `GET` and `POST` endpoints to request status information or perform\n  actions. Performance is *much* better compared to the wrapper script, but\n  obviously this requires the code to be running as a service in an appropriate\n  permission context.\n\nNOTE: this `RESTful` claim is actually not entirely true. Or basically not at\nall, it would be better called an `HTTP-JSON-RPC-API`. We'll still be using the\nterm `REST` for it as this is basically what people nowadays think of when they\nare coming across this label. Sorry, [Roy T. Fielding][www_rtf].\n\n## \ud83e\udd2f Are you serious?\n\nCalling PowerShell as a subprocess from within Python? \ud83d\ude33\n\nTo convert results to JSON and pass them back, just to parse it again in Python.\nReally? \ud83e\uddd0\n\nOr, not sure if that's any better, implementing an HTTP REST API in plain\nPowerShell?!? \ud83e\udee3\n\n### \u2705 Yes. We. Are\n\n*And the package name was chosen to reflect this.*\n\nTo be very clear: performance of the wrapper script is abysmal, but this is *not\nat all* an issue for us. Abysmal, as in: for every wrapped call a full (new)\nPowerShell process needs to be instantiated, usually taking something like 1-2\nseconds. \u23f3\n\nThe REST interface provides a much better performance, at the cost of some\nadditional setup. If you're happy to take on this approach, the package offers a\nvery smooth ride. \ud83c\udfa2\ud83c\udfa1\n\n## \ud83d\udee0\ud83d\udea7 Installation\n\n### Prerequisites\n\nAs mentioned above, the *Citrix Broker PowerShell Snap-In* is required to be\ninstalled on the machine that will run the wrapper script, since its commands\nare being used to communicate with the CVAD stack. This is also the reason why\nthis package will work on ***Windows PowerShell only*** as snap-ins are not\nsupported on other PowerShell editions. Please note this also implies that the\nlatest usable PowerShell version is 5.1 as newer ones have dropped support for\nsnap-ins (but that's a different problem that Citrix will have to solve at some\npoint).\n\nTo install the snap-in, look for an MSI package like this in the `Delivery\nController` or `XenDesktop` installation media and install it as usual:\n\n* `Broker_PowerShellSnapIn_x64.msi`\n\n### Installing the \ud83d\udc0d package\n\nIn case you're planning to use `psytricks` via the subprocess approach\n(discouraged but less components to set up), you will have to install the\npackage itself on the Windows machine having the above mentioned *Snap-In*\ninstalled. For the `REST` approach (recommended) only the PowerShell service\ndescribed in the section below has to run on that machine - the Python package\ncan be installed on any computer that is able to talk to the `REST` service.\n\nFor installing `psytricks` please create and activate a `venv`, then run:\n\n```bash\npip install psytricks\n```\n\nNOTE: this will also register the `psytricks` CLI tool although that one is\nmostly meant for testing and demonstration purposes, otherwise the `*-Broker*`\ncommands provided by the PowerShell snap-in could be used directly.\n\n### Setting up the REST service\n\nThe easiest way for installing the REST service is to use [WinSW (Windows\nService Wrapper)][www_winsw] but you may choose anything you like to launch the\nserver process like NSSM, Scheduled Tasks \ud83d\udcc5, homegrown dark magic \ud83e\ude84\ud83d\udd2e or\nothers.\n\nTo go with **WinSW** simply download the bundled version provided with each\n[PSyTricks release][www_releases]. Just look for the `.zip` asset having `REST`\nand `WinSW` in its name.\n\nUnzip the downloaded file to the desired target location, e.g.\n`%PROGRAMDATA%\\PSyTricks`, then copy / rename `restricks-server.example.xml` to\n`restricks-server.xml` and open it in an editor.\n\nAdapt the entries in the `<serviceaccount>` section to match your requirements\nand make sure to update the hostname passed via the `-AdminAddress` parameter in\nthe `<startarguments>` section. It needs to point to your Citrix Delivery\nController, just in case that's not obvious.\n\nNext step is to install and start the service:\n\n```PowerShell\ncd C:\\ProgramData\\PSyTricks\nrestricks-server.exe isntall\nStart-Service RESTricksServer\n```\n\nIn case the service doesn't start up, check the Windows Event Log and the `.log`\nfiles created by WinSW in the service directory.\n\nOnce the service has started, you can monitor its actions by live-watching the\nlog file:\n\n```PowerShell\nGet-Content -Wait C:\\ProgramData\\PSyTricks\\restricks-server.log\n```\n\nTada! That's it, the service is now ready to take HTTP requests (from\n`localhost`)! \ud83c\udf89\n\nPlease be aware that the REST interface doesn't do **any authentication** on\npurpose, meaning everything / everyone that can access it will be able to run\nall requests! We're using it in combination with an SSH tunnel but essentially\nanything that controls who / what can access the service will do the job.\n\n## \ud83c\udfaa What does it provide?\n\nTo interact with CVAD, a wrapper object needs to be\ninstantiated and instructed how to communicate with the stack.\n\n### Using the REST service - *recommended*\n\nAfter setting up the REST service as described above and making sure to be able\nto connect to it (firewall rules, ssh tunnel, ...), a\n`psytricks.wrapper.ResTricksWrapper` object can be used while passing the URL\nunder which the REST service is reachable, e.g.\n\n```Python\nfrom psytricks.wrapper import ResTricksWrapper\n\nwrapper = ResTricksWrapper(base_url=\"http://localhost:8080/\")\n```\n\n### Using the subprocess wrapper - *use with caution*\n\n(This is only recommended for testing or if for some reason you don't want /\ncan't set up the REST service.)\n\nTo create a wrapper object using the subprocess variant, a\n`psytricks.wrapper.PSyTricksWrapper` with the address of the *Delivery\nController* to connect to has to be instantiated, for example:\n\n```Python\nfrom psytricks.wrapper import PSyTricksWrapper\n\nwrapper = PSyTricksWrapper(deliverycontroller=\"cdc01.vdi.example.xy\")\n```\n\n### Fetching status information\n\nThe wrapper object can then be used to e.g. retrieve information on the machines\ncontrolled (\"brokered\") by Citrix:\n\n```Python\nmachines = wrapper.get_machine_status()\n\nfor machine in machines:\n    print(f\"[{machine[\"DNSName\"]}] is in power state '{machine[\"PowerState\"]}'\")\nprint(f\"Got status details on {len(machines)} machines.\")\n```\n\n### Performing actions\n\nTo restart a machine, use something like this:\n\n```Python\nwrapper.perform_poweraction(machine=\"vm23.vdi.example.xy\", action=\"restart\")\n```\n\nFor placing a machine in *Maintenance Mode* use:\n\n```Python\nwrapper.set_maintenance(machine=\"vm42.vdi.example.xy\", disable=False)\n```\n\n[www_cvad]: https://docs.citrix.com/en-us/citrix-virtual-apps-desktops\n[www_winsw]: https://github.com/winsw/winsw\n[www_releases]: https://github.com/imcf/psytricks/releases\n[www_rtf]: https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven\n",
    "bugtrack_url": null,
    "license": "GPL-3.0-or-later",
    "summary": "PowerShell Python Citrix Tricks.",
    "version": "2.1.6",
    "project_urls": {
        "Changelog": "https://github.com/imcf/psytricks/blob/main/CHANGELOG.md",
        "Documentation": "https://imcf.one/apidocs/psytricks/psytricks.html",
        "Organisation Homepage": "https://imcf.one/",
        "Twitter": "https://twitter.com/imcf_basel"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "72c048a970fbf3b46b3df7387ec21ce6c8a0c9fadd54a0054ba3f497c04456fc",
                "md5": "3f1499ae50bea0e33becd98ba9da1a31",
                "sha256": "5d46c20735e19a43dd8ff62de46aa107ae35aacf259d1e4fad404befe30009f7"
            },
            "downloads": -1,
            "filename": "psytricks-2.1.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3f1499ae50bea0e33becd98ba9da1a31",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9,<4.0",
            "size": 40103,
            "upload_time": "2023-07-20T13:32:14",
            "upload_time_iso_8601": "2023-07-20T13:32:14.052231Z",
            "url": "https://files.pythonhosted.org/packages/72/c0/48a970fbf3b46b3df7387ec21ce6c8a0c9fadd54a0054ba3f497c04456fc/psytricks-2.1.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "75c644de2a09cf4cbdfbbf373e7d66624dd11c7163d2a246fdf88b0b09b8d585",
                "md5": "598829c4f9d568dcbd350c7666bba31a",
                "sha256": "d87cf82751469c4ef41d318466b2a6aa3ec0aa2c66b26f349e69c6ada208a85f"
            },
            "downloads": -1,
            "filename": "psytricks-2.1.6.tar.gz",
            "has_sig": false,
            "md5_digest": "598829c4f9d568dcbd350c7666bba31a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9,<4.0",
            "size": 38975,
            "upload_time": "2023-07-20T13:32:16",
            "upload_time_iso_8601": "2023-07-20T13:32:16.047949Z",
            "url": "https://files.pythonhosted.org/packages/75/c6/44de2a09cf4cbdfbbf373e7d66624dd11c7163d2a246fdf88b0b09b8d585/psytricks-2.1.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-07-20 13:32:16",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "imcf",
    "github_project": "psytricks",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "psytricks"
}
        
Elapsed time: 0.09310s