Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from LeastAuthority/basics
Simple first steps to create a framework on which to hang real functionality. Author: exarkun Reviewer: wallrj This still doesn't do anything but now there's someplace to put code that *will* do something.
- Loading branch information
Showing
14 changed files
with
348 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[run] | ||
branch = True | ||
include = */txkube/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# | ||
# This is the Travis-CI configuration. | ||
# | ||
|
||
language: "python" | ||
|
||
# This is how you get container-based environments on Travis-CI. And | ||
# container-based environments are how you get fast test runs. | ||
sudo: false | ||
|
||
# Only build master; for "push" builds, this is when the branch pushed | ||
# to is master, for "pr" builds, this is when the merge base of the PR | ||
# is master. | ||
branches: | ||
only: | ||
- "master" | ||
|
||
cache: | ||
directories: | ||
# Cache the pip download cache across runs to avoid having to | ||
# repeatedly download packages over the network. | ||
- "$HOME/.cache/pip" | ||
|
||
install: | ||
- "pip install --upgrade pip setuptools wheel coverage codecov" | ||
- "pip install .[dev]" | ||
|
||
script: | ||
- "coverage run --rcfile=${PWD}/.coveragerc $(type -p trial) txkube" | ||
|
||
after_success: | ||
- "codecov" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/usr/bin/env python | ||
|
||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. | ||
|
||
import setuptools | ||
|
||
_metadata = {} | ||
with open("src/txkube/_metadata.py") as f: | ||
exec(f.read(), _metadata) | ||
|
||
setuptools.setup( | ||
name="txkube", | ||
version=_metadata["version_string"], | ||
description="A Twisted-based Kubernetes client.", | ||
author="txkube Developers", | ||
url="https://github.com/leastauthority.com/txkube", | ||
license="MIT", | ||
package_dir={"": "src"}, | ||
packages=setuptools.find_packages(where="src"), | ||
install_requires=[ | ||
"incremental", "twisted[tls]", | ||
], | ||
extras_require={ | ||
"dev": [ | ||
"treq", | ||
], | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. | ||
|
||
""" | ||
A Kubernetes client. | ||
""" | ||
|
||
__all__ = [ | ||
"version", | ||
"IKubernetesClient", | ||
"network_client", "memory_client", | ||
] | ||
|
||
from incremental import Version | ||
|
||
from ._metadata import version_tuple as _version_tuple | ||
version = Version("txkube", *_version_tuple) | ||
|
||
from ._interface import IKubernetes, IKubernetesClient | ||
from ._network import network_kubernetes | ||
from ._memory import memory_kubernetes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. | ||
|
||
""" | ||
Explicit interface definitions for txkube. | ||
""" | ||
|
||
from zope.interface import Attribute, Interface | ||
|
||
class IKubernetes(Interface): | ||
""" | ||
An ``IKubernetes`` provider represents a particular Kubernetes deployment. | ||
""" | ||
base_url = Attribute( | ||
"The root of the Kubernetes HTTP API for this deployment " | ||
"(``twisted.python.url.URL``)." | ||
) | ||
credentials = Attribute( | ||
"The credentials which will grant access to use the " | ||
"deployment's API." | ||
) | ||
|
||
def client(): | ||
""" | ||
Create a client which will interact with the Kubernetes deployment | ||
represented by this object. | ||
:return IKubernetesClient: The client. | ||
""" | ||
|
||
|
||
class IKubernetesClient(Interface): | ||
""" | ||
An ``IKubernetesClient`` provider allows access to the API of a particular | ||
Kubernetes deployment. | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. | ||
|
||
""" | ||
An in-memory implementation of the Kubernetes client interface. | ||
""" | ||
|
||
from zope.interface import implementer | ||
|
||
from twisted.python.url import URL | ||
|
||
from twisted.web.resource import Resource | ||
|
||
from treq.testing import RequestTraversalAgent | ||
|
||
from . import IKubernetes, network_kubernetes | ||
|
||
|
||
def memory_kubernetes(): | ||
""" | ||
Create an in-memory Kubernetes-alike service. | ||
This serves as a places to hold state for stateful Kubernetes interactions | ||
allowed by ``IKubernetesClient``. Only clients created against the same | ||
instance will all share state. | ||
:return IKubernetes: The new Kubernetes-alike service. | ||
""" | ||
return _MemoryKubernetes() | ||
|
||
|
||
@implementer(IKubernetes) | ||
class _MemoryKubernetes(object): | ||
""" | ||
``_MemoryKubernetes`` maintains state in-memory which approximates | ||
the state of a real Kubernetes deployment sufficiently to expose a | ||
subset of the external Kubernetes API. | ||
""" | ||
def __init__(self): | ||
base_url = URL.fromText(u"https://kubernetes.example.invalid./") | ||
self._resource = _kubernetes_resource() | ||
self._kubernetes = network_kubernetes( | ||
base_url=base_url, | ||
credentials=None, | ||
agent=RequestTraversalAgent(self._resource), | ||
) | ||
|
||
def client(self, *args, **kwargs): | ||
""" | ||
:return IKubernetesClient: A new client which interacts with this | ||
object rather than a real Kubernetes deployment. | ||
""" | ||
return self._kubernetes.client(*args, **kwargs) | ||
|
||
|
||
def _kubernetes_resource(): | ||
return Resource() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. | ||
|
||
""" | ||
txkube package metadata definitions. | ||
""" | ||
|
||
version_tuple = (17, 1, 0) | ||
version_string = ".".join(map(str, version_tuple)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. | ||
|
||
""" | ||
A Kubernetes client which uses Twisted to interact with Kubernetes | ||
via HTTP. | ||
""" | ||
|
||
from zope.interface import implementer | ||
|
||
import attr | ||
from attr import validators | ||
|
||
from twisted.python.reflect import namedAny | ||
from twisted.python.url import URL | ||
|
||
from twisted.web.iweb import IAgent | ||
from twisted.web.client import Agent | ||
|
||
from . import IKubernetes, IKubernetesClient | ||
|
||
def network_kubernetes(**kw): | ||
return _NetworkKubernetes(**kw) | ||
|
||
|
||
@implementer(IKubernetesClient) | ||
@attr.s(frozen=True) | ||
class _NetworkClient(object): | ||
kubernetes = attr.ib(validator=validators.provides(IKubernetes)) | ||
agent = attr.ib(validator=validators.provides(IAgent)) | ||
|
||
|
||
@implementer(IKubernetes) | ||
@attr.s(frozen=True) | ||
class _NetworkKubernetes(object): | ||
""" | ||
``_NetworkKubernetes`` knows the location of a particular | ||
Kubernetes deployment and gives out clients which speak to that | ||
deployment. | ||
""" | ||
base_url = attr.ib(validator=validators.instance_of(URL)) | ||
credentials = attr.ib() | ||
_agent = attr.ib( | ||
default=attr.Factory(lambda: Agent(namedAny("twisted.internet.reactor"))), | ||
) | ||
|
||
def client(self): | ||
return _NetworkClient(self, self._agent) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. | ||
|
||
""" | ||
Tests for ``txkube.memory_kubernetes``. | ||
""" | ||
|
||
from ..testing.integration import kubernetes_client_tests | ||
|
||
from .. import memory_kubernetes | ||
|
||
def get_kubernetes(case): | ||
""" | ||
Create an in-memory test double provider of ``IKubernetes``. | ||
""" | ||
return memory_kubernetes() | ||
|
||
|
||
class KubernetesClientIntegrationTests(kubernetes_client_tests(get_kubernetes)): | ||
""" | ||
Integration tests which interact with an in-memory-only Kubernetes | ||
deployment via ``txkube.memory_kubernetes``. | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. | ||
|
||
""" | ||
Tests for ``txkube.network_kubernetes``. | ||
See ``get_kubernetes`` for pre-requisites. | ||
""" | ||
|
||
from os import environ | ||
|
||
from twisted.python.url import URL | ||
|
||
from ..testing.integration import kubernetes_client_tests | ||
|
||
from .. import network_kubernetes | ||
|
||
def get_kubernetes(case): | ||
""" | ||
Create a real ``IKubernetes`` provider, taking necessary | ||
configuration details from the environment. | ||
To use this set: | ||
- TXKUBE_INTEGRATION_KUBERNETES_BASE_URL | ||
""" | ||
try: | ||
base_url = environ["TXKUBE_INTEGRATION_KUBERNETES_BASE_URL"] | ||
except KeyError: | ||
case.skipTest("Cannot find TXKUBE_INTEGRATION_KUBERNETES_BASE_URL in environment.") | ||
else: | ||
return network_kubernetes( | ||
base_url=URL.fromText(base_url.decode("ascii")), | ||
credentials=None, | ||
) | ||
|
||
|
||
class KubernetesClientIntegrationTests(kubernetes_client_tests(get_kubernetes)): | ||
""" | ||
Integration tests which interact with a network-accessible | ||
Kubernetes deployment via ``txkube.network_kubernetes``. | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Copyright Least Authority Enterprises. | ||
# See LICENSE for details. | ||
|
||
""" | ||
Integration test generator for ``txkube.IKubernetesClient``. | ||
""" | ||
|
||
from zope.interface.verify import verifyObject | ||
|
||
from twisted.trial.unittest import TestCase | ||
|
||
from .. import IKubernetesClient | ||
|
||
|
||
def kubernetes_client_tests(get_kubernetes): | ||
class KubernetesClientIntegrationTests(TestCase): | ||
def test_interfaces(self): | ||
""" | ||
The client provides ``txkube.IKubernetesClient``. | ||
""" | ||
kubernetes = get_kubernetes(self) | ||
client = kubernetes.client() | ||
verifyObject(IKubernetesClient, client) | ||
|
||
return KubernetesClientIntegrationTests |