0

i am trying to write some wrapper logic for deployments with Tanka/Jsonnet, but seem to be running into some issue, that is probably very simple to solve.

I am trying to create some wrapper-function for a statefulSet that adds e.g. some stdLabels at multiple locations, but keep getting an error regarding Expected token OPERATOR but got "." on the stateful.new. It works without the local variable, but i have no clue as to why or how to solve this?

{
  local k = import 'github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet',
  local container = k.core.v1.container,
  local stateful = k.apps.v1.statefulSet,

  fns: {
    customStateful(name, config, c):: {

      local stdLabels = {
        realm: $._config.ingress.realm,
        app: name,
        'app.kubernetes.io/part-of': config.name,
      },
    
      stateful.new(
        name=name,
        replicas=null,
        containers=[]
      )
      + stateful.metadata.withLabels(stdLabels)
      + stateful.spec.template.metadata.withLabels(stdLabels)
    }
  },
  
 $.aed.customStateful('test', cfg, container.new('test', alpine:latest)),

 
}
strowi
  • 27
  • 3

1 Answers1

0

The main issue is that customStateful():: {...} is returning an object, thus every entry there should be { key1: value1, key2: value, ...}, you need to change it to be customStateful():: (...) instead.

Pasting below a fixed example:

main.jsonnet

For other readers, mind you need to run tk init to be able to try this code

// main.jsonnet
//
{
  local k = import 'github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet',
  local container = k.core.v1.container,
  local stateful = k.apps.v1.statefulSet,

  // plug just to make below code work when referring to $._config, as per provided example
  _config:: { ingress:: { realm:: 'bar' } },

  // cfg used by customStateful 2nd argument in the provided example, create some foo setting
  local cfg = { name: 'foo' },

  fns:: {
    // NB: returning () instead of {}, to be able to return stateful.new() + overloads,
    //     else it would need to be a named field, e.g.  { sts: stateful.new(...) }
    customStateful(name, config, c):: (

      local stdLabels = {
        realm: $._config.ingress.realm,
        app: name,
        'app.kubernetes.io/part-of': config.name,
      };

      stateful.new(
        name=name,
        replicas=null,
        containers=[]
      )
      + stateful.metadata.withLabels(stdLabels)
      + stateful.spec.template.metadata.withLabels(stdLabels)
    ),
  },

  foo: $.fns.customStateful('test', cfg, container.new('test', 'alpine:latest')),
}

output

$ tk init
$ tk eval main.jsonnet
{
  "foo": {
    "apiVersion": "apps/v1",
    "kind": "StatefulSet",
    "metadata": {
      "labels": {
        "app": "test",
        "app.kubernetes.io/part-of": "foo",
        "realm": "bar"
      },
      "name": "test"
    },
    "spec": {
      "replicas": null,
      "selector": {
        "matchLabels": {
          "name": "test"
        }
      },
      "template": {
        "metadata": {
          "labels": {
            "app": "test",
            "app.kubernetes.io/part-of": "foo",
            "realm": "bar"
          }
        },
        "spec": {
          "containers": []
        }
      },
      "updateStrategy": {
        "type": "RollingUpdate"
      }
    }
  }
}
jjo
  • 2,595
  • 1
  • 8
  • 16
  • 1
    Oh man, thank you very much! I kinda start hating jsonnet's syntax.. ;) Is there any documentation anywhere about the different brackets and meaning? E.g. difference between putting `local k =..` inside and outside the outermost brackets etc.. – strowi Oct 05 '22 at 17:32
  • You're welcome @strowi!, Not particularly on that topio, tho I highly recommend https://tanka.dev/tutorial/jsonnet in case you didn't yet follow it. PS: appreciate if you can mark the question as answered, as it'll also help others finding it. – jjo Oct 06 '22 at 11:56
  • Okay at least it's not my fault of not searching thorough enough. Still all the differente braces and ":" vs "::" are a little confusing. (And i have my fair share with other languages). ;) – strowi Oct 06 '22 at 14:01
  • totally agree!, jsonnet is a language that needs care, patience and practice to "get" it :) – jjo Oct 07 '22 at 12:50