| local kube = import "../../../kube/kube.libsonnet"; |
| |
| { |
| IX: { |
| local ix = self, |
| local cfg = ix.cfg, |
| cfg:: { |
| image: "registry.k0.hswaw.net/bgpwtf/cccampix:1566584484-a2960f526c36de0dbcd911f05ee9db587e63eb9b", |
| |
| |
| octorpki: { |
| image: cfg.image, |
| storageClassName: "waw-hdd-redundant-2", |
| resources: { |
| requests: { cpu: "200m", memory: "1Gi" }, |
| limits: { cpu: "1", memory: "2Gi" }, |
| }, |
| }, |
| |
| verifier: { |
| image: cfg.image, |
| domain: "ix-grpc.bgp.wtf", |
| db: { |
| host: "public.crdb-waw1.svc.cluster.local", |
| port: 26257, |
| username: "cccampix", |
| name: "cccampix", |
| tlsSecret: "client-cccampix-certificate", |
| }, |
| }, |
| |
| pgpencryptor: { |
| image: cfg.image, |
| db: { |
| host: "public.crdb-waw1.svc.cluster.local", |
| port: 26257, |
| username: "cccampix", |
| name: "cccampix-pgpencryptor", |
| tlsSecret: "client-cccampix-certificate", |
| }, |
| }, |
| |
| irr: { |
| image: cfg.image, |
| }, |
| |
| peeringdb: { |
| image: cfg.image, |
| }, |
| |
| frontend: { |
| domain: "ix-status.bgp.wtf", |
| image: cfg.image, |
| }, |
| |
| alice: { |
| domain: "ix-lg.bgp.wtf", |
| image: "registry.k0.hswaw.net/q3k/alice-lg:20190823-1557", |
| }, |
| |
| appName: "ix", |
| namespace: error "namespace must be defined", |
| prefix: "", |
| }, |
| |
| namespace: kube.Namespace(cfg.namespace), |
| name(component):: cfg.prefix + component, |
| metadata(component):: { |
| namespace: cfg.namespace, |
| labels: { |
| "app.kubernetes.io/name": cfg.appName, |
| "app.kubernetes.io/managed-by": "kubecfg", |
| "app.kubernetes.io/component": component, |
| }, |
| }, |
| |
| octorpki: { |
| address:: "%s.%s.svc.cluster.local:%d" % [ |
| "octorpki", |
| ix.cfg.namespace, |
| 8080, |
| ], |
| cache: kube.PersistentVolumeClaim(ix.name("octorpki")) { |
| metadata+: ix.metadata("octorpki"), |
| spec+: { |
| storageClassName: cfg.octorpki.storageClassName, |
| accessModes: [ "ReadWriteOnce" ], |
| resources: { |
| requests: { |
| storage: "2Gi", |
| }, |
| }, |
| }, |
| }, |
| deployment: kube.Deployment(ix.name("octorpki")) { |
| metadata+: ix.metadata("octorpki"), |
| spec+: { |
| template+: { |
| spec+: { |
| volumes_: { |
| cache: kube.PersistentVolumeClaimVolume(ix.octorpki.cache), |
| }, |
| containers_: { |
| octorpki: kube.Container(ix.name("octorpki")){ |
| image: cfg.octorpki.image, |
| args: [ |
| "/octorpki/entrypoint.sh", |
| ], |
| ports_: { |
| client: { containerPort: 8080 }, |
| }, |
| volumeMounts_: { |
| cache: { mountPath: "/cache" }, |
| }, |
| resources: cfg.octorpki.resources, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| svc: kube.Service(ix.name("octorpki")) { |
| metadata+: ix.metadata("octorpki"), |
| target_pod:: ix.octorpki.deployment.spec.template, |
| spec+: { |
| ports: [ |
| { name: "client", port: 8080, targetPort: 8080, protocol: "TCP" }, |
| ], |
| }, |
| }, |
| }, |
| |
| component(name):: { |
| local component = self, |
| args:: error "args must be set", |
| name:: name, |
| port:: 4200, |
| volumes:: {}, |
| volumeMounts:: {}, |
| |
| deployment: kube.Deployment(ix.name(name)) { |
| metadata+: ix.metadata(name), |
| spec+: { |
| template+: { |
| spec+: { |
| volumes_: component.volumes, |
| containers_: { |
| [name]: kube.Container(ix.name(name)) { |
| image: cfg[name].image, |
| args: component.args, |
| volumeMounts_: component.volumeMounts, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| svc: kube.Service(ix.name(name)) { |
| metadata+: ix.metadata(name), |
| target_pod:: component.deployment.spec.template, |
| spec+: { |
| ports: [ |
| { name: "client", port: component.port, targetPort: component.port, protocol: "TCP" }, |
| ], |
| }, |
| }, |
| |
| address:: "%s.%s.svc.cluster.local:%d" % [ |
| component.name, |
| ix.cfg.namespace, |
| component.port, |
| ], |
| }, |
| |
| irr: ix.component("irr") { |
| args: [ |
| "/ix/irr", |
| "-hspki_disable", |
| "-listen_address=0.0.0.0:4200", |
| ], |
| }, |
| |
| peeringdb: ix.component("peeringdb") { |
| args: [ |
| "/ix/peeringdb", |
| "-hspki_disable", |
| "-listen_address=0.0.0.0:4200", |
| ], |
| }, |
| |
| crdb:: { |
| volumes: { |
| tls: { |
| secret: { |
| secretName: cfg.verifier.db.tlsSecret, |
| defaultMode: kube.parseOctal("0400"), |
| }, |
| }, |
| }, |
| volumeMounts: { |
| tls: { |
| mountPath: "/tls", |
| }, |
| }, |
| args(dbconf): [ |
| "-dsn", "postgres://%s@%s:%d/%s?sslmode=require&sslrootcert=%s&sslcert=%s&sslkey=%s" % [ |
| dbconf.username, |
| dbconf.host, |
| dbconf.port, |
| dbconf.name, |
| "/tls/ca.crt", |
| "/tls/tls.crt", |
| "/tls/tls.key", |
| ], |
| ] |
| }, |
| |
| verifier: ix.component("verifier") { |
| volumes: ix.crdb.volumes, |
| volumeMounts: ix.crdb.volumeMounts, |
| args: [ |
| "/ix/verifier", |
| "-hspki_disable", |
| "-listen_address=0.0.0.0:4200", |
| "-peeringdb=" + ix.peeringdb.address, |
| "-irr=" + ix.irr.address, |
| "-octorpki=" + ix.octorpki.address, |
| "-pgpencryptor=" + ix.pgpencryptor.address, |
| ] + ix.crdb.args(cfg.verifier.db), |
| }, |
| |
| pgpencryptor: ix.component("pgpencryptor") { |
| volumes: ix.crdb.volumes, |
| volumeMounts: ix.crdb.volumeMounts, |
| args: [ |
| "/ix/pgpencryptor", |
| "-hspki_disable", |
| "-listen_address=0.0.0.0:4200", |
| ] + ix.crdb.args(cfg.pgpencryptor.db), |
| }, |
| |
| frontend: ix.component("frontend") { |
| port: 8080, |
| args: [ |
| "/ix/frontend.par", |
| "--flask_secret=dupa", |
| "--listen=0.0.0.0:8080", |
| "--verifier=" + ix.verifier.address, |
| ], |
| }, |
| |
| alice: ix.component("alice") { |
| port: 7340, |
| volumes: { |
| config: kube.ConfigMapVolume(ix.alice.configMap), |
| theme: kube.ConfigMapVolume(ix.alice.themeMap), |
| }, |
| volumeMounts: { |
| config: { |
| mountPath: "/etc/alice", |
| }, |
| theme: { |
| mountPath: "/etc/alice-theme", |
| }, |
| }, |
| args: [ |
| "/usr/bin/alice-lg", |
| "-config", "/etc/alice/alice", |
| ], |
| |
| themeMap: kube.ConfigMap(ix.name("alice-theme")) { |
| metadata+: ix.metadata("alice-theme"), |
| data: { |
| "content.js": ||| |
| Alice.updateContent({ |
| header: { |
| title: "CCCampIX Looking Glass", |
| tagline: "powered by alice-lg" |
| }, |
| welcome: { |
| title: "CCCampIX Looking Glass", |
| tagline: "BGP to the tent." |
| } |
| }); |
| |||, |
| }, |
| }, |
| configMap: kube.ConfigMap(ix.name("alice")) { |
| metadata+: ix.metadata("alice"), |
| data: { |
| config: ||| |
| [server] |
| listen_http = 0.0.0.0:7340 |
| enable_neighbors_status_refresh = false |
| asn = 208521 |
| |
| [housekeeping] |
| interval = 5 |
| force_release_memory = true |
| |
| [theme] |
| path = /etc/alice-theme |
| |
| [pagination] |
| routes_filtered_page_size = 250 |
| routes_accepted_page_size = 250 |
| routes_not_exported_page_size = 250 |
| |
| [rejection_reasons] |
| 208521:65666:1 = An IP Bogon was detected |
| 208521:65666:2 = Prefix is longer than 64 |
| 208521:65666:3 = Prefix is longer than 24 |
| 208521:65666:4 = AS path contains a bogon AS |
| 208521:65666:5 = AS path length is longer than 64 |
| 208521:65666:6 = BGP Path invalid (must be only peer) |
| 208521:65666:9 = Prefix not found in RPKI for Origin AS |
| |
| [neighbours_columns] |
| Description = Description |
| address = Neighbour |
| asn = ASN |
| state = State |
| Uptime = Uptime |
| routes_received = Routes Received |
| routes_filtered = Filtered |
| |
| [routes_columns] |
| network = Network |
| gateway = Gateway |
| interface = Interface |
| metric = Metric |
| bgp.as_path = AS Path |
| |
| [lookup_columns] |
| network = Network |
| gateway = Gateway |
| neighbour.asn = ASN |
| neighbour.description = Description |
| bgp.as_path = AS Path |
| routeserver.name = RS |
| |
| [source.rs1-camp-v4] |
| name = rs1.camp.bgp.wtf (IPv4) |
| group = Camp |
| [source.rs1-camp-v4.birdwatcher] |
| timezone = UTC |
| api = http://isw01.camp.bgp.wtf:3000/ |
| type = single_table |
| neighbors_refresh_timeout = 2 |
| servertime = 2006-01-02T15:04:05Z |
| servertime_short = 2006-01-02 15:04:05 |
| servertime_ext = 2006-01-02 15:04:05 |
| |
| [source.rs1-camp-v6] |
| name = rs1.camp.bgp.wtf (IPv6) |
| group = Camp |
| [source.rs1-camp-v6.birdwatcher] |
| timezone = UTC |
| api = http://isw01.camp.bgp.wtf:3001/ |
| type = single_table |
| neighbors_refresh_timeout = 2 |
| servertime = 2006-01-02T15:04:05Z |
| servertime_short = 2006-01-02 15:04:05 |
| servertime_ext = 2006-01-02 15:04:05 |
| |
| [source.rs2-camp-v4] |
| name = rs2.camp.bgp.wtf (IPv4) |
| group = Camp |
| [source.rs2-camp-v4.birdwatcher] |
| timezone = UTC |
| api = http://isw01.camp.bgp.wtf:3002/ |
| type = single_table |
| neighbors_refresh_timeout = 2 |
| servertime = 2006-01-02T15:04:05Z |
| servertime_short = 2006-01-02 15:04:05 |
| servertime_ext = 2006-01-02 15:04:05 |
| |
| [source.rs2-camp-v6] |
| name = rs2.camp.bgp.wtf (IPv6) |
| group = Camp |
| [source.rs2-camp-v6.birdwatcher] |
| timezone = UTC |
| api = http://isw01.camp.bgp.wtf:3003/ |
| type = single_table |
| neighbors_refresh_timeout = 2 |
| servertime = 2006-01-02T15:04:05Z |
| servertime_short = 2006-01-02 15:04:05 |
| servertime_ext = 2006-01-02 15:04:05 |
| |||, |
| }, |
| }, |
| }, |
| |
| ripeSync: kube.CronJob(ix.name("ripe-sync")) { |
| metadata+: ix.metadata("ripe-sync"), |
| spec+: { |
| schedule: "*/5 * * * *", |
| jobTemplate+: { |
| spec+: { |
| selector:: null, |
| template+: { |
| spec+: { |
| containers_: { |
| "ripe-sync": kube.Container(ix.name("ripe-sync")) { |
| image: cfg.image, |
| args: [ |
| "/ix/ripe-sync.par", |
| "$(PASSWORD)", |
| ix.verifier.address, |
| ], |
| env_: { |
| PASSWORD: { |
| secretKeyRef: { |
| name: ix.name("ripe-sync"), |
| key: "password", |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| |
| ingress: kube.Ingress("ingress") { |
| metadata+: ix.metadata("public") { |
| annotations+: { |
| "kubernetes.io/tls-acme": "true", |
| "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod", |
| "nginx.ingress.kubernetes.io/proxy-body-size": "0", |
| }, |
| }, |
| spec+: { |
| tls: [ |
| { hosts: [cfg.frontend.domain], secretName: "public-tls"} |
| ], |
| rules: [ |
| { |
| host: cfg.frontend.domain, |
| http: { |
| paths: [ |
| { path: "/", backend: ix.frontend.svc.name_port }, |
| ], |
| }, |
| }, |
| ], |
| }, |
| }, |
| |
| aliceIngress: kube.Ingress("alice") { |
| metadata+: ix.metadata("alice") { |
| annotations+: { |
| "kubernetes.io/tls-acme": "true", |
| "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod", |
| "nginx.ingress.kubernetes.io/proxy-body-size": "0", |
| }, |
| }, |
| spec+: { |
| tls: [ |
| { hosts: [cfg.alice.domain], secretName: "alice-tls"} |
| ], |
| rules: [ |
| { |
| host: cfg.alice.domain, |
| http: { |
| paths: [ |
| { path: "/", backend: ix.alice.svc.name_port }, |
| ], |
| }, |
| }, |
| ], |
| }, |
| }, |
| |
| grpcIngress: kube.Ingress("grpc") { |
| metadata+: ix.metadata("grpc") { |
| annotations+: { |
| "kubernetes.io/tls-acme": "true", |
| "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod", |
| "kubernetes.io/ingress.class": "nginx", |
| "nginx.ingress.kubernetes.io/ssl-redirect": "true", |
| "nginx.ingress.kubernetes.io/backend-protocol": "GRPC", |
| }, |
| }, |
| spec+: { |
| tls: [ |
| { hosts: [cfg.verifier.domain], secretName: "grpc-tls"} |
| ], |
| rules: [ |
| { |
| host: cfg.verifier.domain, |
| http: { |
| paths: [ |
| { path: "/", backend: ix.verifier.svc.name_port }, |
| ], |
| }, |
| }, |
| ], |
| }, |
| }, |
| }, |
| } |