Skip to content

Instantly share code, notes, and snippets.

@rtnpro
Last active January 21, 2016 09:45
Show Gist options
  • Save rtnpro/17add2ab248ac34a7687 to your computer and use it in GitHub Desktop.
Save rtnpro/17add2ab248ac34a7687 to your computer and use it in GitHub Desktop.
Nulecule spec/answers schema comparison

All Nulecule params in global scope; flat answers file

Nulecule

---
specversion: 0.0.2
id: sentry-atomicapp

metadata:
  name: sentry Atomic App
  appversion: 1.0.0
  description: This is sentry

params:
  - name: db_user
    description: Database user
    default: sentry
  - name: db_pass
    description: Database password
    default: password
  - name: db_name
    description: Database name
    default: sentry
  - name: postgres_container_name
    desciption: Container name for postgresql
    default: postgres
  - name: postgres_container_image
    decription: Container image name for postgresql
    default: postgres
  - name: redis_container_name
    default: redis
  - name: redis_image_name
    default: redis
  - name: sentry_container_name
    default: sentry
  - name: sentry_image_name
    default: rtnpro/sentry
  - name: sentry_node_port
    default: 30001

graph:
  - name: postgresql
    params:
      name: $postgres_container_name
      image: $postgres_container_image
      db_name: $db_name
      db_user: $db_user
      db_pass: $db_pass
      service: postgres
    source: docker://pa/pg

  - name: redis
    params:
      name: $redis_container_name
      image: $redis_image_name
      master_service: redis
    source: docker://pa/redis

  - name: sentry
    params:
      name: $sentry_container_name
      image: $sentry_image_name
      nodePort: $sentry_node_port
    artifacts:
      docker:
        - file://artifacts/docker/sentry
      kubernetes:
        - file://artifacts/kubernetes/sentry-pod.yaml
        - file://artifacts/kubernetes/sentry-service.yaml

answers.conf

[general]
redis_image_name = redis
postgres_container_name = postgres
db_pass = password
postgres_container_image = postgres
namespace = default
redis_container_name = redis
db_name = sentry
db_user = sentry
sentry_container_name = sentry
sentry_node_port = 30001
provider = kubernetes
sentry_image_name = rtnpro/sentry

Nulecule global params and private component params; sectional answers file

Nulecule

---
specversion: 0.0.2
id: sentry-atomicapp

metadata:
  name: sentry Atomic App
  appversion: 1.0.0
  description: This is sentry

params:
  - name: db_user
    description: Database user
    default: sentry
  - name: db_name
    description: Database name
    default: sentry
  - name: db_pass
    description: Database password
    default: password

graph:
  - name: postgresql
    params:
      - name: postgres_container_name
        desciption: Container name for postgresql
        default: postgres

      - name: postgres_container_image
        decription: Container image name for postgresql
        default: postgres

    source: docker://pa/pg
    args:
      name: $postgres_container_name
      image: $postgres_container_image
      db_name: $db_name
      db_user: $db_user
      db_pass: $db_pass
      service: postgres

  - name: redis
    params:
      - name: redis_container_name
        default: redis
      - name: redis_image_name
        default: redis
    source: docker://pa/redis
    args:
      name: $redis_container_name
      image: $redis_image_name
      master_service: redis

  - name: sentry
    params:
      - name: sentry_container_name
        default: sentry
      - name: sentry_image_name
        default: rtnpro/sentry
      - name: sentry_node_port
        default: 30001
    args:
      name: $sentry_container_name
      image: $sentry_image_name
      nodePort: $sentry_node_port
    artifacts:
      docker:
        - file://artifacts/docker/sentry
      kubernetes:
        - file://artifacts/kubernetes/sentry-pod.yaml
        - file://artifacts/kubernetes/sentry-service.yaml

answers.conf

[general]
provider = kubernetes
namespace = default

db_name = sentry
db_user = sentry
db_pass = password

