Commit d58cfc46 authored by Matt Butcher's avatar Matt Butcher

reset

parent 4d7c681b
*~
.*.swp
*.pyc
.project
nohup.out
/.coverage
/bin
/vendor/*
/rootfs/manager/bin/manager
/rootfs/manager/bin/kubectl
/rootfs/manager/bin/v1.*
/rootfs/resourcifier/bin/resourcifier
/rootfs/resourcifier/bin/kubectl
/rootfs/resourcifier/bin/v1.*
/rootfs/expandybird/bin/expandybird
/rootfs/expandybird/opt/expansion
.DS_Store
/log/
/scripts/env.sh
# Contributing Guidelines
The Kubernetes Helm project accepts contributions via GitHub pull requests. This document outlines the process to help get your contribution accepted.
## Contributor License Agreements
We'd love to accept your patches! Before we can take them, we have to jump a couple of legal hurdles.
Please fill out either the individual or corporate Contributor License Agreement (CLA).
* If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an [individual CLA](http://code.google.com/legal/individual-cla-v1.0.html).
* If you work for a company that wants to allow you to contribute your work, then you'll need to sign a [corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html).
Follow either of the two links above to access the appropriate CLA and instructions for how to sign and return it. Once we receive it, we'll be able to accept your pull requests.
***NOTE***: Only original source code from you and other people that have signed the CLA can be accepted into the main repository.
## Development Lifecycle
The project uses a combination of milestones and priority labels on GitHub issues to help development flow smoothly. While exceptions may be required on occasion, the team observes the following guidelines:
* At appropriate intervals, the Helm team creates a milestone and assigns
issues to it. This represents the team's priorities and intent.
* PRs/Issues related to the current milestone are prioritized over other PRs.
* PRs/Issues that fix a broken master build (or meet other P0 criteria) are
prioritized over other PRs.
## How to Contribute A Patch
### Overview
1. Submit an issue describing your proposed change to the repo in question.
1. A collaborator will respond to your issue.
1. If your proposed change is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above).
1. Fork the desired repo, develop and test your code changes.
1. Submit a pull request.
### Feature Proposals
Before adding a feature or making a major change to the code, open an
issue marked as a _proposal_ and explain your idea. For complex changes,
you may be asked to produce a design document.
### Single Issue
When fixing or implementing a GitHub issue, resist the temptation to refactor nearby code or to fix that potential bug you noticed. Instead, open a new pull request just for that change.
Keeping concerns separated allows pull requests to be tested, reviewed, and merged more quickly.
Squash and rebase the commit or commits in your pull request into logical units of work with `git`. Include tests and documentation changes in the same commit, so that a revert would remove all traces of the feature or fix.
If a PR completely resolves an existing issue, this should be noted. In the PR description–not in the commit itself–include a line such as "Closes #1234". The issue referenced will then be closed when your PR is merged. If it otherwise relates to an existing issue, that should be noted in the comment as well.
### Include Tests & Documentation
If you change or add functionality, your changes should include the necessary tests to prove that it works. While working on local code changes, always run the tests. Any change that could affect a user's experience also needs a change or addition to the relevant documentation.
Pull requests that do not include sufficient tests or documentation will be rejected.
***NOTE***: Please note that we are currently using Go version 1.6, and tests will fail if you run them on any other version of Go.
### Coding Standards
Go code should always be run through `gofmt` on the default settings. Lines of code may be up to 99 characters long. Documentation strings and tests are required for all public methods. Use of third-party go packages should be minimal, but when doing so, vendor code using [Glide](http://glide.sh/).
Python code should conform to [PEP8](https://www.python.org/dev/peps/pep-0008/).
### Merge Approval
Helm collaborators may add "LGTM" (Looks Good To Me) or an equivalent comment to indicate that a PR is acceptable. Any change requires at least one LGTM. No pull requests can be merged until at least one Helm collaborator signs off with an LGTM.
If the PR is from a Helm collaborator, then he or she should be the one to merge and close it. This keeps the commit stream clean and gives the collaborator the benefit of revisiting the PR before deciding whether or not to merge the changes.
## Support Channels
Whether you are a user or contributor, official support channels include:
- GitHub issues: https://github.com/kubenetes/helm/issues/new
- Slack: #Helm room in the [Kubernetes Slack](http://slack.kubernetes.io/)
Before opening a new issue or submitting a new pull request, it's helpful to search the project - it's likely that another user has already reported the issue you're facing, or it's a known issue that we're already aware of.
This diff is collapsed.
# Helm Maintainers
This document explains the leadership structure of the Kubernetes Helm project, and list the current project maintainers.
## What is a Maintainer?
(Unabashedly stolen from the [Docker](https://github.com/docker/docker/blob/master/MAINTAINERS) project)
There are different types of maintainers, with different responsibilities, but
all maintainers have 3 things in common:
1. They share responsibility in the project's success.
2. They have made a long-term, recurring time investment to improve the project.
3. They spend that time doing whatever needs to be done, not necessarily what
is the most interesting or fun.
## Types of Maintainers
The Helm project includes two types of official maintainers: maintainers and core maintainers.
### Helm Maintainers
Helm maintainers are developers who have commit access to the Helm repository.
The duties of a maintainer include:
* Classify and respond to GitHub issues and review pull requests
* Perform code reviews
* Shape the Helm roadmap and lead efforts to accomplish roadmap milestones
* Participate actively in feature development and bug fixing
* Answer questions and help users
* Participate in planning meetings
### Helm Core Maintainers
In addition to the duties of a Maintainer, Helm Core Maintainers also:
* Coordinate planning meetings
* Triage GitHub issues for milestone planning
* Escalate emergency issues (broken builds, security flaws) outside of
the normal planning process
The current core maintainers of Helm:
* Jack Greenfield - [@jackgr](https://github.com/jackgr)
* Matt Butcher - [@technosophos](https://github.com/technosophos)
## Project Planning
The Helm team holds regular planning meetings to set the project direction, milestones, and relative prioritization of issues. Planning meetings are coordinated via the #Helm room in the [Kubernetes Slack](http://slack.kubernetes.io/).
In order to solicit feedback from the community, planning meetings are run in public whenever possible.
## Becoming a Maintainer
Generally, potential maintainers are selected by the existing core maintainers based in part on the following criteria:
* Sustained contributions to the project over a period of time (usually months)
* A willingness to help users on GitHub and in the [#Helm Slack room](http://slack.kubernetes.io/)
* A friendly attitude
The Helm core maintainers must unanimously agree before inviting a community member to join as a maintainer, although in many cases the candidate has already been acting in the capacity of a maintainer for some time, and has been consulted on issues, pull requests, etc.
\ No newline at end of file
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
GO_DIRS ?= $(shell glide nv -x )
GO_PKGS ?= $(shell glide nv)
ROOTFS := rootfs
CLIENT := cmd/helm
.PHONY: info
info:
$(MAKE) -C $(ROOTFS) $@
.PHONY: gocheck
ifndef GOPATH
$(error No GOPATH set)
endif
.PHONY: build
build: gocheck
@scripts/build-go.sh
.PHONY: build-static
build-static: gocheck
@BUILD_TYPE=STATIC scripts/build-go.sh
.PHONY: build-cross
build-cross: gocheck
@BUILD_TYPE=CROSS scripts/build-go.sh
.PHONY: all
all: build
.PHONY: clean
clean:
$(MAKE) -C $(ROOTFS) $@
go clean -v $(GO_PKGS)
rm -rf bin
.PHONY: test
test: build test-style test-unit test-flake8
.PHONY: quicktest
quicktest: test-style
go test $(GO_PKGS)
.PHONY: push
push: push-server push-client
.PHONY: push-server
push-server: build-static
$(MAKE) -C $(ROOTFS) push
.PHONY: push-client
push-client: gocheck
@BUILD_TYPE=CROSS scripts/build-go.sh $(CLIENT)
$(MAKE) -C $(CLIENT) push
.PHONY: container
container: build-static
$(MAKE) -C $(ROOTFS) $@
.PHONY: test-unit
test-unit:
@echo Running tests...
go test -race -v $(GO_PKGS)
.PHONY: test-flake8
test-flake8:
@echo Running flake8...
flake8 expansion
@echo ----------------
.PHONY: test-style
test-style:
@scripts/validate-go.sh
HAS_GLIDE := $(shell command -v glide;)
HAS_GOLINT := $(shell command -v golint;)
HAS_GOVET := $(shell command -v go tool vet;)
HAS_GOX := $(shell command -v gox;)
HAS_PIP := $(shell command -v pip;)
HAS_FLAKE8 := $(shell command -v flake8;)
.PHONY: bootstrap
bootstrap:
@echo Installing deps
ifndef HAS_PIP
$(error Please install the latest version of Python pip)
endif
ifndef HAS_GLIDE
go get -u github.com/Masterminds/glide
endif
ifndef HAS_GOLINT
go get -u github.com/golang/lint/golint
endif
ifndef HAS_GOVET
go get -u golang.org/x/tools/cmd/vet
endif
ifndef HAS_GOX
go get -u github.com/mitchellh/gox
endif
ifndef HAS_FLAKE8
pip install flake8
endif
glide install
pip install --user -r expansion/requirements.txt
# Helm
[![Circle CI](https://circleci.com/gh/kubernetes/helm.svg?style=svg)](https://circleci.com/gh/kubernetes/helm) [![Go Report Card](http://goreportcard.com/badge/kubernetes/helm)](http://goreportcard.com/report/kubernetes/helm)
Helm makes it easy to create, describe, update and
delete Kubernetes resources using declarative configuration. A configuration is
just a `YAML` file that configures Kubernetes resources or supplies parameters
to templates.
Helm Manager runs server side, in your Kubernetes cluster, so it can tell you what templates
you've instantiated there, what resources they created, and even how the resources
are organized. So, for example, you can ask questions like:
* What Redis instances are running in this cluster?
* What Redis master and slave services are part of this Redis instance?
* What pods are part of this Redis slave?
The official Helm repository of charts is available in the
[kubernetes/charts](https://github.com/kubernetes/charts) repository.
Please hang out with us in [the Slack chat room](https://kubernetes.slack.com/messages/helm/).
## Installing Helm
Note: if you're exploring or using the project, you'll probably want to pull
[the latest release](https://github.com/kubernetes/helm/releases/latest),
since there may be undiscovered or unresolved issues at HEAD.
From a Linux or Mac OS X client:
```
$ git clone https://github.com/kubernetes/helm.git
$ cd helm
$ make build
$ bin/helm server install
```
That's it. You can now use `kubectl` to see Helm running in your cluster like this:
```
$ kubectl get pod,rc,service --namespace=helm
NAME READY STATUS RESTARTS AGE
expandybird-rc-e0whp 1/1 Running 0 35m
expandybird-rc-zdp8w 1/1 Running 0 35m
manager-rc-bl4i4 1/1 Running 0 35m
resourcifier-rc-21clg 1/1 Running 0 35m
resourcifier-rc-i2zhi 1/1 Running 0 35m
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
expandybird-service 10.0.0.248 <none> 8081/TCP 35m
manager-service 10.0.0.49 <none> 8080/TCP 35m
resourcifier-service 10.0.0.184 <none> 8082/TCP 35m
NAME DESIRED CURRENT AGE
expandybird-rc 2 2 35m
manager-rc 1 1 35m
resourcifier-rc 2 2 35m
```
If you see expandybird, manager and resourcifier services, as well as expandybird, manager and resourcifier replication controllers with pods that are READY, then Helm is up and running!
## Using Helm
Run a Kubernetes proxy to allow the Helm client to connect to the remote cluster:
```
kubectl proxy --port=8001 &
```
Configure the HELM_HOST environment variable to let the local Helm client talk to the Helm manager service running in your remote Kubernetes cluster using the proxy.
```
export HELM_HOST=http://localhost:8001/api/v1/proxy/namespaces/helm/services/manager-service:manager
```
## Installing Charts
To quickly deploy a chart, you can use the Helm command line tool.
Currently here is the step by step guide.
First add a respository of Charts used for testing:
```
$ bin/helm repo add kubernetes-charts-testing gs://kubernetes-charts-testing
```
Then deploy a Chart from this repository. For example to start a Redis cluster:
```
$ bin/helm deploy --name test --properties "workers=2" gs://kubernetes-charts-testing/redis-2.0.0.tgz
```
The command above will create a helm "deployment" called `test` using the `redis-2.0.0.tgz` chart stored in the google storage bucket `kubernetes-charts-testing`.
`$ bin/helm deployment describe test` will allow you to see the status of the resources you just created using the redis-2.0.0.tgz chart. You can also use kubectl to see the the same resources. It'll look like this:
```
$ kubectl get pods,svc,rc
NAME READY STATUS RESTARTS AGE
barfoo-barfoo 5/5 Running 0 45m
redis-master-rc-8wrqt 1/1 Running 0 41m
redis-slave-rc-6ptx6 1/1 Running 0 41m
redis-slave-rc-yc12q 1/1 Running 0 41m
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.0.0.1 <none> 443/TCP 45m
redis-master 10.0.0.67 <none> 6379/TCP 41m
redis-slave 10.0.0.168 <none> 6379/TCP 41m
NAME DESIRED CURRENT AGE
redis-master-rc 1 1 41m
redis-slave-rc 2 2 41m
```
To connect to your Redis master with a local `redis-cli` just use `kubectl port-forward` in a similar manner to:
```
$ kubectl port-forward redis-master-rc-8wrqt 6379:639 &
$ redis-cli
127.0.0.1:6379> info
...
role:master
connected_slaves:2
slave0:ip=172.17.0.10,port=6379,state=online,offset=925,lag=0
slave1:ip=172.17.0.11,port=6379,state=online,offset=925,lag=1
```
Once you are done, you can delete your deployment with
```
$ bin/helm deployment list
test
$ bin/helm deployment rm test
````
## Uninstalling Helm from Kubernetes
You can uninstall Helm entirely using the following command:
```
$ bin/helm server uninstall
```
This command will remove everything in the Helm namespace being used.
## Design of Helm
There is a more detailed [design document](docs/design/design.md) available.
## Status of the Project
This project is still under active development, so you might run into issues. If
you do, please don't be shy about letting us know, or better yet, contribute a
fix or feature.
## Contributing
Your contributions are welcome.
We use the same [workflow](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/development.md#git-setup),
[License](LICENSE) and [Contributor License Agreement](CONTRIBUTING.md) as the main Kubernetes repository.
## Relationship to Google Cloud Platform's Deployment Manager and Deis's Helm
Kubernetes Helm represent a merge of Google's Deployment Manager (DM) and the original Helm from Deis.
Kubernetes Helm uses many of the same concepts and languages as
[Google Cloud Deployment Manager](https://cloud.google.com/deployment-manager/overview),
but creates resources in Kubernetes clusters, not in Google Cloud Platform projects. It also brings several concepts from the original Helm such as Charts.
machine:
environment:
GLIDE_VERSION: "0.10.1"
GO15VENDOREXPERIMENT: 1
GOPATH: /usr/local/go_workspace
HOME: /home/ubuntu
IMPORT_PATH: "github.com/kubernetes/helm"
PATH: $HOME/go/bin:$PATH
GOROOT: $HOME/go
dependencies:
override:
- mkdir -p $HOME/go
- wget "https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz"
- tar -C $HOME -xzf go1.6.linux-amd64.tar.gz
- go version
- go env
- sudo chown -R $(whoami):staff /usr/local
- cd $GOPATH
- mkdir -p $GOPATH/src/$IMPORT_PATH
- cd $HOME/helm
- rsync -az --delete ./ "$GOPATH/src/$IMPORT_PATH/"
- wget "https://github.com/Masterminds/glide/releases/download/$GLIDE_VERSION/glide-$GLIDE_VERSION-linux-amd64.tar.gz"
- mkdir -p $HOME/bin
- tar -vxz -C $HOME/bin --strip=1 -f glide-$GLIDE_VERSION-linux-amd64.tar.gz
- export PATH="$HOME/bin:$PATH" GLIDE_HOME="$HOME/.glide"
- cd $GOPATH/src/$IMPORT_PATH
- sudo pip install -r expansion/requirements.txt
- sudo pip install flake8
test:
override:
- cd $GOPATH/src/$IMPORT_PATH && make bootstrap test
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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.
*/
// Package cmd contains the executables for Helm.
package cmd
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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.
*/
package expander
import (
"bytes"
"encoding/json"
"fmt"
"github.com/ghodss/yaml"
"log"
"os/exec"
"github.com/kubernetes/helm/pkg/expansion"
)
type expander struct {
ExpansionBinary string
}
// NewExpander returns an ExpandyBird expander.
func NewExpander(binary string) expansion.Expander {
return &expander{binary}
}
type expandyBirdConfigOutput struct {
Resources []interface{} `yaml:"resources,omitempty"`
}
type expandyBirdOutput struct {
Config *expandyBirdConfigOutput `yaml:"config,omitempty"`
Layout interface{} `yaml:"layout,omitempty"`
}
// ExpandChart passes the given configuration to the expander and returns the
// expanded configuration as a string on success.
func (e *expander) ExpandChart(request *expansion.ServiceRequest) (*expansion.ServiceResponse, error) {
if err := expansion.ValidateRequest(request); err != nil {
return nil, err
}
request, err := expansion.ValidateProperties(request)
if err != nil {
return nil, err
}
chartInv := request.ChartInvocation
chartFile := request.Chart.Chartfile
chartMembers := request.Chart.Members
if e.ExpansionBinary == "" {
message := fmt.Sprintf("expansion binary cannot be empty")
return nil, fmt.Errorf("%s: %s", chartInv.Name, message)
}
entrypointIndex := -1
for i, f := range chartMembers {
if f.Path == chartFile.Expander.Entrypoint {
entrypointIndex = i
}
}
if entrypointIndex == -1 {
message := fmt.Sprintf("The entrypoint in the chart.yaml cannot be found: %s", chartFile.Expander.Entrypoint)
return nil, fmt.Errorf("%s: %s", chartInv.Name, message)
}
// Those are automatically increasing buffers, so writing arbitrary large
// data here won't block the child process.
var stdout bytes.Buffer
var stderr bytes.Buffer
// Now we convert the new chart representation into the form that classic ExpandyBird takes.
chartInvJSON, err := json.Marshal(chartInv)
if err != nil {
return nil, fmt.Errorf("error marshalling chart invocation %s: %s", chartInv.Name, err)
}
content := "{ \"resources\": [" + string(chartInvJSON) + "] }"
cmd := &exec.Cmd{
Path: e.ExpansionBinary,
// Note, that binary name still has to be passed argv[0].
Args: []string{e.ExpansionBinary, content},
Stdout: &stdout,
Stderr: &stderr,
}
for i, f := range chartMembers {
name := f.Path
path := f.Path
if i == entrypointIndex {
// This is how expandyBird identifies the entrypoint.
name = chartInv.Type
}
cmd.Args = append(cmd.Args, name, path, string(f.Content))
}
if err := cmd.Start(); err != nil {
log.Printf("error starting expansion process: %s", err)
return nil, err
}
cmd.Wait()
log.Printf("Expansion process: pid: %d SysTime: %v UserTime: %v", cmd.ProcessState.Pid(),
cmd.ProcessState.SystemTime(), cmd.ProcessState.UserTime())
if stderr.String() != "" {
return nil, fmt.Errorf("%s: %s", chartInv.Name, stderr.String())
}
output := &expandyBirdOutput{}
if err := yaml.Unmarshal(stdout.Bytes(), output); err != nil {
return nil, fmt.Errorf("cannot unmarshal expansion result (%s):\n%s", err, output)
}
return &expansion.ServiceResponse{Resources: output.Config.Resources}, nil
}
This diff is collapsed.
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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.
*/
package main
import (
"github.com/kubernetes/helm/cmd/expandybird/expander"
"github.com/kubernetes/helm/pkg/expansion"
"github.com/kubernetes/helm/pkg/version"
"flag"
"log"
)
// interface that we are going to listen on
var address = flag.String("address", "", "Interface to listen on")
// port that we are going to listen on
var port = flag.Int("port", 8080, "Port to listen on")
// path to expansion binary
var expansionBinary = flag.String("expansion_binary", "../../../expansion/expansion.py",
"The path to the expansion binary that will be used to expand the template.")
func main() {
flag.Parse()
backend := expander.NewExpander(*expansionBinary)
service := expansion.NewService(*address, *port, backend)
log.Printf("Version: %s", version.Version)
log.Printf("Listening on http://%s:%d/expand", *address, *port)
log.Fatal(service.ListenAndServe())
}
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
config:
resources:
- name: expandybird-service
properties:
apiVersion: v1
kind: Service
metadata:
labels:
app: expandybird
name: expandybird-service
namespace: default
spec:
ports:
- name: expandybird
port: 8080
targetPort: 8080
selector:
app: expandybird
type: LoadBalancer
type: Service
- name: expandybird-rc
properties:
apiVersion: v1
kind: ReplicationController
metadata:
labels:
app: expandybird
name: expandybird-rc
namespace: default
spec:
replicas: 3
selector:
app: expandybird
template:
metadata:
labels:
app: expandybird
spec:
containers:
- env: []
image: gcr.io/kubernetes-helm/expandybird
name: expandybird
ports:
- containerPort: 8080
name: expandybird
type: ReplicationController
layout:
resources:
- name: expandybird
properties:
container_port: 8080
external_service: true
image: gcr.io/kubernetes-helm/expandybird
labels:
app: expandybird
replicas: 3
service_port: 8080
target_port: 8080
resources:
- name: expandybird-service
type: Service
- name: expandybird-rc
type: ReplicationController
type: replicatedservice.py
\ No newline at end of file
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
imports:
- path: invalidfilename.py
resources:
- name: expandybird
type: replicatedservice.py
properties:
service_port: 8080
target_port: 8080
image: gcr.io/kubernetes-helm/expandybird
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
imports:
- path: replicatedservice.py
resources:
- name: expandybird
type: replicatedservice.py
properties:
service_port: 8080
target_port: 8080
invalidproperty: gcr.io/kubernetes-helm/expandybird
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
imports:
- path: replicatedservice.py
resources:
- name: expandybird
type: invalidtypename.py
properties:
service_port: 8080
target_port: 8080
image: gcr.io/kubernetes-helm/expandybird
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
imports:
- path: replicatedservice.py
resources:
- name: expandybird
type: replicatedservice.py
thisisnotalist: somevalue
shouldnotbehere: anothervalue
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
imports:
resources:
- name: expandybird
type: replicatedservice.py
properties:
service_port: 8080
target_port: 8080
image: gcr.io/kubernetes-helm/expandybird
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
imports:
- path: replicatedservice.py
resources:
- type: replicatedservice.py
properties:
service_port: 8080
target_port: 8080
image: gcr.io/kubernetes-helm/expandybird
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
imports:
- path: replicatedservice.py
resources:
- name: expandybird
properties:
service_port: 8080
target_port: 8080
image: gcr.io/kubernetes-helm/expandybird
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
imports:
- path: replicatedservice.py
resources:
- name: expandybird
type: replicatedservice.py
properties:
service_port: 8080
target_port: 8080
container_port: 8080
external_service: true
replicas: 3
image: gcr.io/kubernetes-helm/expandybird
labels:
app: expandybird
\ No newline at end of file
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# 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.
######################################################################
"""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 = name + '-rc'
rc_type = RC_TYPE_COLLECTION
service = {
'name': service_name,
'type': service_type,
'properties': {
'apiVersion': 'v1',
'kind': 'Service',
'metadata': {
'name': service_name,
'namespace': namespace,
'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'
config['resources'].append(service)
rc = {
'name': rc_name,
'type': rc_type,
'properties': {
'apiVersion': 'v1',
'kind': 'ReplicationController',
'metadata': {
'name': rc_name,
'namespace': namespace,
'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'],
}
]
}
]
}
}
}
}
}
config['resources'].append(rc)
return yaml.dump(config)
def GenerateLabels(context, name):
"""Generates labels either from the context.properties['labels'] or
generates a default label 'app':name
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 'app':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 = {'app': 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
"""
service_port = context.properties.get('service_port', None)
target_port = context.properties.get('target_port', None)
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
info:
title: Schema with a lots of errors in it
imports:
properties:
exclusiveMin:
type: integer
exclusiveMinimum: 0
info:
title: Schema with a property that has a referenced default value
imports:
properties:
number:
$ref: '#/level/mult'
level:
mult:
type: integer
multipleOf: 1
default: 1
info:
title: Schema with properties that have default values
imports:
properties:
one:
type: integer
default: 1
alpha:
type: string
default: alpha
info:
title: Schema with properties that have default values
imports:
properties:
one:
type: integer
default: 1
alpha:
type: string
default: alpha
info:
title: Schema with a required integer property that has a default string value
imports:
required:
- number
properties:
number:
type: integer
default: string
info:
title: Schema with references to something that doesnt exist
imports:
properties:
odd:
type: integer
not:
$ref: '#/wheeeeeee'
info:
title: Schema with references to something that doesnt exist
imports:
properties:
odd:
$ref: '#/wheeeeeee'
info:
title: Schema with properties that have extra metadata
imports:
properties:
one:
type: integer
default: 1
metadata:
gcloud: is great!
compute: is awesome
alpha:
type: string
default: alpha
metadata:
- you
- can
- do
- anything
info:
title: Schema with references
imports:
properties:
number:
$ref: #/number
number:
type: integer
info:
title: VM with Disks
author: Kubernetes
description: Creates a single vm, then attaches disks to it.
required:
- zone
properties:
zone:
type: string
description: GCP zone
default: us-central1-a
disks:
type: array
items:
type: object
required:
- name
properties:
name:
type: string
description: Suffix for this disk
sizeGb:
type: integer
default: 100
diskType:
type: string
enum:
- pd-standard
- pd-ssd
default: pd-standard
additionalProperties: false
info:
title: Schema with a lots of number properties and restrictions
imports:
properties:
minimum0:
type: integer
minimum: 0
exclusiveMin0:
type: integer
minimum: 0
exclusiveMinimum: true
maximum10:
type: integer
maximum: 10
exclusiveMax10:
type: integer
maximum: 10
exclusiveMaximum: true
even:
type: integer
multipleOf: 2
odd:
type: integer
not:
multipleOf: 2
info:
title: VM with Disks
author: Kubernetes
description: Creates a single vm, then attaches disks to it.
required:
- zone
properties:
zone:
type: string
description: GCP zone
default: us-central1-a
disks:
type: array
items:
$ref: '#/disk'
disk:
type: object
required:
- name
properties:
name:
type: string
description: Suffix for this disk
sizeGb:
type: integer
default: 100
diskType:
type: string
enum:
- pd-standard
- pd-ssd
default: pd-standard
additionalProperties: false
info:
title: Schema with references
imports:
properties:
odd:
type: integer
not:
$ref: '#/even'
even:
multipleOf: 2
info:
title: Schema with a required property that has a referenced default value
imports:
required:
- number
properties:
number:
$ref: '#/default_val'
default_val:
type: integer
default: my_name
info:
title: Schema with a required property
imports:
required:
- name
properties:
name:
type: string
info:
title: Schema with a required property that has a default value
imports:
required:
- name
properties:
name:
type: string
default: my_name
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
resources:
- type: compute.v1.instance
name: my_instance
properties:
zone: test-zone-a
- type: compute.v1.instance
name: my_instance
properties:
zone: test-zone-b
resources:
- type: compute.v1.instance
name: B
properties:
zone: test-zone-b
resources:
- type: compute.v1.instance
name: C
properties:
zone: test-zone-c
resources:
- type: compute.v1.instance
name: my_instance
properties:
zone: test-zone-a
- type: compute.v1.instance
name: my_instance
properties:
zone: test-zone-b
imports: ["duplicate_names_in_subtemplates.jinja"]
resources:
- name: subtemplate
type: duplicate_names_in_subtemplates.jinja
imports: ["duplicate_names_B.jinja", "duplicate_names_C.jinja"]
resources:
- name: A
type: duplicate_names_B.jinja
- name: B
type: duplicate_names_C.jinja
config:
resources:
- name: B
properties:
zone: test-zone-b
type: compute.v1.instance
- name: C
properties:
zone: test-zone-c
type: compute.v1.instance
layout:
resources:
- name: A
resources:
- name: B
type: compute.v1.instance
type: duplicate_names_B.jinja
- name: B
resources:
- name: C
type: compute.v1.instance
type: duplicate_names_C.jinja
imports: ["duplicate_names_B.jinja"]
resources:
- name: A
type: duplicate_names_B.jinja
- name: B
type: compute.v1.instance
config:
resources:
- name: B
properties:
zone: test-zone-b
type: compute.v1.instance
- name: B
type: compute.v1.instance
layout:
resources:
- name: A
resources:
- name: B
type: compute.v1.instance
type: duplicate_names_B.jinja
- name: B
type: compute.v1.instance
resources:
- name: helper
type: bar
properties:
test: {{ properties["foobar"] }}
properties:
foobar:
type: string
default: Use this schema
{%- macro GenerateMachineName(prefix='', suffix='') -%}
{{ prefix + "-" + suffix }}
{%- endmacro %}
"""Dummy helper methods invoked in other constructors."""
def GenerateMachineName(prefix, suffix):
"""Generates name of a VM."""
return prefix + "-" + suffix
"""Dummy helper methods invoked in other constructors."""
def GenerateMachineSize():
"""Generates size of a VM."""
return "big"
resources:
- name: foo properties: bar: baz
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ properties["deployment"] }}
properties:
zone: {{ properties["zone"] }}
machineType: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/zones/{{ properties["zone"] }}/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-{{ properties["deployment"] }}
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/global/networks/default
info:
title: Schema for a basic jinja template that includes default values
imports:
properties:
foo:
description: blah
type: string
zone:
type: string
default: test-zone
project:
type: string
default: test-project
deployment:
type: string
default: test-deployment
imports:
- path: "jinja_defaults.jinja"
- path: "jinja_defaults.jinja.schema"
resources:
- name: jinja_defaults_name
type: jinja_defaults.jinja
properties:
foo: bar
config:
resources:
- name: vm-created-by-cloud-config-test-deployment
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
layout:
resources:
- name: jinja_defaults_name
properties:
deployment: test-deployment
foo: bar
project: test-project
zone: test-zone
resources:
- name: vm-created-by-cloud-config-test-deployment
type: compute.v1.instance
type: jinja_defaults.jinja
Nothing here because this file should never be called.
The validation will fail before this file is used.
{{% Invalid
info:
title: Schema with a required property
imports:
required:
- important
properties:
important:
type: string
imports:
- path: "jinja_missing_required.jinja"
- path: "jinja_missing_required.jinja.schema"
resources:
- name: jinja_missing_required_resource_name
type: jinja_missing_required.jinja
properties:
less-important: an optional property
Nothing here because this file should never be called.
The validation will fail before this file is used.
{{% Invalid
info:
title: Schema with several rules
imports:
properties:
number:
type: integer
short-string:
type: string
maxLength: 10
odd:
type: integer
not:
multipleOf: 2
abc:
type: string
enum:
- a
- b
- c
imports:
- path: "jinja_multiple_errors.jinja"
- path: "jinja_multiple_errors.jinja.schema"
resources:
- name: jinja_multiple_errors
type: jinja_multiple_errors.jinja
properties:
number: a string
short-string: longer than 10 chars
odd: 6
abc: d
resources:
{% for name in ['name1', 'name2'] %}
- type: compute.v1.instance
name: {{ name }}
properties:
zone: test-zone
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
{% endfor %}
imports: ["jinja_noparams.jinja"]
resources:
- name: jinja_noparams_name
type: jinja_noparams.jinja
config:
resources:
- name: name1
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
- name: name2
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
layout:
resources:
- name: jinja_noparams_name
resources:
- name: name1
type: compute.v1.instance
- name: name2
type: compute.v1.instance
type: jinja_noparams.jinja
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ properties["deployment"] }}
properties:
zone: {{ properties["zone"] }}
machineType: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/zones/{{ properties["zone"] }}/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-{{ properties["deployment"] }}
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/global/networks/default
imports: ["jinja_template.jinja"]
resources:
- name: jinja_template_name
type: jinja_template.jinja
properties:
zone: test-zone
project: test-project
deployment: test-deployment
config:
resources:
- name: vm-created-by-cloud-config-test-deployment
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
layout:
resources:
- name: jinja_template_name
properties:
deployment: test-deployment
project: test-project
zone: test-zone
resources:
- name: vm-created-by-cloud-config-test-deployment
type: compute.v1.instance
type: jinja_template.jinja
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ env["deployment"] }}
properties:
zone: {{ properties["zone"] }}
machineType: https://www.googleapis.com/compute/v1/projects/{{ env["project"] }}/zones/{{ properties["zone"] }}/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-{{ env["deployment"] }}-{{ env["name"] }}-{{ env["type"] }}
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/{{ env["project"] }}/global/networks/default
imports: ["jinja_template_with_env.jinja"]
resources:
- name: jinja_template_with_env_name
type: jinja_template_with_env.jinja
properties:
zone: test-zone
config:
resources:
- name: vm-created-by-cloud-config-test-deployment
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-test-deployment-jinja_template_with_env_name-jinja_template_with_env.jinja
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/test-project/zones/test-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/test-project/global/networks/default
zone: test-zone
type: compute.v1.instance
layout:
resources:
- name: jinja_template_with_env_name
properties:
zone: test-zone
resources:
- name: vm-created-by-cloud-config-test-deployment
type: compute.v1.instance
type: jinja_template_with_env.jinja
{% import 'helpers/common.jinja' as common %}
resources:
- name: {{ common.GenerateMachineName("myFrontend", "prod") }}
type: compute.v1.instance
properties:
machineSize: big
imports: ["jinja_template_with_import.jinja", "helpers/common.jinja"]
resources:
- name: jinja_template_with_import_name
type: jinja_template_with_import.jinja
config:
resources:
- name: myFrontend-prod
properties:
machineSize: big
type: compute.v1.instance
layout:
resources:
- name: jinja_template_with_import_name
resources:
- name: myFrontend-prod
type: compute.v1.instance
type: jinja_template_with_import.jinja
{% import 'helpers/common.jinja' as common %}
resources:
- name: {{ common.GenerateMachineName("myFrontend", "prod") }}
type: compute.v1.instance
properties:
description: {{ imports[properties["description-file"]] }}
machineSize: big
imports: ["jinja_template_with_inlinedfile.jinja", "helpers/common.jinja", "description_text.txt"]
resources:
- name: jinja_template_with_inlinedfile_name
type: jinja_template_with_inlinedfile.jinja
properties:
description-file: description_text.txt
config:
resources:
- name: myFrontend-prod
properties:
description: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
machineSize: big
type: compute.v1.instance
layout:
resources:
- name: jinja_template_with_inlinedfile_name
properties:
description-file: description_text.txt
resources:
- name: myFrontend-prod
type: compute.v1.instance
type: jinja_template_with_inlinedfile.jinja
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ porcelain["deployment"] }}
properties:
zone: {{ properties["zone"] }}
machineType: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/zones/{{ properties["zone"] }}/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-{{ properties["deployment"] }}
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/global/networks/default
imports: ["jinja_unresolved.jinja"]
resources:
- name: jinja_template_name
type: jinja_unresolved.jinja
properties:
zone: test-zone
project: test-project
deployment: test-deployment
"""Return empty resources block."""
def GenerateConfig(_):
return """resources:"""
imports:
- path: "no_properties.py"
resources:
- name: test-resource
type: no_properties.py
config:
resources: []
layout:
resources:
- name: test-resource
type: no_properties.py
"""Does nothing."""
def GenerateConfig(_):
"""Returns empty string."""
return ''
imports:
- path: "no_resources.py"
resources:
- name: test-resource
type: no_resources.py
resources:
- type: compute.v1.instance
name: vm-created-by-cloud-config-{{ properties["deployment"] }}
properties:
zone: {{ properties["zone"] }}
machineType: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/zones/{{ properties["zone"] }}/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
diskName: disk-created-by-cloud-config-{{ properties["deployment"] }}
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/{{ properties["project"] }}/global/networks/default
#% description: Creates a VM running a Salt master daemon in a Docker container.
#% parameters:
#% - name: masterAddress
#% type: string
#% description: Name of the Salt master VM.
#% required: true
#% - name: project
#% type: string
#% description: Name of the Cloud project.
#% required: true
#% - name: zone
#% type: string
#% description: Zone to create the resources in.
#% required: true
"""Generates config for a VM running a SaltStack master.
Just for fun this template is in Python, while the others in this
directory are in Jinja2.
"""
def GenerateConfig(evaluation_context):
return """
resources:
- name: python_and_jinja_template_jinja_name
type: python_and_jinja_template.jinja
properties:
zone: %(zone)s
project: %(project)s
deployment: %(master)s
""" % {"master": evaluation_context.properties["masterAddress"],
"project": evaluation_context.properties["project"],
"zone": evaluation_context.properties["zone"]}
imports: ["python_and_jinja_template.jinja", "python_and_jinja_template.py"]
resources:
- name: python_and_jinja_template_name
type: python_and_jinja_template.py
properties:
masterAddress: master-address
project: my-project
zone: my-zone
config:
resources:
- name: vm-created-by-cloud-config-master-address
properties:
disks:
- autoDelete: true
boot: true
deviceName: boot
initializeParams:
diskName: disk-created-by-cloud-config-master-address
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
type: PERSISTENT
machineType: https://www.googleapis.com/compute/v1/projects/my-project/zones/my-zone/machineTypes/f1-micro
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/my-project/global/networks/default
zone: my-zone
type: compute.v1.instance
layout:
resources:
- name: python_and_jinja_template_name
properties:
masterAddress: master-address
project: my-project
zone: my-zone
resources:
- name: python_and_jinja_template_jinja_name
properties:
deployment: master-address
project: my-project
zone: my-zone
resources:
- name: vm-created-by-cloud-config-master-address
type: compute.v1.instance
type: python_and_jinja_template.jinja
type: python_and_jinja_template.py
"""Throws an exception."""
raise Exception
info:
title: Schema with several errors
imports:
properties:
bad-type:
type: int
missing-cond:
type: string
exclusiveMaximum: 10
odd-string:
type: string
not:
multipleOf: 2
bad-enum:
type: string
enum: not a list
imports:
- path: "python_bad_schema.py"
- path: "python_bad_schema.py.schema"
resources:
- name: python_bad_schema
type: python_bad_schema.py
properties:
innocent: true
"""Constructs a VM."""
def GenerateConfig(_):
"""Generates config of a VM."""
return """
resources:
- name: myBackend
type: compute.v1.instance
properties:
machineSize: big
"""
imports: ["python_noparams.py"]
resources:
- name: myFrontend
type: compute.v1.instance
properties:
machineSize: big
- name: python_noparams_name
type: python_noparams.py
config:
resources:
- name: myFrontend
properties:
machineSize: big
type: compute.v1.instance
- name: myBackend
properties:
machineSize: big
type: compute.v1.instance
layout:
resources:
- name: myFrontend
type: compute.v1.instance
- name: python_noparams_name
resources:
- name: myBackend
type: compute.v1.instance
type: python_noparams.py
#% description: Creates a VM running a Salt master daemon in a Docker container.
#% parameters:
#% - name: masterAddress
#% type: string
#% description: Name of the Salt master VM.
#% required: true
#% - name: project
#% type: string
#% description: Name of the Cloud project.
#% required: true
#% - name: zone
#% type: string
#% description: Zone to create the resources in.
#% required: true
"""Generates config for a VM running a SaltStack master.
Just for fun this template is in Python, while the others in this
directory are in Jinja2.
"""
def GenerateConfig(evaluation_context):
return """
resources:
- type: compute.v1.firewall
name: %(master)s-firewall
properties:
network: https://www.googleapis.com/compute/v1/projects/%(project)s/global/networks/default
sourceRanges: [ "0.0.0.0/0" ]
allowed:
- IPProtocol: tcp
ports: [ "4505", "4506" ]
- type: compute.v1.instance
name: %(master)s
properties:
zone: %(zone)s
machineType: https://www.googleapis.com/compute/v1/projects/%(project)s/zones/%(zone)s/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140619
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/%(project)s/global/networks/default
accessConfigs:
- name: External NAT
type: ONE_TO_ONE_NAT
metadata:
items:
- key: startup-script
value: startup-script-value
""" % {"master": evaluation_context.properties["masterAddress"],
"project": evaluation_context.env["project"],
"zone": evaluation_context.properties["zone"]}
info:
title: A simple python template that has a schema.
imports:
properties:
masterAddress:
type: string
default: slave-address
description: masterAddress
zone:
type: string
default: not-test-zone
description: zone
imports:
- path: "python_schema.py"
- path: "python_schema.py.schema"
resources:
- name: python_schema
type: python_schema.py
properties:
masterAddress: master-address
zone: my-zone
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment