Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into watch-read-timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
perj committed Jan 17, 2024
2 parents 8195fd2 + 9fb405d commit 4ec3ede
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 3 deletions.
5 changes: 3 additions & 2 deletions .semaphore/make-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ name: Publish k8s library
agent:
machine:
type: e1-standard-2
os_image: ubuntu1804
os_image: ubuntu2004
blocks:
- name: Publish
task:
Expand All @@ -30,11 +30,12 @@ blocks:
value: .pip_cache
prologue:
commands:
- sem-version python 3.9
- export PATH="${HOME}/.local/bin":"${PATH}"
- checkout
- mkdir "${PIP_CACHE_DIR}"
- cache restore "setup-${SEMAPHORE_GIT_BRANCH}-$(checksum setup.py)","setup-${SEMAPHORE_GIT_BRANCH}",setup-master
- pip install --user publish
- pip install publish
jobs:
- name: Publish
commands:
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ imagesize==1.4.1
# via sphinx
importlib-metadata==6.8.0
# via sphinx
jinja2==3.1.2
jinja2==3.1.3
# via sphinx
markupsafe==2.1.3
# via jinja2
Expand Down
20 changes: 20 additions & 0 deletions k8s/models/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,23 @@ class DeleteOptions(Model):

class LocalObjectReference(Model):
name = Field(str)


class LabelSelectorRequirement(Model):
key = Field(str)
operator = Field(str)
values = ListField(str)


class LabelSelector(Model):
matchExpressions = ListField(LabelSelectorRequirement)
matchLabels = Field(dict)


class Condition(Model):
lastTransitionTime = Field(datetime.datetime)
message = Field(str)
observedGeneration = Field(int)
reason = Field(str)
status = Field(str)
type = Field(str)
48 changes: 48 additions & 0 deletions k8s/models/policy_v1_pod_disruption_budget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env python
# -*- coding: utf-8

# Copyright 2017-2019 The FIAAS Authors
#
# 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
#
# http://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.


from .common import ObjectMeta, LabelSelector, Condition
from ..base import Model
from ..fields import Field, ListField


class PodDisruptionBudgetSpec(Model):
minAvailable = Field(str, alt_type=int)
maxUnavailable = Field(str, alt_type=int)
selector = Field(LabelSelector)
unhealthyPodEvictionPolicy = Field(str)


class PodDisruptionBudgetStatus(Model):
conditions = ListField(Condition)
currentHealthy = Field(int)
desiredHealthy = Field(int)
disruptionsAllowed = Field(int)
disruptedPods = Field(dict)
expectedPods = Field(int)
observedGeneration = Field(int)


class PodDisruptionBudget(Model):
class Meta:
list_url = "/apis/policy/v1/poddisruptionbudgets"
url_template = "/apis/policy/v1/namespaces/{namespace}/poddisruptionbudgets/{name}"

metadata = Field(ObjectMeta)
spec = Field(PodDisruptionBudgetSpec)
status = Field(PodDisruptionBudgetStatus)
102 changes: 102 additions & 0 deletions tests/k8s/test_policy_v1_pod_disruption_budget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env python
# -*- coding: utf-8

# Copyright 2017-2019 The FIAAS Authors
#
# 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
#
# http://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 mock
import pytest

from k8s.client import NotFound
from k8s.models.common import ObjectMeta, LabelSelector
from k8s.models.policy_v1_pod_disruption_budget import PodDisruptionBudget, PodDisruptionBudgetSpec

NAME = "my-name"
NAMESPACE = "my-namespace"
PDB_URI = PodDisruptionBudget._meta.url_template.format(name="", namespace=NAMESPACE)


@pytest.mark.usefixtures("logger", "k8s_config")
class TestPodDisruptionBudget(object):
def test_create_blank_pdb(self):
pdb = _create_pdb()
assert pdb.metadata.name == NAME
assert pdb.as_dict()["metadata"]["name"] == NAME

def test_pdb_created_if_not_exists(self, post, api_get):
api_get.side_effect = NotFound()
pdb = _create_pdb()
call_params = pdb.as_dict()
post.return_value.json.return_value = call_params

assert pdb._new
pdb.save()
assert not pdb._new
pytest.helpers.assert_any_call(post, PDB_URI, call_params)

def test_get_or_create_pdb_not_new(self, put, get):
mock_response = mock.Mock()
mock_response.json.return_value = {
'apiVersion': 'policy/v1',
'kind': 'PodDisruptionBudget',
'metadata': {
'creationTimestamp': '2017-10-03T10:36:20Z',
'labels': {
'app': 'my-name', 'test': 'true'
},
'name': 'my-name',
'namespace': 'my-namespace',
'resourceVersion': '852',
'uid': 'b1e35ab5-a826-11e7-ba76-0800273598c9'
},
'spec': {
'minAvailable': 1,
'selector': {
'matchLabels': {
'app': 'my-name',
},
},
},
'status': {
'currentHealthy': 1,
'desiredHealthy': 1,
'disruptedPods': {},
'expectedPods': 1,
'observedGeneration': 1
}
}
get.return_value = mock_response
pdb = PodDisruptionBudget.get(name=NAME, namespace=NAMESPACE)
assert not pdb._new
assert pdb.metadata.name == NAME
assert pdb.spec.minAvailable == 1
assert pdb.spec.selector.matchLabels["app"] == NAME
call_params = pdb.as_dict()
put.return_value.json.return_value = call_params

pdb.save()
pytest.helpers.assert_any_call(put, PDB_URI + NAME, call_params)

def test_pdb_deleted(self, delete):
PodDisruptionBudget.delete(NAME, NAMESPACE)

# call delete with service_name
pytest.helpers.assert_any_call(delete, PDB_URI + NAME)


def _create_pdb():
object_meta = ObjectMeta(name=NAME, namespace=NAMESPACE, labels={"test": "true", "app": NAME})
pdb_spec = PodDisruptionBudgetSpec(minAvailable=1, selector=LabelSelector(matchLabels={"app": NAME}))
first = PodDisruptionBudget(metadata=object_meta, spec=pdb_spec)
return first

0 comments on commit 4ec3ede

Please sign in to comment.