1
1
Fork 0
mirror of https://github.com/mcuadros/ascode synced 2024-04-27 04:15:06 +02:00

examples: examples review and render to markdown

This commit is contained in:
Máximo Cuadros 2020-03-29 19:06:41 +02:00
parent f912a591f8
commit a13a11072b
No known key found for this signature in database
GPG Key ID: 17A5DFEDC735AE4B
10 changed files with 302 additions and 80 deletions

View File

@ -5,7 +5,7 @@ OUTLINE_CMD ?= outline
DOCUMENTATION_PATH ?= $(BASE_PATH)/_documentation
DOCUMENTATION_REFERENCE_PATH ?= $(DOCUMENTATION_PATH)/reference
DOCUMENTATION_REFERENCE_TEMPLATE ?= $(DOCUMENTATION_REFERENCE_PATH)/reference.md.tmpl
EXAMPLES_PATH ?= starlark/types/testdata/examples
DOCUMENTATION_INLINE_EXAMPLES_PATH ?= starlark/types/testdata/examples
RUNTIME_MODULES = \
github.com/mcuadros/ascode/starlark/module/os \
@ -25,6 +25,12 @@ STARLIB_PKG ?= github.com/qri-io/starlib
STARLIB_COMMIT ?= $(shell $(QUERY_GO_MOD_CMD) . $(STARLIB_PKG))
STARLIB_PKG_LOCATION = $(GOPATH)/src/$(STARLIB_PKG)
# Examples
EXAMPLE_TO_MD_CMD = go run _scripts/example-to-md.go
EXAMPLES = functions.star runtime.star
EXAMPLES_PATH = $(BASE_PATH)/_examples
DOCUMENTATION_EXAMPLES_PATH = $(DOCUMENTATION_PATH)/example
# Build Info
GO_LDFLAGS_CMD = go run _scripts/goldflags.go
GO_LDFLAGS_PACKAGE = cmd
@ -39,7 +45,8 @@ HUGO_SITE_TEMPLATE_PATH ?= $(HUGO_SITE_PATH)/themes/hugo-ascode-theme
HUGO_THEME_URL ?= https://github.com/mcuadros/hugo-ascode-theme
HUGO_PARAMS_VERSION ?= dev
export HUGO_PARAMS_VERSION
# Rules
.PHONY: documentation clean hugo-server
@ -47,7 +54,7 @@ documentation: $(RUNTIME_MODULES)
$(RUNTIME_MODULES): $(DOCUMENTATION_RUNTIME_PATH) $(STARLIB_PKG_LOCATION)
$(OUTLINE_CMD) package \
-t $(DOCUMENTATION_REFERENCE_TEMPLATE) \
-d $(EXAMPLES_PATH) \
-d $(DOCUMENTATION_INLINE_EXAMPLES_PATH) \
$@ \
> $(DOCUMENTATION_REFERENCE_PATH)/`basename $@`.md
@ -60,13 +67,20 @@ $(STARLIB_PKG_LOCATION):
git checkout $(STARLIB_COMMIT); \
cd $(BASE_PATH);
examples: $(EXAMPLES)
$(EXAMPLES):
$(EXAMPLE_TO_MD_CMD) \
$(EXAMPLES_PATH)/$@ $(shell ls -1 $(DOCUMENTATION_EXAMPLES_PATH) | wc -l) \
> $(DOCUMENTATION_EXAMPLES_PATH)/$@.md
goldflags:
@$(GO_LDFLAGS_CMD) $(GO_LDFLAGS_PACKAGE) . $(GO_LDFLAGS_PACKAGES)
hugo-build: $(HUGO_SITE_PATH) documentation
hugo-build: $(HUGO_SITE_PATH) documentation examples
hugo --minify --source $(HUGO_SITE_PATH) --config $(DOCUMENTATION_PATH)/config.toml
hugo-server: $(HUGO_SITE_PATH) documentation
hugo-server: $(HUGO_SITE_PATH) documentation examples
hugo server --source $(HUGO_SITE_PATH) --config $(DOCUMENTATION_PATH)/config.toml
$(HUGO_SITE_PATH): $(HUGO_SITE_TEMPLATE_PATH)

5
_documentation/example/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# Ignore
*.md
# Allow
!_index.md

View File

@ -0,0 +1,5 @@
---
title: 'Examples'
weight: 30
summary: true
---

View File

