mirror of https://github.com/helm/helm
parent
fb0e722ed9
commit
e46a1eb752
Binary file not shown.
@ -0,0 +1,7 @@
|
|||||||
|
name: replicatedservice
|
||||||
|
description: Port of the replicatedservice template from kubernetes/charts
|
||||||
|
version: 3
|
||||||
|
expander:
|
||||||
|
name: Expandybird
|
||||||
|
entrypoint: templates/replicatedservice.py
|
||||||
|
schema: templates/replicatedservice.py.schema
|
@ -0,0 +1,195 @@
|
|||||||
|
"""Defines a ReplicatedService type by creating both a Service and an RC.
|
||||||
|
|
||||||
|
This module creates a typical abstraction for running a service in a
|
||||||
|
Kubernetes cluster, namely a replication controller and a service packaged
|
||||||
|
together into a single unit.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
SERVICE_TYPE_COLLECTION = 'Service'
|
||||||
|
RC_TYPE_COLLECTION = 'ReplicationController'
|
||||||
|
|
||||||
|
|
||||||
|
def GenerateConfig(context):
|
||||||
|
"""Generates a Replication Controller and a matching Service.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
context: Template context. See schema for context properties
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A Container Manifest as a YAML string.
|
||||||
|
"""
|
||||||
|
# YAML config that we're going to create for both RC & Service
|
||||||
|
config = {'resources': []}
|
||||||
|
|
||||||
|
name = context.env['name']
|
||||||
|
container_name = context.properties.get('container_name', name)
|
||||||
|
namespace = context.properties.get('namespace', 'default')
|
||||||
|
|
||||||
|
# Define things that the Service cares about
|
||||||
|
service_name = context.properties.get('service_name', name + '-service')
|
||||||
|
service_type = SERVICE_TYPE_COLLECTION
|
||||||
|
|
||||||
|
# Define things that the Replication Controller (rc) cares about
|
||||||
|
rc_name = context.properties.get('rc_name', name + '-rc')
|
||||||
|
rc_type = RC_TYPE_COLLECTION
|
||||||
|
|
||||||
|
service = {
|
||||||
|
'name': service_name,
|
||||||
|
'type': service_type,
|
||||||
|
'properties': {
|
||||||
|
'apiVersion': 'v1',
|
||||||
|
'kind': 'Service',
|
||||||
|
'namespace': namespace,
|
||||||
|
'metadata': {
|
||||||
|
'name': service_name,
|
||||||
|
'labels': GenerateLabels(context, service_name),
|
||||||
|
},
|
||||||
|
'spec': {
|
||||||
|
'ports': [GenerateServicePorts(context, container_name)],
|
||||||
|
'selector': GenerateLabels(context, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_up_external_lb = context.properties.get('external_service', None)
|
||||||
|
if set_up_external_lb:
|
||||||
|
service['properties']['spec']['type'] = 'LoadBalancer'
|
||||||
|
cluster_ip = context.properties.get('cluster_ip', None)
|
||||||
|
if cluster_ip:
|
||||||
|
service['properties']['spec']['clusterIP'] = cluster_ip
|
||||||
|
config['resources'].append(service)
|
||||||
|
|
||||||
|
rc = {
|
||||||
|
'name': rc_name,
|
||||||
|
'type': rc_type,
|
||||||
|
'properties': {
|
||||||
|
'apiVersion': 'v1',
|
||||||
|
'kind': 'ReplicationController',
|
||||||
|
'namespace': namespace,
|
||||||
|
'metadata': {
|
||||||
|
'name': rc_name,
|
||||||
|
'labels': GenerateLabels(context, rc_name),
|
||||||
|
},
|
||||||
|
'spec': {
|
||||||
|
'replicas': context.properties['replicas'],
|
||||||
|
'selector': GenerateLabels(context, name),
|
||||||
|
'template': {
|
||||||
|
'metadata': {
|
||||||
|
'labels': GenerateLabels(context, name),
|
||||||
|
},
|
||||||
|
'spec': {
|
||||||
|
'containers': [
|
||||||
|
{
|
||||||
|
'env': GenerateEnv(context),
|
||||||
|
'name': container_name,
|
||||||
|
'image': context.properties['image'],
|
||||||
|
'ports': [
|
||||||
|
{
|
||||||
|
'name': container_name,
|
||||||
|
'containerPort': context.properties['container_port'],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set up volume mounts
|
||||||
|
if context.properties.get('volumes', None):
|
||||||
|
rc['properties']['spec']['template']['spec']['containers'][0]['volumeMounts'] = []
|
||||||
|
rc['properties']['spec']['template']['spec']['volumes'] = []
|
||||||
|
for volume in context.properties['volumes']:
|
||||||
|
# mountPath should be unique
|
||||||
|
volume_name = volume['mount_path'].replace('/', '-').lstrip('-') + '-storage'
|
||||||
|
rc['properties']['spec']['template']['spec']['containers'][0]['volumeMounts'].append(
|
||||||
|
{
|
||||||
|
'name': volume_name,
|
||||||
|
'mountPath': volume['mount_path']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
del volume['mount_path']
|
||||||
|
volume['name'] = volume_name
|
||||||
|
rc['properties']['spec']['template']['spec']['volumes'].append(volume)
|
||||||
|
|
||||||
|
if context.properties.get('privileged', False):
|
||||||
|
rc['properties']['spec']['template']['spec']['containers'][0]['securityContext'] = {
|
||||||
|
'privileged': True
|
||||||
|
}
|
||||||
|
|
||||||
|
config['resources'].append(rc)
|
||||||
|
return yaml.dump(config)
|
||||||
|
|
||||||
|
|
||||||
|
# Generates labels either from the context.properties['labels'] or generates
|
||||||
|
# a default label 'name':name
|
||||||
|
def GenerateLabels(context, name):
|
||||||
|
"""Generates labels from context.properties['labels'] or creates default.
|
||||||
|
|
||||||
|
We make a deep copy of the context.properties['labels'] section to avoid
|
||||||
|
linking in the yaml document, which I believe reduces readability of the
|
||||||
|
expanded template. If no labels are given, generate a default 'name':name.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
context: Template context, which can contain the following properties:
|
||||||
|
labels - Labels to generate
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A dict containing labels in a name:value format
|
||||||
|
"""
|
||||||
|
tmp_labels = context.properties.get('labels', None)
|
||||||
|
ret_labels = {'name': name}
|
||||||
|
if isinstance(tmp_labels, dict):
|
||||||
|
for key, value in tmp_labels.iteritems():
|
||||||
|
ret_labels[key] = value
|
||||||
|
return ret_labels
|
||||||
|
|
||||||
|
|
||||||
|
def GenerateServicePorts(context, name):
|
||||||
|
"""Generates a ports section for a service.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
context: Template context, which can contain the following properties:
|
||||||
|
service_port - Port to use for the service
|
||||||
|
target_port - Target port for the service
|
||||||
|
protocol - Protocol to use.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A dict containing a port definition
|
||||||
|
"""
|
||||||
|
container_port = context.properties['container_port']
|
||||||
|
target_port = context.properties.get('target_port', container_port)
|
||||||
|
service_port = context.properties.get('service_port', target_port)
|
||||||
|
protocol = context.properties.get('protocol')
|
||||||
|
|
||||||
|
ports = {}
|
||||||
|
if name:
|
||||||
|
ports['name'] = name
|
||||||
|
if service_port:
|
||||||
|
ports['port'] = service_port
|
||||||
|
if target_port:
|
||||||
|
ports['targetPort'] = target_port
|
||||||
|
if protocol:
|
||||||
|
ports['protocol'] = protocol
|
||||||
|
|
||||||
|
return ports
|
||||||
|
|
||||||
|
def GenerateEnv(context):
|
||||||
|
"""Generates environmental variables for a pod.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
context: Template context, which can contain the following properties:
|
||||||
|
env - Environment variables to set.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A list containing env variables in dict format {name: 'name', value: 'value'}
|
||||||
|
"""
|
||||||
|
env = []
|
||||||
|
tmp_env = context.properties.get('env', [])
|
||||||
|
for entry in tmp_env:
|
||||||
|
if isinstance(entry, dict):
|
||||||
|
env.append({'name': entry.get('name'), 'value': entry.get('value')})
|
||||||
|
return env
|
@ -0,0 +1,91 @@
|
|||||||
|
info:
|
||||||
|
title: Replicated Service
|
||||||
|
description: |
|
||||||
|
Defines a ReplicatedService type by creating both a Service and an RC.
|
||||||
|
|
||||||
|
This module creates a typical abstraction for running a service in a
|
||||||
|
Kubernetes cluster, namely a replication controller and a service packaged
|
||||||
|
together into a single unit.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- image
|
||||||
|
|
||||||
|
properties:
|
||||||
|
container_name:
|
||||||
|
type: string
|
||||||
|
description: Name to use for container. If omitted, name is used.
|
||||||
|
service_name:
|
||||||
|
type: string
|
||||||
|
description: Name to use for service. If omitted, name-service is used.
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
description: Namespace to create resources in. If omitted, 'default' is
|
||||||
|
used.
|
||||||
|
default: default
|
||||||
|
protocol:
|
||||||
|
type: string
|
||||||
|
description: Protocol to use for the service.
|
||||||
|
service_port:
|
||||||
|
type: int
|
||||||
|
description: Port to use for the service.
|
||||||
|
target_port:
|
||||||
|
type: int
|
||||||
|
description: Target port to use for the service.
|
||||||
|
container_port:
|
||||||
|
type: int
|
||||||
|
description: Port to use for the container.
|
||||||
|
replicas:
|
||||||
|
type: int
|
||||||
|
description: Number of replicas to create in RC.
|
||||||
|
image:
|
||||||
|
type: string
|
||||||
|
description: Docker image to use for replicas.
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
description: Labels to apply.
|
||||||
|
env:
|
||||||
|
type: array
|
||||||
|
description: Environment variables to apply.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
value:
|
||||||
|
type: string
|
||||||
|
external_service:
|
||||||
|
type: boolean
|
||||||
|
description: If set to true, enable external load balancer.
|
||||||
|
cluster_ip:
|
||||||
|
type: string
|
||||||
|
description: IP to use for the service
|
||||||
|
privileged:
|
||||||
|
type: boolean
|
||||||
|
description: If set to true, enable privileged container
|
||||||
|
volumes:
|
||||||
|
type: array
|
||||||
|
description: Volumes to mount.
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
mounth_path:
|
||||||
|
type: string
|
||||||
|
description: Path to mount volume
|
||||||
|
# See https://cloud.google.com/container-engine/docs/spec-schema?hl=en for possible volumes. Since we only use gcePersistentDisk and NFS in our examples we have only added these ones.
|
||||||
|
oneOf:
|
||||||
|
gcePersistentDisk:
|
||||||
|
pdName:
|
||||||
|
type: string
|
||||||
|
description: Persistent's disk name
|
||||||
|
fsType:
|
||||||
|
type: string
|
||||||
|
description: Filesystem type of the persistent disk
|
||||||
|
nfs:
|
||||||
|
server:
|
||||||
|
type: string
|
||||||
|
description: The hostname or IP address of the NFS server
|
||||||
|
path:
|
||||||
|
type: string
|
||||||
|
description: The path that is exported by the NFS server
|
||||||
|
readOnly:
|
||||||
|
type: boolean
|
||||||
|
description: Forces the NFS export to be mounted with read-only permissions
|
||||||
|
|
Loading…
Reference in new issue