Git Product home page Git Product logo

spiff's Introduction

                                        ___ _ __ (_)/ _|/ _|
                                       / __| '_ \| | |_| |_
                                       \__ \ |_) | |  _|  _|
                                       |___/ .__/|_|_| |_|
                                           |_|


NOTE: Active development on spiff is currently paused, including Pull Requests. Very severe issues will be addressed, and we will still be actively responding to requests for help via Issues.


spiff is a command line tool and declarative YAML templating system, specially designed for generating BOSH deployment manifests.

Contents:

Installation

Official release executable binaries can be downloaded via Github releases for Darwin and Linux machines (and virtual machines).

Some of spiff's dependencies have changed since the last official release, and spiff will not be updated to keep up with these dependencies. Working dependencies are vendored in the Godeps directory (more information on the godep tool is available here). As such, trying to go get spiff will likely fail; the only supported way to use spiff is to use an official binary release.

Usage

spiff merge template.yml [template2.ymll ...]

Merge a bunch of template files into one manifest, printing it out.

See 'dynaml templating language' for details of the template file, or examples/ subdir for more complicated examples.

Example:

spiff merge cf-release/templates/cf-deployment.yml my-cloud-stub.yml

spiff diff manifest.yml other-manifest.yml

Show structural differences between two deployment manifests.

Unlike basic diffing tools and even bosh diff, this command has semantic knowledge of a deployment manifest, and is not just text-based. For example, if two manifests are the same except they have some jobs listed in different orders, spiff diff will detect this, since job order matters in a manifest. On the other hand, if two manifests differ only in the order of their resource pools, for instance, then it will yield and empty diff since resource pool order doesn't actually matter for a deployment.

Also unlike bosh diff, this command doesn't modify either file.

It's tailored for checking differences between one deployment and the next.

Typical flow:

$ spiff merge template.yml [templates...] > upgrade.yml
$ bosh download manifest [deployment] current.yml
$ spiff diff upgrade.yml current.yml
$ bosh deployment upgrade.yml
$ bosh deploy

dynaml Templating Language

Spiff uses a declarative, logic-free templating language called 'dynaml' (dynamic yaml).

Every dynaml node is guaranteed to resolve to a YAML node. It is not string interpolation. This keeps developers from having to think about how a value will render in the resulting template.

A dynaml node appears in the .yml file as an expression surrounded by two parentheses. They can be used as the value of a map or an entry in a list.

The following is a complete list of dynaml expressions:

(( foo ))

Look for the nearest 'foo' key (i.e. lexical scoping) in the current template and bring it in.

e.g.:

fizz:
  buzz:
    foo: 1
    bar: (( foo ))
  bar: (( foo ))
foo: 3
bar: (( foo ))

This example will resolve to:

fizz:
  buzz:
    foo: 1
    bar: 1
  bar: 3
foo: 3
bar: 3

The following will not resolve because the key name is the same as the value to be merged in:

foo: 1

hi:
  foo: (( foo ))

(( foo.bar.[1].baz ))

Look for the nearest 'foo' key, and from there follow through to .bar.baz.

A path is a sequence of steps separated by dots. A step is either a word for maps, or digits surrounded by brackets for list indexing.

If the path cannot be resolved, this evaluates to nil. A reference node at the top level cannot evaluate to nil; the template will be considered not fully resolved. If a reference is expected to sometimes not be provided, it should be used in combination with '||' (see below) to guarantee resolution.

Note that references are always within the template, and order does not matter. You can refer to another dynamic node and presume it's resolved, and the reference node will just eventually resolve once the dependent node resolves.

e.g.:

properties:
  foo: (( something.from.the.stub ))
  something: (( merge ))

This will resolve as long as 'something' is resolveable, and as long as it brings in something like this:

from:
  the:
    stub: foo

(( "foo" ))

String literal. The only escape character handled currently is '"'.

(( "foo" bar ))

Concatenation (where bar is another dynaml expr).

e.g.

domain: example.com
uri: (( "https://" domain ))

In this example uri will resolve to the value "https://example.com".

(( auto ))

Context-sensitive automatic value calculation.

In a resource pool's 'size' attribute, this means calculate based on the total instances of all jobs that declare themselves to be in the current resource pool.

e.g.:

resource_pools:
  - name: mypool
    size: (( auto ))

jobs:
  - name: myjob
    resource_pool: mypool
    instances: 2
  - name: myotherjob
    resource_pool: mypool
    instances: 3
  - name: yetanotherjob
    resource_pool: otherpool
    instances: 3

In this case the resource pool size will resolve to '5'.

(( merge ))

Bring the current path in from the stub files that are being merged in.

e.g.:

foo:
  bar:
    baz: (( merge ))

Will try to bring in foo.bar.baz from the first stub, or the second, etc., returning the value from the first stub that provides it.

If the corresponding value is not defined, it will return nil. This then has the same semantics as reference expressions; a nil merge is an unresolved template. See ||.

<<: (( merge ))

Merging maps

values.yml

foo:
  a: 1
  b: 2

template.yml

foo:
  <<: (( merge ))
  b: 3
  c: 4

spiff merge template.yml values.yml yields:

foo:
  a: 1
  b: 2
  c: 4

Merging lists

values.yml

foo:
  - 1
  - 2

template.yml

foo:
  - 3
  - <<: (( merge ))
  - 4