@ -1,37 +0,0 @@
aws = tf.provider("aws")
aws.region = "us-west-2"
# It creates a new instance for the given name, distro and type.
def new_instance(name, distro, type="t2.micro"):
instance = aws.resource.instance(name)
instance.instance_type = type
instance.ami = get_ami_id(distro)
return instance
amis = {}
ami_names_owners = {
"ubuntu": ["ubuntu/images/*/ubuntu-xenial-16.04-amd64-server-*", "099720109477"],
"ecs": ["*amazon-ecs-optimized", "591542846629"],
}
# We create the AMI data-source for the given distro.
def get_ami_id(distro):
if distro in amis:
return amis[distro]
data = ami_names_owners[distro]
ami = aws.data.ami(distro)
ami.most_recent = True
ami.filter(name="name", values=[data[0]])
ami.filter(name="virtualization-type", values=["hvm"])
ami.owners = [data[1]]
amis[distro] = ami.id
return ami.id
# Creates 20 instances of each distro.
for i in range(20):
new_instance("ubuntu_%d" % i, "ubuntu")
new_instance("ecs_%d" % i, "ecs")

View File

@ -1,3 +0,0 @@
tf.backend = backend("gcs")
tf.backend.bucket = "tf-state-prod"
tf.backend.prefix = "terraform/state"

View File

@ -1,12 +0,0 @@
load("experimental/docker", "docker")
p = tf.provider("docker", "2.7.0", "foo")
# using docker.image semver can be used to choose the docker image, `
golang = docker.image("golang", "1.13.x")
foo = p.resource.container("foo")
foo.name = "foo"
# version queries the docker repository and returns the correct tag.
foo.image = golang.version(full=True)

126
_examples/functions.star Normal file
View File

@ -0,0 +1,126 @@
# Using functions
# This example illustrates how with the usage through the usage of functions,
# we can simplify and improve the readability of our infrastructure declaration.
# <!--more-->
# Instantiates a new AWS provider, `aws` will be available in the context of
# the functions.
aws = tf.provider("aws", region="us-west-2")
# Every instance requires an `ami` data source; this data source contains a
# very specif configuration like the ID of the owner or a name pattern. So
# we define a dictionary with the different values we want to use.
ami_names_owners = {
"ubuntu": ["ubuntu/images/*/ubuntu-xenial-16.04-amd64-server-*", "099720109477"],
"ecs": ["*amazon-ecs-optimized", "591542846629"],
}
# `get_ami` returns the ami for the given `distro`. It searches in the
# `ResouceCollection` of the `ami` data source, if finds the `ami` it simply
# returns it; if not creates a new one using the data from the `ami_names_owners`
# dictionary.
def get_ami(distro):
amis = aws.data.ami.search(distro)
if len(amis) != 0:
return amis[0]
data = ami_names_owners[distro]
ami = aws.data.ami(distro)
ami.most_recent = True
ami.filter(name="name", values=[data[0]])
ami.filter(name="virtualization-type", values=["hvm"])
ami.owners = [data[1]]
return ami
# `new_instance` instantiates a new `instance` for the given name, distro and
# type, the type has a default value `t2.micro`. The `distro` value is resolved
# to an `ami` resource using the previously defined function `get_ami`.
def new_instance(name, distro, type="t2.micro"):
instance = aws.resource.instance(name)
instance.instance_type = type
instance.ami = get_ami(distro).id
# Now using a basic `for` loop we can instantiate 5 different web servers,
# where the even machines are using ubuntu and the odd ones ecs.
for i in range(5):
distro = "ubuntu"
if i % 2:
distro = "ecs"
new_instance("web_%d" % i, distro)
# ### Output
# If we execute this script with the flag `--print-hcl` the result shuld be
# something like this:
"""hcl
provider "aws" {
alias = "id_01E4KEA5ZAA1PYERQ8KM5D04GC"
version = "2.13.0"
region = "us-west-2"
}
data "aws_ami" "ubuntu" {
provider = aws.id_01E4KEA5ZAA1PYERQ8KM5D04GC
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/*/ubuntu-xenial-16.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
data "aws_ami" "ecs" {
provider = aws.id_01E4KEA5ZAA1PYERQ8KM5D04GC
most_recent = true
owners = ["591542846629"]
filter {
name = "name"
values = ["*amazon-ecs-optimized"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
resource "aws_instance" "web_0" {
provider = aws.id_01E4KEA5ZAA1PYERQ8KM5D04GC
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.micro"
}
resource "aws_instance" "web_1" {
provider = aws.id_01E4KEA5ZAA1PYERQ8KM5D04GC
ami = "${data.aws_ami.ecs.id}"
instance_type = "t2.micro"
}
resource "aws_instance" "web_2" {
provider = aws.id_01E4KEA5ZAA1PYERQ8KM5D04GC
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.micro"
}
resource "aws_instance" "web_3" {
provider = aws.id_01E4KEA5ZAA1PYERQ8KM5D04GC
ami = "${data.aws_ami.ecs.id}"
instance_type = "t2.micro"
}
resource "aws_instance" "web_4" {
provider = aws.id_01E4KEA5ZAA1PYERQ8KM5D04GC
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.micro"
}
"""

