Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to use kubectl to work around kubernetes-client/python#411 #813

Merged
merged 4 commits into from
May 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions k8s/tools/block-aws/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,26 @@ ENV PYTHONUNBUFFERED=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1

# add non-priviledged user
RUN adduser --uid 1000 --disabled-password --gecos '' --no-create-home webdev
RUN adduser --uid 1000 --disabled-password --gecos '' --no-create-home blocker

# end from Dockerfile.footer

WORKDIR /app

# Install app
COPY block-aws.py /app/block-aws.py
COPY block_aws.py /app/block_aws.py
COPY requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

CMD ["python", "/app/block-aws.py"]
# Install kubectl
# to get latest version: "curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt"
ENV KUBECTL_VERSION="v1.10.1"
ADD https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl /usr/local/bin/kubectl
RUN chmod +x /usr/local/bin/kubectl

CMD ["python", "/app/block_aws.py"]

# Change User
RUN chown webdev.webdev -R .
USER webdev
RUN chown blocker.blocker -R .
USER blocker

2 changes: 1 addition & 1 deletion k8s/tools/block-aws/block-aws-cron.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ spec:
spec:
containers:
- name: block-aws-cron
image: quay.io/mozmar/blockaws:1f888cb
image: quay.io/mozmar/blockaws:0905680
env:
- name: DMS_URL
valueFrom:
Expand Down
20 changes: 20 additions & 0 deletions k8s/tools/block-aws/block-aws-networkpolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: v1
items:
- apiVersion: extensions/v1beta1
kind: NetworkPolicy
metadata:
name: block-aws
spec:
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.0.0/16
podSelector:
matchExpressions:
- key: k8s-app
operator: DoesNotExist
policyTypes:
- Egress
kind: List
65 changes: 0 additions & 65 deletions k8s/tools/block-aws/block-aws.py

This file was deleted.

113 changes: 113 additions & 0 deletions k8s/tools/block-aws/block_aws.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"""
This script iterates through all k8s namespaces and installs a NetworkPolicy
that blocks the AWS metadata service (169.254.0.0/16). Namespaces can
be whitelisted via the WHITELISTED_NAMESPACES list, with kube-system
being whitelisted by default (meaning we don't install this particular
network policy in kube-system, but others may be installed in kube-system
via some other method).
"""

from collections import defaultdict
import os

from kubernetes import client, config
from munch import munchify
import requests
import sh
import yaml

WHITELISTED_NAMESPACES = os.getenv('WHITELISTED_NAMESPACES',
'kube-system').split(',')
AWS_NETWORK_POLICY_NAME = os.getenv('AWS_NETWORK_POLICY_NAME', 'block-aws')
POLICY_FILENAME = os.getenv('POLICY_FILENAME', 'block-aws-networkpolicy.yaml')
DMS_URL = os.getenv('DMS_URL')
USE_KUBECTL = os.getenv('USE_KUBECTL', True)
IN_CLUSTER = os.getenv('IN_CLUSTER', True)

if IN_CLUSTER:
config.load_incluster_config()
else:
config.load_kube_config()


def kubemunch(*args):
kubectl = sh.kubectl.bake('-o', 'yaml')
munched = munchify(yaml.load(kubectl(args).stdout))
if 'items' in munched.keys():
# override items method
munched.items = munched['items']
return munched


def namespace_network_policy_names(use_kubectl=USE_KUBECTL):
if use_kubectl:
policies = kubemunch('get', 'netpol', '--all-namespaces').items
else:
v1beta1 = client.ExtensionsV1beta1Api()
policies = v1beta1.list_network_policy_for_all_namespaces().items

ns_policies = defaultdict(list)
for policy in policies:
ns_policies[policy.metadata.namespace].append(policy.metadata.name)
return ns_policies


def namespaces(use_kubectl=USE_KUBECTL):
if use_kubectl:
return [ns.metadata.name for ns in kubemunch('get', 'ns').items]
else:
v1 = client.CoreV1Api()
return [ns.metadata.name for ns in v1.list_namespace().items]


def create_policy(namespace, use_kubectl=USE_KUBECTL):
if use_kubectl:
response = kubemunch('create', '-n', namespace, '-f', POLICY_FILENAME)
else:
md = client.V1ObjectMeta(name=AWS_NETWORK_POLICY_NAME,
namespace=namespace)
match_expression = client.V1LabelSelectorRequirement(
key='k8s-app', operator='DoesNotExist')
pod_selector = client.V1LabelSelector(
match_expressions=[match_expression])

ip_block = client.V1beta1IPBlock(
cidr='0.0.0.0/0', _except=['169.254.0.0/16'])
peer = client.V1beta1NetworkPolicyPeer(ip_block=ip_block)
egress = client.V1beta1NetworkPolicyEgressRule(to=[peer])
spec = client.V1beta1NetworkPolicySpec(
pod_selector=pod_selector,
egress=[egress],
policy_types=['Egress'])
policy = client.V1beta1NetworkPolicy(metadata=md, spec=spec)
networkingv1 = client.NetworkingV1Api()
response = networkingv1.create_namespaced_network_policy(namespace,
policy)
print("\tCreated {} in ns {}".format(response.metadata.name,
response.metadata.namespace))


def ping_dms():
if DMS_URL:
print("Notifying DMS")
r = requests.get(DMS_URL)
print(r.status_code)
else:
print('DMS_URL not found, not notifying DMS')


def main():
ns_policies = namespace_network_policy_names()
for namespace in namespaces():
print("-> ", namespace)
if namespace in WHITELISTED_NAMESPACES:
print("\tskipping, ns whitelisted")
elif AWS_NETWORK_POLICY_NAME not in ns_policies[namespace]:
create_policy(namespace)
else:
print("\tAWS already blocked")
ping_dms()


if __name__ == '__main__':
main()
2 changes: 2 additions & 0 deletions k8s/tools/block-aws/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
kubernetes
munch
requests
sh