spiff merge template.yml values.yml yields:

foo:
  - 3
  - 1
  - 2
  - 4

(( a || b ))

Uses a, or b if a cannot be resolved.

e.g.:

foo:
  bar:
    - name: some
    - name: complicated
    - name: structure

mything:
  complicated_structure: (( merge || foo.bar ))

This will try to merge in mything.complicated_structure, or, if it cannot be merged in, use the default specified in foo.bar.

(( !foo ))

Leaves the string (( !foo )) in the resulting merge.

e.g.: calling spiff merge on a file with the contents below:

bar: (( !foo ))
foo: 33

will simply result in:

bar: (( !foo ))
foo: 33

(( static_ips(0, 1, 3) ))

Generate a list of static IPs for a job.

e.g.:

jobs:
  - name: myjob
    instances: 2
    networks:
    - name: mynetwork
      static_ips: (( static_ips(0, 3, 4) ))

This will create 3 IPs from mynetworks subnet, and return two entries, as there are only two instances. The two entries will be the 0th and 3rd offsets from the static IP ranges defined by the network.

For example, given the file bye.yml:

networks: (( merge ))

jobs:
  - name: myjob
    instances: 3
    networks:
    - name: cf1
      static_ips: (( static_ips(0,3,60) ))

and file hi.yml:

networks:
- name: cf1
  subnets:
  - cloud_properties:
      security_groups:
      - cf-0-vpc-c461c7a1
      subnet: subnet-e845bab1
    dns:
    - 10.60.3.2
    gateway: 10.60.3.1
    name: default_unused
    range: 10.60.3.0/24
    reserved:
    - 10.60.3.2 - 10.60.3.9
    static:
    - 10.60.3.10 - 10.60.3.70
  type: manual
spiff merge bye.yml hi.yml

returns

jobs:
- instances: 3
  name: myjob
  networks:
  - name: cf1
    static_ips:
    - 10.60.3.10
    - 10.60.3.13
    - 10.60.3.70
networks:
- name: cf1
  subnets:
  - cloud_properties:
      security_groups:
      - cf-0-vpc-c461c7a1
      subnet: subnet-e845bab1
    dns:
    - 10.60.3.2
    gateway: 10.60.3.1
    name: default_unused
    range: 10.60.3.0/24
    reserved:
    - 10.60.3.2 - 10.60.3.9
    static:
    - 10.60.3.10 - 10.60.3.70
  type: manual

.

If bye.yml was instead

networks: (( merge ))

jobs:
  - name: myjob
    instances: 2
    networks:
    - name: cf1
      static_ips: (( static_ips(0,3,60) ))
spiff merge bye.yml hi.yml

instead returns

jobs:
- instances: 2
  name: myjob
  networks:
  - name: cf1
    static_ips:
    - 10.60.3.10
    - 10.60.3.13
networks:
- name: cf1
  subnets:
  - cloud_properties:
      security_groups:
      - cf-0-vpc-c461c7a1
      subnet: subnet-e845bab1
    dns:
    - 10.60.3.2
    gateway: 10.60.3.1
    name: default_unused
    range: 10.60.3.0/24
    reserved:
    - 10.60.3.2 - 10.60.3.9
    static:
    - 10.60.3.10 - 10.60.3.70
  type: manual

spiff's People

Contributors

amitkgupta avatar cdavisafc avatar christopherclark avatar cppforlife avatar dsabeti avatar emalm avatar fraenkel avatar gberche-orange avatar hsiliev avatar jamesclonk avatar jfmyers9 avatar mavenraven avatar maxbrunsfeld avatar mikfreedman avatar onsi avatar vito avatar xoebus avatar zrob avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spiff's Issues

memory leak when network ranges are incorrect

If you have a broken network range, like:

        static:
          - 10.20.4.10 - 10.10.4.50

(note it starts in 10.20.x.x and ends in 10.10.x.x). Currently, that causes spiff to use all available memory and die. Detecting that as a problem and spitting out an error would be a more ideal outcome.

Install in Centos 7 unable to run

How is this installed? I have downloaded the spiff source from Git, but are there examples to how should I run spiff with my cf-stub.yml?

Besides, installing GOLANG, what environment variables should I set?

Please advise.

error: command '/usr/bin/gcc-4.8' failed with exit status 1

I'm trying to install spiff on ubuntu 14.04.2 desktop, first I install linux brew:

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/linuxbrew/go/install)"
$ export PATH=$PATH:/home/dzlab/.linuxbrew/bin

Then I try to install spiff:

$ brew install spiff
==> Installing spiff from xoebus/homebrew-cloudfoundry
==> Installing dependencies for spiff: mercurial, godep
==> Installing spiff dependency: mercurial
==> Downloading http://mercurial.selenic.com/release/mercurial-3.3.tar.gz
Already downloaded: /home/heavenize/.cache/Homebrew/mercurial-3.3.tar.gz
==> make PREFIX=/home/heavenize/.linuxbrew/Cellar/mercurial/3.3 install-bin
 #include <Python.h>
                                 ^
compilation terminated.
error: command '/usr/bin/gcc-4.8' failed with exit status 1
make: *** [build] Error 1

READ THIS: https://github.com/Homebrew/linuxbrew/blob/master/share/doc/homebrew/Troubleshooting.md#troubleshooting

How I can fix this issue? is there another way to install spiff on ubuntu?

Add x86_64/Darwin build for release v0.1

. ~/Downloads/spiff_darwin_amd64 
/Users/drnic/Downloads/spiff_darwin_amd64:1: command not found: ????^G
/Users/drnic/Downloads/spiff_darwin_amd64:4: parse error near `)'

But:

$ uname -a
Darwin drnic.local 12.5.0 Darwin Kernel Version 12.5.0: Sun Sep 29 13:33:47 PDT 2013; root:xnu-2050.48.12~1/RELEASE_X86_64 x86_64

I have an X86 mac air. Can we release spiff for this arch?

BTW, who has amd64 for Darwin? Which machine is that?

Spiff merge seems to be nondeterministic.

Im using spiff for merging CF templates, and Ive noticed that using spiff merge yields a couple of different results when using the same templates.

# repeat is zsh specific
$ (repeat 100 ../../cf-release/generate_deployment_manifest vsphere hehe.yml | md5sum ) | sort | uniq -c
     12 1347cc537cab4d703abcb8cef63cdd44  -
     17 2ae0e8eb50deca14c86663d611f47486  -
     19 2d19dffe513c56d22b4211e78dcbe441  -
     14 5c7b72eb080a3849109e7b59c2dded89  -
     11 67ef6a2ebee92aa90edf63b9b167ee5f  -
     14 75e3e55e9c4415bbcc1d5a7cecd7b672  -
     13 773bd7f0cde35ef78f759d5b6e5400e3  -
$ (repeat 100 ../../cf-release/generate_deployment_manifest vsphere hehe.yml | md5sum ) | sort | uniq -c
     10 1347cc537cab4d703abcb8cef63cdd44  -
     13 2ae0e8eb50deca14c86663d611f47486  -
     18 2d19dffe513c56d22b4211e78dcbe441  -
     18 5c7b72eb080a3849109e7b59c2dded89  -
     17 67ef6a2ebee92aa90edf63b9b167ee5f  -
     11 75e3e55e9c4415bbcc1d5a7cecd7b672  -
     13 773bd7f0cde35ef78f759d5b6e5400e3  -
# Notice how the distribution changes between runs aswell
$ pwd && git rev-parse HEAD
/home/simon/go/src/github.com/cloudfoundry-incubator/spiff
96389b2819f0324de7b90cb4609208100a1f5cfb

$ spiff --v
spiff version 1.0.2

$ pwd && git rev-parse HEAD 
/home/simon/src/cf-release
c4dfff2fe703fd05c4a9044b492d8e4abfb4ac6b # Aka tag v173

Here is the hehe.yml (minimum that is needed for spiff to manage to merge)


---
name:
director_uuid:

meta:
  stemcell:
    name:

networks:
  - name: cf1
    subnets:
      - range:
        static:
          - 10.230.8.1 - 10.230.8.20

  - name: cf2
    subnets:
      - range:
        static:
          - 10.230.9.1 - 10.230.9.20

properties:

  dea_next:
    memory_mb:
    disk_mb:

  loggregator_endpoint:
    shared_secret:

  cc:
    bulk_api_password:
    staging_upload_user:
    staging_upload_password:
    db_encryption_key:
    srv_api_uri:

  uaa:
    jwt:
      signing_key:
      verification_key:
    cc:
      client_secret:
    admin:
      client_secret:
    clients:
      login:
        secret:
      cc_service_broker_client:
        secret:
      developer_console:
        secret:
      app-direct:
        secret:
      support-services:
        secret:
      servicesmgmt:
        secret:
      space-mail:
        secret:
    scim:
      users:
    batch:
      username:
      password:

  nats:
    user:
    password:

  router:
    status:
      user:
      password:

Please let me know if there is any additional information needed!

YAML anchor

For me it looks like there is a bug in spiff if the source yml file is
using YAML anchor.

Something like this

test1: &test1
  a: 2
  b: 2
test2:
  <<: *test1

should merge the values from test1 into test2.

Currently this example results in:

test1:
  a: 2
  b: 2
test2:
  <<:
    a: 2
    b: 2

after processing the yml file with spiff.

So the <<: is used as a key and the values are added with the wrong indent.

how to run the tests?

Sorry to have to ask - how do I install the source dependencies and run the test suite?

I think its go test but I get the complaints about missing packages:

go test
../../../launchpad.net/goyaml/emitterc.go:4:2: cannot find package "bytes" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/bytes (from $GOROOT)
    /Users/drnic/Projects/golang/src/bytes (from $GOPATH)
dynaml/parser.go:4:2: cannot find package "container/list" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/container/list (from $GOROOT)
    /Users/drnic/Projects/golang/src/container/list (from $GOPATH)
yaml/parser.go:4:2: cannot find package "errors" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/errors (from $GOROOT)
    /Users/drnic/Projects/golang/src/errors (from $GOPATH)
../../codegangsta/cli/context.go:5:2: cannot find package "flag" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/flag (from $GOROOT)
    /Users/drnic/Projects/golang/src/flag (from $GOPATH)
spiff.go:4:2: cannot find package "fmt" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/fmt (from $GOROOT)
    /Users/drnic/Projects/golang/src/fmt (from $GOPATH)
../../../launchpad.net/goyaml/apic.go:4:2: cannot find package "io" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/io (from $GOROOT)
    /Users/drnic/Projects/golang/src/io (from $GOPATH)
../../codegangsta/cli/app.go:5:2: cannot find package "io/ioutil" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/io/ioutil (from $GOROOT)
    /Users/drnic/Projects/golang/src/io/ioutil (from $GOPATH)
spiff.go:6:2: cannot find package "log" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/log (from $GOROOT)
    /Users/drnic/Projects/golang/src/log (from $GOPATH)
../../../launchpad.net/goyaml/resolve.go:4:2: cannot find package "math" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/math (from $GOROOT)
    /Users/drnic/Projects/golang/src/math (from $GOPATH)
dynaml/call.go:4:2: cannot find package "net" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/net (from $GOROOT)
    /Users/drnic/Projects/golang/src/net (from $GOPATH)
../../../launchpad.net/goyaml/apic.go:5:2: cannot find package "os" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/os (from $GOROOT)
    /Users/drnic/Projects/golang/src/os (from $GOPATH)
../../../launchpad.net/goyaml/decode.go:4:2: cannot find package "reflect" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/reflect (from $GOROOT)
    /Users/drnic/Projects/golang/src/reflect (from $GOPATH)
yaml/find.go:4:2: cannot find package "regexp" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/regexp (from $GOROOT)
    /Users/drnic/Projects/golang/src/regexp (from $GOPATH)
../../../launchpad.net/goyaml/goyaml.go:8:2: cannot find package "runtime" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/runtime (from $GOROOT)
    /Users/drnic/Projects/golang/src/runtime (from $GOPATH)
../../../launchpad.net/goyaml/encode.go:5:2: cannot find package "sort" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/sort (from $GOROOT)
    /Users/drnic/Projects/golang/src/sort (from $GOPATH)
../../../launchpad.net/goyaml/decode.go:5:2: cannot find package "strconv" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/strconv (from $GOROOT)
    /Users/drnic/Projects/golang/src/strconv (from $GOPATH)
../../../launchpad.net/goyaml/goyaml.go:9:2: cannot find package "strings" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/strings (from $GOROOT)
    /Users/drnic/Projects/golang/src/strings (from $GOPATH)
../../../launchpad.net/goyaml/goyaml.go:10:2: cannot find package "sync" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/sync (from $GOROOT)
    /Users/drnic/Projects/golang/src/sync (from $GOPATH)
../../codegangsta/cli/help.go:6:2: cannot find package "text/tabwriter" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/text/tabwriter (from $GOROOT)
    /Users/drnic/Projects/golang/src/text/tabwriter (from $GOPATH)
../../codegangsta/cli/help.go:7:2: cannot find package "text/template" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/text/template (from $GOROOT)
    /Users/drnic/Projects/golang/src/text/template (from $GOPATH)
../../codegangsta/cli/app.go:7:2: cannot find package "time" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/time (from $GOROOT)
    /Users/drnic/Projects/golang/src/time (from $GOPATH)
../../../launchpad.net/goyaml/sorter.go:5:2: cannot find package "unicode" in any of:
    /usr/local/Cellar/go/1.2/src/pkg/unicode (from $GOROOT)
    /Users/drnic/Projects/golang/src/unicode (from $GOPATH)

The Cartridge file looks like it mentions dependencies; but I'm not sure how to use it to install the deps. Could you please update the README for developers and I'll test out the README on how to do testing? Thanks!

<<: doesn't work for arrays

the example I put in the release doesn't actually work

bar:
  - 1
  - 2

foo:
  - 3
  - <<: (( bar ))
  - 4

spiff merge yields:

bar:
- 1
- 2
foo:
- 3
- {}
- 4

error messages are unclear

As an example, I ran the following command:

± ac+cj |master ✓| → spiff merge a1/cf-aws-stub.yml dijon/aws_vpc_receipt.yml
2014/01/17 16:09:27 error parsing stub: YAML error: line 133: did not find URI escaped octet

and when looking on line 133 of either file, neither of them have any kind or merge or "(( -))" syntax. This makes debugging a bad merge a bit more difficult.

spiff diff does not show differences in template ordering

spiff diff fails to recognize that the ordering of templates is relevant (not for bosh but -in practice- for monit)

$ cat a.yml 

---
templates:
  mytemplate:
  - name: A
    version: 1
  - name: B
    version: 2
$ cat b.yml 

---
templates:
  mytemplate:
  - name: B
    version: 2
  - name: A
    version: 1
$ spiff diff a.yml b.yml 
no differences!
$ spiff -v
spiff version 1.0.8dev

Spiff removes quotes

I've tried to use spiff to generate deploy manifest for RabbitMQ server. And I was unpleasantly surprised with it's automatic removing quotes feature. Please check:

$ cat rabbit.yml 
  rabbitmq:
    user: "rabbit"
    password: "with space"
    exchange: "amq.direct"
    host: "192.168.1.1"

$ spiff m rabbit.yml 
rabbitmq:
  exchange: amq.direct
  host: 192.168.1.1
  password: with space
  user: rabbit

Please note, that some services like RabbitMQ requires to use quotes with values containing characters like spaces or dots. So now I can't use Spiff to generate manifests for RabitMQ.
Is there any way to prevent Spiff to remove quotes? Why it's does it at all?

Cannot install spiff with "go get"

I got this error with "go get -v -u github.com/cloudfoundry-incubator/spiff"

$ go version
go version go1.4.2 linux/amd64

$ go get -v -u github.com/cloudfoundry-incubator/spiff
github.com/cloudfoundry-incubator/spiff (download)
github.com/cloudfoundry-incubator/candiedyaml (download)
github.com/codegangsta/cli (download)
github.com/cloudfoundry-incubator/candiedyaml
github.com/codegangsta/cli
github.com/cloudfoundry-incubator/spiff/yaml
# github.com/cloudfoundry-incubator/spiff/yaml
bin/src/github.com/cloudfoundry-incubator/spiff/yaml/node.go:23: cannot use AnnotatedNode literal (type AnnotatedNode) as type Node in return argument:
    AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
        have MarshalYAML() (string, interface {})
        want MarshalYAML() (string, interface {}, error)
bin/src/github.com/cloudfoundry-incubator/spiff/yaml/parser.go:49: cannot use AnnotatedNode literal (type AnnotatedNode) as type Node in return argument:
    AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
        have MarshalYAML() (string, interface {})
        want MarshalYAML() (string, interface {}, error)
bin/src/github.com/cloudfoundry-incubator/spiff/yaml/parser.go:63: cannot use AnnotatedNode literal (type AnnotatedNode) as type Node in return argument:
    AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
        have MarshalYAML() (string, interface {})
        want MarshalYAML() (string, interface {}, error)
bin/src/github.com/cloudfoundry-incubator/spiff/yaml/parser.go:66: cannot use AnnotatedNode literal (type AnnotatedNode) as type Node in return argument:
    AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
        have MarshalYAML() (string, interface {})
        want MarshalYAML() (string, interface {}, error)

Unable to concat calculated value

The following example works:

offset: 1

template_only:
  offset1: (( offset + 0 ))
  offset2: (( offset + 1 ))

result:

offset: 1
template_only:
  offset1: 1
  offset2: 2

But when I want to use offset1 in a concat:

offset: 1

template_only:
  offset1: (( offset + 0 ))
  offset2: (( offset + 1 ))

network-range1: (( "10.0." template_only.offset1 ".0/24"  ))
network-range2: (( "10.0." template_only.offset2 ".0/24"  ))

I get:

2014/01/29 14:25:16 error generating manifest: unresolved nodes:
    dynaml.ConcatenationExpr{{10.0.} {{[template_only offset1]} {.0/24}}}
    dynaml.ConcatenationExpr{{10.0.} {{[template_only offset2]} {.0/24}}}

Add support for (( $env_var )) syntax

Currently in order to blend in env var into .yml one needs to have template file, sed the placeholder for env var, then spiff merge - which basically defeats the purpose of using spiff. Adding this support (which I hope would be next to trivial) would reduce the boilerplate significantly.

Spiff is not honest when handle ""

I have the following YAML file, in which I hardcoded some key value pair and enclose with "". Then after running spiff to replace some parts of the template.yml (didn't attach here, since the merge works great), I found the hardcoded key value pair format are changed. " -> ' or deleted ..

Could spiff be honest to keep the "" part if no merge required, just copy the original one directly to output

template.yml:

foo:
  json: "{key: value}"  
  non-json: "key: value"
$ spiff merge template.yml:

foo:
  non-json: key: value
  json: '{key: value}'

Goyaml package dependency

The goyaml package can't be downloaded when executing:

go get -v github.com/cloudfoundry-incubator/spiff

A manual download of the files via bzr into $GOPATH/src/launchpad.net/goyaml
solved the problem for me.

spiff does not evaluate static_ips method if parameter has a trailing space

Given that hi.yml is

networks:
- name: cf1
  subnets:
  - cloud_properties:
      security_groups:
      - cf-0-vpc-c461c7a1
      subnet: subnet-e845bab1
    dns:
    - 10.60.3.2
    gateway: 10.60.3.1
    name: default_unused
    range: 10.60.3.0/24
    reserved:
    - 10.60.3.2 - 10.60.3.9
    static:
    - 10.60.3.10 - 10.60.3.70
  type: manual

and that bye.yml is

networks: (( merge ))

jobs:
  - name: myjob
    instances: 2
    networks:
    - name: mynetwork
      static_ips: (( static_ips(0, 3, 4 ) ))

.

spiff merge bye.yml hi.yml 

returns

jobs:
- instances: 2
  name: myjob
  networks:
  - name: mynetwork
    static_ips: (( static_ips(0, 3, 4 ) ))
networks:
- name: cf1
  subnets:
  - cloud_properties:
      security_groups:
      - cf-0-vpc-c461c7a1
      subnet: subnet-e845bab1
    dns:
    - 10.60.3.2
    gateway: 10.60.3.1
    name: default_unused
    range: 10.60.3.0/24
    reserved:
    - 10.60.3.2 - 10.60.3.9
    static:
    - 10.60.3.10 - 10.60.3.70
  type: manual

It would be would be nice if this case either errored out, or ignored the trailing whitespace.

Go1 compatibility

Attempts to compile Spiff with go1 compiler (which is what Ubuntu 12.04 provides) fail with

# github.com/vito/spiff/yaml
/usr/lib/go/src/pkg/github.com/vito/spiff/yaml/parser.go:31: function ends without a return statement

The go1.1 requirement is an obstacle for those looking to use cf-release as older distributions don't provide it.

"go install" instructions fail for me

$  go install github.com/vito/spiff
Projects/golang/src/github.com/vito/spiff/spiff.go:10:2: cannot find package "github.com/codegangsta/cli" in any of:
    /usr/local/Cellar/go/1.1.2/src/pkg/github.com/codegangsta/cli (from $GOROOT)
    /Users/drnic/Projects/golang/src/github.com/codegangsta/cli (from $GOPATH)
Projects/golang/src/github.com/vito/spiff/yaml/parser.go:7:2: cannot find package "launchpad.net/goyaml" in any of:
    /usr/local/Cellar/go/1.1.2/src/pkg/launchpad.net/goyaml (from $GOROOT)
    /Users/drnic/Projects/golang/src/launchpad.net/goyaml (from $GOPATH)

$ echo $GOPATH
/Users/drnic/Projects/golang

$ cd $GOPATH
$ tree -L 3
...
└── src
    ├── cgl.tideland.biz
    │   ├── applog
    │   ├── asserts
    │   ├── cache
    │   ├── cells
    │   ├── config
    │   ├── ebus
    │   ├── identifier
    │   ├── mapreduce
    │   ├── markup
    │   ├── monitoring
    │   ├── net
    │   ├── numerics
    │   ├── redis
    │   ├── sort
    │   ├── state
    │   ├── supervisor
    │   ├── time
    │   ├── util
    │   ├── web
    │   └── worm
    ├── code.google.com
    │   └── p
    └── github.com
        ├── cloudfoundry
        ├── mitchellh
        ├── racker
        ├── rackspace
        └── vito

Ideas?

BREW for Linux User

There is tutorial said

brew tap xoebus/homebrew-cloudfoundry
brew install spiff
spiff

anyone can help how to install spiff for linux user.

F

Precompiled binary fails on macOS Sierra

I only tested version 1.0.7, and it fails under some circumstances with

failed MSpanList_Insert 0x51a140 0x38b6af607ebb 0x0
fatal error: MSpanList_Insert

I believe it is related to this bug: golang/go#16352

I've recompiled spiff on Sierra using Go 1.7.3, and the new binary works fine. So maybe the binary releases for Darwin should be recompiled.

go get fails with "AnnotatedNode does not implement Node"

go verion: 1.4.2
system: ubuntu 14.04

$ go get github.com/cloudfoundry-incubator/spiff
# github.com/cloudfoundry-incubator/spiff/yaml
gopath/src/github.com/cloudfoundry-incubator/spiff/yaml/node.go:23: cannot use AnnotatedNode literal (type AnnotatedNode) as type Node in return argument:
    AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
        have MarshalYAML() (string, interface {})
        want MarshalYAML() (string, interface {}, error)
gopath/src/github.com/cloudfoundry-incubator/spiff/yaml/parser.go:49: cannot use AnnotatedNode literal (type AnnotatedNode) as type Node in return argument:
    AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
        have MarshalYAML() (string, interface {})
        want MarshalYAML() (string, interface {}, error)
gopath/src/github.com/cloudfoundry-incubator/spiff/yaml/parser.go:63: cannot use AnnotatedNode literal (type AnnotatedNode) as type Node in return argument:
    AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
        have MarshalYAML() (string, interface {})
        want MarshalYAML() (string, interface {}, error)
gopath/src/github.com/cloudfoundry-incubator/spiff/yaml/parser.go:66: cannot use AnnotatedNode literal (type AnnotatedNode) as type Node in return argument:
    AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
        have MarshalYAML() (string, interface {})
        want MarshalYAML() (string, interface {}, error)

Spiff for Ubuntu

Hello,

Found Spiff for MacOSX and Linux, but for Ubuntu, i have tried same as for Linux, but that binary seems not working.
Is there any way to install spiff for Ubuntu.
Help in this would be great.

Thanks & Regards,
Sreelatha.

error generating manifest: unresolved nodes

Running

generate_deployment_manifest aws

from the master branch of cf-release gives me the following

2014/06/12 14:29:30 error generating manifest: unresolved nodes:
    (( properties.template_only.aws.availability_zone ))    in dynaml   meta.zones.z1
    (( properties.template_only.aws.availability_zone2 ))   in dynaml   meta.zones.z2
    (( properties.template_only.aws.access_key_id ))    in dynaml   meta.fog_config.aws_access_key_id
    (( properties.template_only.aws.secret_access_key ))    in dynaml   meta.fog_config.aws_secret_access_key
    (( merge )) in ./templates/cf-infrastructure-aws.yml    properties.template_only
    (( properties.template_only.aws.access_key_id ))    in dynaml   properties.cc.resource_pool.fog_connection.aws_access_key_id
    (( properties.template_only.aws.secret_access_key ))    in dynaml   properties.cc.resource_pool.fog_connection.aws_secret_access_key
    (( properties.template_only.aws.access_key_id ))    in dynaml   properties.cc.packages.fog_connection.aws_access_key_id
    (( properties.template_only.aws.secret_access_key ))    in dynaml   properties.cc.packages.fog_connection.aws_secret_access_key
    (( properties.template_only.aws.access_key_id ))    in dynaml   properties.cc.droplets.fog_connection.aws_access_key_id
    (( properties.template_only.aws.secret_access_key ))    in dynaml   properties.cc.droplets.fog_connection.aws_secret_access_key
    (( properties.template_only.aws.access_key_id ))    in dynaml   properties.cc.buildpacks.fog_connection.aws_access_key_id
    (( properties.template_only.aws.secret_access_key ))    in dynaml   properties.cc.buildpacks.fog_connection.aws_secret_access_key
    (( meta.zones.z1 )) in dynaml   compilation.cloud_properties.availability_zone
    (( properties.template_only.aws.subnet_ids.cf1 ))   in dynaml   networks.[0].subnets.[0].cloud_properties.subnet
    (( properties.template_only.aws.subnet_ids.cf2 ))   in dynaml   networks.[1].subnets.[0].cloud_properties.subnet
    (( meta.zones.z1 )) in dynaml   resource_pools.[0].cloud_properties.availability_zone
    (( meta.zones.z2 )) in dynaml   resource_pools.[1].cloud_properties.availability_zone
    (( meta.zones.z1 )) in dynaml   resource_pools.[2].cloud_properties.availability_zone
    (( meta.zones.z2 )) in dynaml   resource_pools.[3].cloud_properties.availability_zone
    (( meta.zones.z1 )) in dynaml   resource_pools.[4].cloud_properties.availability_zone
    (( meta.zones.z2 )) in dynaml   resource_pools.[5].cloud_properties.availability_zone
    (( meta.zones.z1 )) in dynaml   resource_pools.[6].cloud_properties.availability_zone
    (( meta.zones.z2 )) in dynaml   resource_pools.[7].cloud_properties.availability_zone
    (( meta.zones.z1 )) in dynaml   resource_pools.[8].cloud_properties.availability_zone
    (( meta.zones.z2 )) in dynaml   resource_pools.[9].cloud_properties.availability_zone
    (( meta.zones.z1 )) in dynaml   resource_pools.[10].cloud_properties.availability_zone

go get -v github.com/cloudfoundry-incubator/spiff; spiff => command not found: spiff

$ go get -v github.com/cloudfoundry-incubator/spiff
github.com/cloudfoundry-incubator/spiff (download)
import "bytes": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports bytes: unrecognized import path "bytes"
import "errors": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports errors: unrecognized import path "errors"
import "flag": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports flag: unrecognized import path "flag"
import "fmt": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports fmt: unrecognized import path "fmt"
import "io/ioutil": import path doesn't contain a hostname
package github.com/cloudfoundry-incubator/spiff
    imports io/ioutil: unrecognized import path "io/ioutil"
import "os": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports os: unrecognized import path "os"
import "runtime": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports runtime: unrecognized import path "runtime"
import "strconv": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports strconv: unrecognized import path "strconv"
import "strings": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports strings: unrecognized import path "strings"
import "text/tabwriter": import path doesn't contain a hostname
package github.com/cloudfoundry-incubator/spiff
    imports text/tabwriter: unrecognized import path "text/tabwriter"
import "text/template": import path doesn't contain a hostname
package github.com/cloudfoundry-incubator/spiff
    imports text/template: unrecognized import path "text/template"
import "time": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports time: unrecognized import path "time"
github.com/vito/spiff (download)
import "io": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports github.com/vito/spiff/compare
    imports github.com/vito/spiff/yaml
    imports io: unrecognized import path "io"
import "math": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports github.com/vito/spiff/compare
    imports github.com/vito/spiff/yaml
    imports math: unrecognized import path "math"
import "reflect": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports github.com/vito/spiff/compare
    imports github.com/vito/spiff/yaml
    imports reflect: unrecognized import path "reflect"
import "sort": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports github.com/vito/spiff/compare
    imports github.com/vito/spiff/yaml
    imports sort: unrecognized import path "sort"
import "sync": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports github.com/vito/spiff/compare
    imports github.com/vito/spiff/yaml
    imports sync: unrecognized import path "sync"
import "unicode": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports github.com/vito/spiff/compare
    imports github.com/vito/spiff/yaml
    imports unicode: unrecognized import path "unicode"
import "regexp": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports github.com/vito/spiff/compare
    imports github.com/vito/spiff/yaml
    imports regexp: unrecognized import path "regexp"
import "container/list": import path doesn't contain a hostname
package github.com/cloudfoundry-incubator/spiff
    imports github.com/vito/spiff/compare
    imports github.com/vito/spiff/yaml
    imports github.com/vito/spiff/flow
    imports container/list: unrecognized import path "container/list"
import "net": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports github.com/vito/spiff/compare
    imports github.com/vito/spiff/yaml
    imports github.com/vito/spiff/flow
    imports net: unrecognized import path "net"
import "log": import path doesn't contain a slash
package github.com/cloudfoundry-incubator/spiff
    imports github.com/vito/spiff/compare
    imports github.com/vito/spiff/yaml
    imports github.com/vito/spiff/flow
    imports log: unrecognized import path "log"
$ spiff
zsh: command not found: spiff

My env vars:

$  echo $GOPATH                                     
/Users/drnic/Projects/golang
$  echo $PATH  
/Users/drnic/.rvm/gems/ruby-1.9.3-p448/bin:/Users/drnic/.rvm/gems/ruby-1.9.3-p448@global/bin:/Users/drnic/.rvm/rubies/ruby-1.9.3-p448/bin:/Users/drnic/.rvm/bin:/usr/local/heroku/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/drnic/bin:/Users/drnic/Projects/pebble-dev/arm-cs-tools/bin:/Users/drnic/Projects/golang/bin:/Users/drnic/bin

Value tracing to source document

As a bosh release writer who uses several stubs to generate a complete manifest, I want to supply spiff a command line argument, like --trace, and receive lookup information that describes where spiff derived final values.

This might be in the form of a symmetrical yml file where values are swapped with filenames of the source document, or inline comment. The main intent is so that folks who use stubs can easily figure out how an unintended resultant value came to be and where to go to correct it. There is also cases of hash keys being blocked from the completed manifest, and this information would be illustrative of where to look for that as well.

Error installing from homebrew

I tried installing from homebrew but got the following error:

lmsurpre@Lees-MacBook-Pro ~> brew install spiff
==> Cloning https://github.com/cloudfoundry-incubator/spiff.git
Updating /Library/Caches/Homebrew/spiff--git
==> Checking out tag v0.3
==> rsync -avR --exclude src ./ src/github.com/cloudfoundry-incubator/spiff
==> gocart install
output:
launchpad.net/goyaml (download)
go: missing Bazaar command. See http://golang.org/s/gogetcmd
package launchpad.net/goyaml: exec: "bzr": executable file not found in $PATH

I installed bzr but got the same error again. Not sure if homebrew is caching something or what...

int64 Support

Would it be possible to support int64 numbers? Currently there is a int32 defined and we're using values that are to big for int32. For example postgres shmall parameter.

The code part where spiff stops is this part

error generating manifest: unresolved nodes

Hi all,

I'm trying to create my cf-deployment.yml to deploy CF via bosh. When i launch the command :

./generate_deployment_manifest openstack ../cf-stub.yml > cf-deployment.yml

I have the following error :

2015/04/29 05:31:53 error generating manifest: unresolved nodes:
(( merge )) in ./templates/cf-properties.yml properties.uaa.clients.gorouter.secret (properties.uaa.clients.gorouter.secret)

whereas i dont't find any mention of the properties.uaa.clients.gorouter.secret attribute neither in my ../cf-stub.yml, nor in my cf-deployment.yml.

Thanks in advance for your support.
Sylvain

Merge of array and value works differently

Take 3 files - merge them together:

riak-core.yml

jobs:
- name: riak
  template: riak
  instances: (( merge ))
  networks:
  - name: riak-network
    static_ips: (( merge ))

4_server_toggle.yml

jobs:
- name: riak
  instances: 4
  networks:
  - name: riak-network
    static_ips:
    - 10.244.3.6
    - 10.244.3.10
    - 10.244.3.14
    - 10.244.3.22

env.yml

jobs:
- name: riak
  instances: 3
  networks:
  - name: riak-network
    static_ips:
    - 10.244.3.6
    - 10.244.3.10
    - 10.244.3.14
spiff merge riak-core.yml 4_server_toggle.yml env.yml

results in instances = 3, but with 4 IPs in the static IPs array

spiff merge riak-core.yml env.yml 4_server_toggle.yml

results in instances = 4, but with 3 IPs in the static IPs array

repeating the 4_server_toggle.yml reference leads to the "correct" output

spiff merge riak-core.yml 4_server_toggle.yml env.yml 4_server_toggle.yml

results in instances = 4, with 4 IPs in the static IPs array

Is this expected behavior? spiff version 1.0.0 on Mac

thanks

James M

Unable to install spiff in vagrant on windows

Command go get -v github.com/cloudfoundry-incubator/spiff resulting in the following error.

github.com/cloudfoundry-incubator/spiff/yaml
/root/go/src/github.com/cloudfoundry-incubator/spiff/yaml/node.go:23: cannot use AnnotatedNode literal (type AnnotatedNo
de) as type Node in return argument:
AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
have MarshalYAML() (string, interface {})
want MarshalYAML() (string, interface {}, error)
/root/go/src/github.com/cloudfoundry-incubator/spiff/yaml/parser.go:49: cannot use AnnotatedNode literal (type Annotated
Node) as type Node in return argument:
AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
have MarshalYAML() (string, interface {})
want MarshalYAML() (string, interface {}, error)
/root/go/src/github.com/cloudfoundry-incubator/spiff/yaml/parser.go:63: cannot use AnnotatedNode literal (type Annotated
Node) as type Node in return argument:
AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
have MarshalYAML() (string, interface {})
want MarshalYAML() (string, interface {}, error)
/root/go/src/github.com/cloudfoundry-incubator/spiff/yaml/parser.go:66: cannot use AnnotatedNode literal (type Annotated
Node) as type Node in return argument:
AnnotatedNode does not implement Node (wrong type for MarshalYAML method)
have MarshalYAML() (string, interface {})
want MarshalYAML() (string, interface {}, error)

It would be nice if someone could let me know how to resolve the above error.

helpers that support static IPs and DNS

@vito any thoughts on how we might have a set of helpers that aren't specific to static_ips; rather could allocate/find a set of static IPs, if using static IPs, or specify the DNS entry for the target job if using DNS?

Add a property to a pre-existing node

Would it be possible to add the ability to add a property to a node downstream after the node exists. Basically its hard to extend or override if the “leftmost” yml files don’t allow for that extension/override.

distribute spiff via homebrew

packer is distributing itself via brew tap homebrew/binary; perhaps spiff could also distribute itself this way for OS X users

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.