[postgresql]
postgres_container_name = postgres
postgres_container_image = postgres

[redis]
redis_container_name = redis
redis_image_name = redis

[sentry]
sentry_container_name = sentry
sentry_node_port = 30001
sentry_image_name = rtnpro/sentry

Concerns

  • How do we pass needed args when using this app from another app, since there's no flat structure for params?

Nulecule with ability to cross reference sibling params, and optionally pass config data to componenents by mapping params in its namespace

Nulecule

---
specversion: 0.0.2
id: sentry-atomicapp

metadata:
  name: sentry Atomic App
  appversion: 1.0.0
  description: This is sentry

graph:
  - name: postgresql
    params:
      - name: db_user
        description: Database user
        default: sentry

      - name: db_pass
        description: Database password
        default: password

      - name: db_name
        description: Database name
        default: sentry

      - name: postgres_container_name
        desciption: Container name for postgresql
        default: postgres

      - name: postgres_container_image
        decription: Container image name for postgresql
        default: postgres
    mapping:
      postgresql:
        name: $postgres_container_name
        image: $postgres_container_image
        db_name: $db_name
        db_user: $db_user
        db_pass: $db_pass
        service: postgres
    source: docker://pa/pg

  - name: redis
    params:
      - name: image_name
        default: redis
      - name: service_name
        default: redis

    mapping:
        # Dict similar to config data needed by the external application
        redismaster-app:
            image: $image_name
            service: $redis_service_name

        # By default mapping extends current config data
        # extend false will help in providing only those data
        # the external app and it's children needs
        # Default value is true.
        _inherit: false

    source: docker://pa/redis

  - name: sentry
    params:
      - name: container_name
        default: sentry
      - name: image_name
        default: rtnpro/sentry
      - name: node_port
        default: 30001

      # Reference a param from a sibling component
      - name: db_user
        link: $postgresql.db_user

      # Reference a param from a sibling component.
      - name: db_pass
        link: $postgresql.db_pass

    # Hypothetical, but allow mapping config values for local apps
    # if needed
    mapping:
        sentry:
          name: $container_name
          image: $image_name
          nodePort: $node_port

    artifacts:
      docker:
        - file://artifacts/docker/sentry
      kubernetes:
        - file://artifacts/kubernetes/sentry-pod.yaml
        - file://artifacts/kubernetes/sentry-service.yaml

answers.conf

[general]
provider=kubernetes
namespace=default

[postgresql]
db_user: sentry
db_pass: password
db_name: sentry
postgres_container_name: sentry_postgres
postgres_container_image: postgres

[redis]
image_name: redis
service_name: redis

[sentry]
container_name: sentry
image_name: rtnpro/sentry
node_port: 9000

[redis:redisslave-app]
hostport: 6390

Comments:

  • Cross referencing params across siblings removes the problem of having duplicate param definitions and assignment (in answers file)
  • Mapping allows to update, override, and hence control the config data that gets passed to the component. This allows explicit and controlled distribution of config data from the root Nulecule application to all the leaves. Also, this allows abstracting an external Nulecule application and it's children altogether, even if the external Nulecule application does not use mapping.
  • This leads to a cleaner answers file with sections belonging to the components of the Nulecule application I am consuming
  • However, this does not stop, updating or patching config data for a Nulecule component at any level in answers.conf. For example, we have overriden the default values of redis-slave in external redis app.
  • This seems to be backwards compatible with the current Nulecule params.
@rtnpro
Copy link
Author

rtnpro commented Jan 6, 2016

One important reason for the work on refactoring the Nulecule params was that, I should not care to know what are the child components of a Nulecule when using it in another Nulecule app. However, that said, I should not be restricted to know about a Nulecule component at any level and override variables in it's scope.

This is easily possible by adding extra sections in answers.conf:

[level1_comp1:level2_comp3:level3_comp2]
key1=var1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment