Devnet arguments for BigTable connection.

Change-Id: Idc893dc87739d1b309ffefcc67d98641f4bccd9a
This commit is contained in:
jschuldt 2021-07-07 04:39:48 -05:00 committed by Justin Schuldt
parent ce22a18101
commit 9e16baa040
12 changed files with 243 additions and 1 deletions

4
.gitignore vendored
View File

@ -7,4 +7,6 @@ bin
target
/mutagen.sh
venv
.env
.env
bigtable-admin.json
bigtable-writer.json

View File

@ -81,3 +81,10 @@ To Solana as CPI instruction:
Set the include path:
![](https://i.imgur.com/bDij6Cu.png)
## BigTable event persistence
Guardian events can be persisted to a BigTable instance. Launch the devnet with flags supplying your database info to enable forwarding events:
tilt up -- --num=1 --bigTablePersistence --gcpProject=your-project-id --bigTableKeyPath=./your-service-account-key.json

View File

@ -6,6 +6,7 @@
#
load("ext://namespace", "namespace_create", "namespace_inject")
load('ext://secret', 'secret_yaml_generic')
# Runtime configuration
@ -17,9 +18,18 @@ config.define_string("num", False, "Number of guardian nodes to run")
#
config.define_string("namespace", False, "Kubernetes namespace to use")
# These arguments will enable writing Guardian events to a BigTable instance.
# Writing to BigTable is optional. These arguments are not required to run the devnet.
config.define_bool("bigTablePersistence", False, "Enable forwarding guardian events to BigTable")
config.define_string("gcpProject", False, "GCP project ID for BigTable persistence")
config.define_string("bigTableKeyPath", False, "Path to BigTable json key file")
cfg = config.parse()
num_guardians = int(cfg.get("num", "5"))
namespace = cfg.get("namespace", "wormhole")
bigTablePersistence = cfg.get("bigTablePersistence", False)
gcpProject = cfg.get("gcpProject", None)
bigTableKeyPath = cfg.get("bigTableKeyPath", "./bigtable-writer.json")
# namespace
@ -47,6 +57,14 @@ local_resource(
# bridge
if bigTablePersistence:
k8s_yaml_with_ns(
secret_yaml_generic(
"bridge-bigtable-key",
from_file = "bigtable-key.json=" + bigTableKeyPath
)
)
docker_build(
ref = "guardiand-image",
context = "bridge",
@ -63,6 +81,12 @@ def build_bridge_yaml():
if container["name"] != "guardiand":
fail("container 0 is not guardiand")
container["command"] += ["--devNumGuardians", str(num_guardians)]
if bigTablePersistence:
container["command"] += [
"--bigTablePersistenceEnabled",
"--bigTableGCPProject",
gcpProject
]
return encode_yaml_stream(bridge_yaml)

View File

@ -79,6 +79,12 @@ var (
publicRPC *string
publicREST *string
bigTablePersistenceEnabled *bool
bigTableGCPProject *string
bigTableInstanceName *string
bigTableTableName *string
bigTableKeyPath *string
)
func init() {
@ -119,6 +125,12 @@ func init() {
publicRPC = BridgeCmd.Flags().String("publicRPC", "", "Listen address for public gRPC interface")
publicREST = BridgeCmd.Flags().String("publicREST", "", "Listen address for public REST interface")
bigTablePersistenceEnabled = BridgeCmd.Flags().Bool("bigTablePersistenceEnabled", false, "Turn on forwarding events to BigTable")
bigTableGCPProject = BridgeCmd.Flags().String("bigTableGCPProject", "", "Google Cloud project ID for storing events")
bigTableInstanceName = BridgeCmd.Flags().String("bigTableInstanceName", "", "BigTable instance name for storing events")
bigTableTableName = BridgeCmd.Flags().String("bigTableTableName", "", "BigTable table name to store events in")
bigTableKeyPath = BridgeCmd.Flags().String("bigTableKeyPath", "", "Path to json Service Account key")
}
var (
@ -312,6 +324,21 @@ func runBridge(cmd *cobra.Command, args []string) {
logger.Fatal("Please specify --terraContract")
}
if *bigTablePersistenceEnabled {
if *bigTableGCPProject == "" {
logger.Fatal("Please specify --bigTableGCPProject")
}
if *bigTableInstanceName == "" {
logger.Fatal("Please specify --bigTableInstanceName")
}
if *bigTableTableName == "" {
logger.Fatal("Please specify --bigTableTableName")
}
if *bigTableKeyPath == "" {
logger.Fatal("Please specify --bigTableKeyPath")
}
}
ethContractAddr := eth_common.HexToAddress(*ethContract)
bscContractAddr := eth_common.HexToAddress(*bscContract)
solBridgeAddress, err := solana_types.PublicKeyFromBase58(*solanaBridgeAddress)

View File

@ -44,12 +44,21 @@ spec:
# mount shared between containers for runtime state
- name: bridge-rundir
emptyDir: {}
- name: bridge-keysdir
secret:
secretName: bridge-bigtable-key
optional: true
items:
- key: bigtable-key.json
path: bigtable-key.json
containers:
- name: guardiand
image: guardiand-image
volumeMounts:
- mountPath: /run/bridge
name: bridge-rundir
- mountPath: /tmp/mounted-keys
name: bridge-keysdir
command:
# Uncomment this to enable in-place debugging using dlv
# (not suitable for regular development since the process will no longer restart on its own)
@ -93,6 +102,12 @@ spec:
- /tmp/admin.sock
- --dataDir
- /tmp/data
- --bigTableInstanceName
- wormhole-dev
- --bigTableTableName
- v2Events
- --bigTableKeyPath
- /tmp/mounted-keys/bigtable-key.json
# - --logLevel=debug
securityContext:
capabilities:

View File

@ -4,6 +4,11 @@
"Name": "namespace",
"ExtensionRegistry": "https://github.com/tilt-dev/tilt-extensions",
"TimeFetched": "2020-12-05T16:06:07.229737938+01:00"
},
{
"Name": "secret",
"ExtensionRegistry": "https://github.com/tilt-dev/tilt-extensions",
"TimeFetched": "2021-07-01T15:08:09.818136358-05:00"
}
]
}

View File

@ -0,0 +1,51 @@
# Secret
Author: [Nick Santos](https://github.com/nicks)
Helper functions for creating Kubernetes secrets.
## Functions
### secret_yaml_generic
```
secret_yaml_generic(name: str, namespace: str = "", from_file: Union[str, List] = None, secret_type: str = None): Blob
```
Returns YAML for a generic secret.
* `from_file` ( str ) equivalent to `kubectl create secret --from-file`
* `secret_type` ( str ) - equivalent to `kubectl create secret --type`
### secret_create_generic
```
secret_create_generic(name: str, namespace: str = "", from_file: Union[str, List] = None, secret_type: str = None)
```
Deploys a secret to the cluster. Equivalent to
```
load('ext://namespace', 'secret_yaml_generic')
k8s_yaml(secret_yaml_generic('name', from_file=[...]))
```
## Example Usage
### For a Postgres password:
```
load('ext://secret', 'secret_create_generic')
secret_create_generic('pgpass', from_file='.pgpass=./.pgpass')
```
### For Google Cloud Platform Key:
```
load('ext://secret', 'secret_generic_create')
secret_create_generic('gcp-key', from_file='key.json=./gcp-creds.json')
```
## Caveats
- This extension doesn't do any validation to confirm that names or namespaces are valid.

View File

@ -0,0 +1,75 @@
# -*- mode: Python -*-
def secret_yaml_generic(name, namespace="", from_file=None, secret_type=None, from_env_file=None):
"""Returns YAML for a generic secret
Args:
name: The secret name.
namespace: The namespace.
from_file: Use the from-file secret generator. May be a string or a list of strings.
Example: ["ssh--privatekey=path/to/id_rsa", "ssh-publickey=path/to/id_rsa.pub"]
from_env_file: Specify the path to a file to read lines of key=val pairs to create a secret
(i.e. a Docker .env file)
secret_type (optional): Specify the type of the secret
Example: 'kubernetes.io/dockerconfigjson'
Returns:
The secret YAML as a blob
"""
args = [
"kubectl",
"create",
"secret",
"generic",
name,
]
if namespace:
args.extend(["-n", namespace])
generator = False
if from_file:
if type(from_file) == "string":
args.extend(["--from-file", from_file])
generator = True
elif type(from_file) == "list":
for f in from_file:
args.extend(["--from-file", f])
generator = True
else:
fail("Bad from_file argument: %s" % from_file)
if from_env_file:
if type(from_env_file) != "string":
fail("from_env_file only accepts strings")
args.extend(["--from-env-file", from_env_file])
generator = True
if not generator:
fail("No secret generator specified")
if secret_type:
if type(secret_type) == "string":
args.extend(["--type", secret_type])
else:
fail("Bad secret_type argument: %s" % secret_type)
args.extend(["-o=yaml", "--dry-run=client"])
return local(args)
def secret_create_generic(name, namespace="", from_file=None, secret_type=None, from_env_file=None):
"""Creates a secret in the current Kubernetes cluster.
Args:
name: The secret name.
namespace: The namespace.
from_file: Use the from-file secret generator. May be a string or a list of strings.
Example: ["ssh--privatekey=path/to/id_rsa", "ssh-publickey=path/to/id_rsa.pub"]
from_env_file: Specify the path to a file to read lines of key=val pairs to create a secret
(i.e. a Docker .env file)
secret_type (optional): Specify the type of the secret
Example: 'kubernetes.io/dockerconfigjson'
"""
k8s_yaml(secret_yaml_generic(name, namespace, from_file, secret_type, from_env_file))

View File

@ -0,0 +1 @@
hostname:5432:database:username:password

View File

@ -0,0 +1,4 @@
load('../Tiltfile', 'secret_create_generic')
secret_create_generic('pgpass', namespace='default', from_file='.pgpass=./.pgpass')
k8s_yaml('job.yaml')

View File

@ -0,0 +1,24 @@
apiVersion: batch/v1
kind: Job
metadata:
name: secret-verify
spec:
backoffLimit: 1
template:
spec:
containers:
- name: secret-verify
image: alpine
command: ["grep", "password", "/var/secrets/pgpass/.pgpass"]
volumeMounts:
- name: pgpass
mountPath: /var/secrets/pgpass
env:
- name: PGPASSFILE
value: /var/secrets/pgpass/.pgpass
restartPolicy: Never
volumes:
- name: pgpass
secret:
secretName: pgpass
defaultMode: 0600

View File

@ -0,0 +1,7 @@
#!/bin/bash
cd $(dirname $0)
set -ex
tilt ci
tilt down --delete-namespaces