View File

@ -1,22 +0,0 @@
ignition = tf.provider("ignition", "1.1.0")
user = ignition.data.user()
user.name = "foo"
user.uid = 42
user.groups = ["foo", "bar"]
user.system = True
disk = ignition.data.disk()
disk.device = "/dev/sda"
root = disk.partition()
root.start = 2048
root.size = 4 * 1024 * 1024
home = disk.partition()
home.start = root.size + root.start
home.size = 4 * 1024 * 1024
ignition.data.config(disks=[disk.id], users=[user.id])

View File

@ -1,7 +1,51 @@
# Runtime Modules
# AsCode comes with a variety of modules available like `http`, `math`,
# `encoding/json`, etc. All this [modules](/docs/reference/) are available
# runtime through the [`load`](/docs/starlark/statements/#load-statements)
# statement. This example shows the usage of this modules and some others.
# <!--more-->
# ## Basic Module
# The load statement expects at least two arguments; the first is the name of
# the module, and the same the symbol to extract to it. The runtime modules
# always define a symbol called equals to the last part of the module name.
load("encoding/base64", "base64")
load("http", "http")
# This modules are very usuful to do basic operations such as encoding of
# strings, like in this case to `base64` or to make HTTP requests.
dec = base64.encode("ascode is amazing")
msg = http.get("https://httpbin.org/base64/%s" % dec)
print(msg.body())
print(msg.body())
# ### Output
"""sh
ascode is amazing
"""
# ## Advanced Modules
# Also, AsCode has some more specif modules, like the `docker` module. The
# docker modules allow you to manipulate docker image names.
load("experimental/docker", "docker")
# A docker image tag can be defined using semver, instead of using the infamous
# 'latest' tag, or fixing a particular version. This allows us to be up-to-date
# without breaking our deployment.
golang = docker.image("golang", "1.13.x")
# We can use this in the definition of resources, allowing use to upgrade
# the version of our containers in every `terraform apply`
p = tf.provider("docker", "2.7.0")
container = p.resource.container("golang", image=golang.version(full=True))
# version queries the docker repository and returns the correct tag.
print(hcl(container))
# ### Output
"""hcl
resource "docker_container" "foo" {
provider = docker.id_01E4KHW2RSW0FQM93KN5W70Y42
image = "docker.io/library/golang:1.13.9"
}
"""

102
_scripts/example-to-md.go Normal file
View File

@ -0,0 +1,102 @@
package main
import (
"bufio"
"bytes"
"fmt"
"log"
"os"
"strings"
)
func main() {
md, err := exampleToMD(os.Args[1], os.Args[2])
if err != nil {
log.Fatal(err)
}
fmt.Println(md)
}
func exampleToMD(filename string, weight string) (string, error) {
b := bytes.NewBuffer(nil)
f, err := os.Open(filename)
if err != nil {
return "", err
}
var isComment, isCodeBlock, isPrint bool
var preLine string
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
curIsComment := len(line) > 0 && line[0] == '#'
if isCodeBlock && len(preLine) == 0 && curIsComment {
isPrint = false
}
if len(preLine) >= 3 && preLine[:3] == `"""` {
isPrint = false
}
if isPrint {
preLine = strings.Trim(preLine, "#")
fmt.Fprintln(b, preLine)
isPrint = false
}
preLine = line
if curIsComment {
line = strings.TrimSpace(line[1:])
isComment = true
if isCodeBlock {
fmt.Fprintln(b, "```\n\n")
isCodeBlock = false
}
if b.Len() == 0 {
fmt.Fprintf(b,
"---\ntitle: '%s'\nweight: %s\n---\n\n",
line, weight,
)
continue
}
isPrint = true
continue
}
if len(line) == 0 && isComment {
isPrint = true
continue
}
if isComment {
isComment = false
isCodeBlock = true
if len(line) >= 3 && line[:3] == `"""` {
fmt.Fprintln(b, "```"+line[3:])
continue
}
fmt.Fprintln(b, "\n\n```python")
}
isPrint = true
}
if isCodeBlock {
fmt.Fprintln(b, "```")
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
}
return b.String(), nil
}