{ "info": { "author": "Red Hat", "author_email": "user-cont-team@redhat.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development", "Topic :: Utilities" ], "description": "# Sandcastle [![Build Status](https://ci.centos.org/job/sandcastle-master/badge/icon)](https://ci.centos.org/job/sandcastle-master/)\n\nRun untrusted code in a castle (OpenShift pod), which stands in a sandbox.\n\n\n## Usage\n\nThe prerequisite is that you're logged in an OpenShift cluster:\n```\n$ oc status\n In project Local Project (myproject) on server https://localhost:8443\n```\n\nThe simplest use case is to invoke a command in a new openshift pod:\n\n```python\nfrom sandcastle import Sandcastle\n\ns = Sandcastle(\n image_reference=\"docker.io/this-is-my/image:latest\",\n k8s_namespace_name=\"myproject\"\n)\noutput = s.run(command=[\"ls\", \"-lha\"])\n```\n\nThese things will happen:\n\n* A new pod is created, using the image set in `image_reference`.\n* The library actively waits for the pod to finish.\n* If the pod terminates with a return code greater than 0, an exception is raised.\n* Output of the command is return from the `.run()` method.\n\n\n### Sharing data between sandbox and current pod\n\nThis library allows you to share volumes between the pod it is running in and between sandbox.\n\nThere is a dedicated class and an interface to access this functionality:\n* `VolumeSpec` class\n* `volume_mounts` kwarg of Sandcastle constructor\n\nAn example is worth of thousand words:\n```python\nfrom pathlib import Path\nfrom sandcastle import Sandcastle, VolumeSpec\n\n# the expectation is that volume assigned to PVC set\n# via env var SANDCASTLE_PVC is mounted in current pod at /path\nvs = VolumeSpec(path=\"/path\", pvc_from_env=\"SANDCASTLE_PVC\")\n\ns = Sandcastle(\n image_reference=\"docker.io/this-is-my/image:latest\",\n k8s_namespace_name=\"myproject\",\n volume_mounts=[vs]\n)\ns.run()\ns.exec(command=[\"bash\", \"-c\", \"ls -lha /path\"]) # will be empty\ns.exec(command=[\"bash\", \"-c\", \"mkdir /path/dir\"]) # will create a dir\nassert Path(\"/path/dir\").is_dir() # should pass\n```\n\n#### Sharing data by copying them\n\nSandcastle is able to run the sandbox pod in a different namespace. This\nimproves security since it's trivial to lock networking of this project down -\nthe pod won't be able to access OpenShift API server nor any of your services\ndeployed in the cluster. For more info, check out [egress\nrules](https://blog.openshift.com/accessing-external-services-using-egress-router/)\nand [network\npolicy](https://docs.openshift.com/container-platform/3.6/admin_guide/managing_networking.html#admin-guide-networking-networkpolicy).\n\nWhen you set up this sandbox namespace, please make sure that service account\nof namespace your app is deployed in can manage pods in the sandbox namespace.\nThis command should help:\n```bash\n$ oc adm -n ${SANDBOX_NAMESPACE} policy add-role-to-user edit system:serviceaccount:${APP_NAMESPACE}:default\n```\n\nReal code:\n\n```python\nm_dir = MappedDir(\n local_dir, # share this dir\n sandbox_mountpoint, # make it available here\n with_interim_pvc=True # the data will be placed in a volume\n)\n\no = Sandcastle(\n image_reference=container_image,\n k8s_namespace_name=namespace, # can be a different namespace\n mapped_dir=m_dir,\n working_dir=sandbox_mountpoint,\n)\no.run()\n# happy execing\no.exec(command=[\"ls\", \"-lha\", f\"{sandbox_mountpoint}/\"])\n```\n\n## Developing sandcastle\n\nIn order to develop this project (and run tests), there are several requirements which need to be met.\n\n1. Build container images using makefile target `make test-image-build`.\n\n2. An openshift cluster and be logged into it\n\n Which means that running `oc status` should yield the cluster where you want\n to run the tests.\n\n The e2e test `test_from_pod` builds current codebase and runs the other e2e\n tests in a pod: to verify the E2E functionality. This expects that the\n openshift cluster is deployed in your current environment, meaning that\n openshift can access your local container images in your dockerd. Otherwise the\n image needs to be pushed somewhere so openshift can access it.\n\n3. In the default `oc cluster up` environment, the tests create sandbox pod\n using the default service account which is assigned to every pod. This SA\n doesn't have permissions to create nor delete pods (so the sandboxing would\n not work). With this command, the SA is allowed to change any objects in the\n namespace:\n ```\n oc adm policy add-role-to-user edit system:serviceaccount:myproject:default\n ```\n\n4. Docker binary and docker daemon running. This is implied from the first point.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/packit-service/sandcastle", "keywords": "openshift,sandbox", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "sandcastle", "package_url": "https://pypi.org/project/sandcastle/", "platform": "", "project_url": "https://pypi.org/project/sandcastle/", "project_urls": { "Homepage": "https://github.com/packit-service/sandcastle" }, "release_url": "https://pypi.org/project/sandcastle/0.1.0/", "requires_dist": [ "kubernetes (<9)" ], "requires_python": ">=3.6", "summary": "Run untrusted commands in a sandbox.", "version": "0.1.0" }, "last_serial": 5487297, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "ad7348dd35c8ba54090e18db28728c66", "sha256": "ef4e2d64838d4d3e7ce4003c13cee7e0b3e1ff2771182e7011678ffada8c9e74" }, "downloads": -1, "filename": "sandcastle-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "ad7348dd35c8ba54090e18db28728c66", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 17025, "upload_time": "2019-07-04T15:33:25", "url": "https://files.pythonhosted.org/packages/7c/7b/939c2f2a584c54b5887a64e243b35bec2548a9d6cfae1702c483f1415adb/sandcastle-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8ea7f64e3e44b8b83022e129773ce82a", "sha256": "71aea7b740b4f42acfd997d56fd4d408cc887437079c0f721ea92cb6d5eeb513" }, "downloads": -1, "filename": "sandcastle-0.1.0.tar.gz", "has_sig": false, "md5_digest": "8ea7f64e3e44b8b83022e129773ce82a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 24119, "upload_time": "2019-07-04T15:33:27", "url": "https://files.pythonhosted.org/packages/67/f5/0be9a151a3aac5ace0d508c612943cce1dbae87614db4de107a164c4613f/sandcastle-0.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ad7348dd35c8ba54090e18db28728c66", "sha256": "ef4e2d64838d4d3e7ce4003c13cee7e0b3e1ff2771182e7011678ffada8c9e74" }, "downloads": -1, "filename": "sandcastle-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "ad7348dd35c8ba54090e18db28728c66", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 17025, "upload_time": "2019-07-04T15:33:25", "url": "https://files.pythonhosted.org/packages/7c/7b/939c2f2a584c54b5887a64e243b35bec2548a9d6cfae1702c483f1415adb/sandcastle-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8ea7f64e3e44b8b83022e129773ce82a", "sha256": "71aea7b740b4f42acfd997d56fd4d408cc887437079c0f721ea92cb6d5eeb513" }, "downloads": -1, "filename": "sandcastle-0.1.0.tar.gz", "has_sig": false, "md5_digest": "8ea7f64e3e44b8b83022e129773ce82a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 24119, "upload_time": "2019-07-04T15:33:27", "url": "https://files.pythonhosted.org/packages/67/f5/0be9a151a3aac5ace0d508c612943cce1dbae87614db4de107a164c4613f/sandcastle-0.1.0.tar.gz" } ] }