221 lines
7.6 KiB
YAML
221 lines
7.6 KiB
YAML
|
|
apiVersion: v1
|
||
|
|
kind: Secret
|
||
|
|
metadata:
|
||
|
|
name: trillian-mysql
|
||
|
|
namespace: agent-trust
|
||
|
|
type: Opaque
|
||
|
|
stringData:
|
||
|
|
# NOTE: committed in plain form for the first deploy. Rotate to a Sealed
|
||
|
|
# Secret before the first real attestation lands; see deploy/trillian/README.md.
|
||
|
|
MYSQL_ROOT_PASSWORD: trillian-root-dev-only
|
||
|
|
MYSQL_USER: trillian
|
||
|
|
MYSQL_PASSWORD: trillian-dev-only
|
||
|
|
MYSQL_DATABASE: trillian
|
||
|
|
# DSN consumed by the Trillian log server/signer MySQL driver.
|
||
|
|
MYSQL_URI: trillian:trillian-dev-only@tcp(trillian-mysql.agent-trust.svc.cluster.local:3306)/trillian?parseTime=true
|
||
|
|
---
|
||
|
|
# Schema ConfigMap. Content is deploy/trillian/storage.sql (vendored verbatim
|
||
|
|
# from https://github.com/google/trillian/blob/v1.6.1/storage/mysql/schema/storage.sql).
|
||
|
|
# Applied via a mysql init-container at MySQL first start.
|
||
|
|
#
|
||
|
|
# This block MUST be re-generated when deploy/trillian/storage.sql changes:
|
||
|
|
# kubectl -n agent-trust create configmap trillian-mysql-init \
|
||
|
|
# --from-file=storage.sql=deploy/trillian/storage.sql \
|
||
|
|
# --dry-run=client -o yaml > deploy/trillian/10-mysql-init-cm.yaml
|
||
|
|
#
|
||
|
|
# For the first deploy we inline it here so a plain `kubectl apply -f deploy/trillian/`
|
||
|
|
# brings up a working database on its own.
|
||
|
|
apiVersion: v1
|
||
|
|
kind: ConfigMap
|
||
|
|
metadata:
|
||
|
|
name: trillian-mysql-init
|
||
|
|
namespace: agent-trust
|
||
|
|
data:
|
||
|
|
storage.sql: |
|
||
|
|
# MySQL / MariaDB version of the tree schema
|
||
|
|
|
||
|
|
-- ---------------------------------------------
|
||
|
|
-- Tree stuff here
|
||
|
|
-- ---------------------------------------------
|
||
|
|
|
||
|
|
-- Tree parameters should not be changed after creation. Doing so can
|
||
|
|
-- render the data in the tree unusable or inconsistent.
|
||
|
|
CREATE TABLE IF NOT EXISTS Trees(
|
||
|
|
TreeId BIGINT NOT NULL,
|
||
|
|
TreeState ENUM('ACTIVE', 'FROZEN', 'DRAINING') NOT NULL,
|
||
|
|
TreeType ENUM('LOG', 'MAP', 'PREORDERED_LOG') NOT NULL,
|
||
|
|
HashStrategy ENUM('RFC6962_SHA256', 'TEST_MAP_HASHER', 'OBJECT_RFC6962_SHA256', 'CONIKS_SHA512_256', 'CONIKS_SHA256') NOT NULL,
|
||
|
|
HashAlgorithm ENUM('SHA256') NOT NULL,
|
||
|
|
SignatureAlgorithm ENUM('ECDSA', 'RSA', 'ED25519') NOT NULL,
|
||
|
|
DisplayName VARCHAR(20),
|
||
|
|
Description VARCHAR(200),
|
||
|
|
CreateTimeMillis BIGINT NOT NULL,
|
||
|
|
UpdateTimeMillis BIGINT NOT NULL,
|
||
|
|
MaxRootDurationMillis BIGINT NOT NULL,
|
||
|
|
PrivateKey MEDIUMBLOB NOT NULL, -- Unused.
|
||
|
|
PublicKey MEDIUMBLOB NOT NULL, -- This is now used to store settings.
|
||
|
|
Deleted BOOLEAN,
|
||
|
|
DeleteTimeMillis BIGINT,
|
||
|
|
PRIMARY KEY(TreeId)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS TreeControl(
|
||
|
|
TreeId BIGINT NOT NULL,
|
||
|
|
SigningEnabled BOOLEAN NOT NULL,
|
||
|
|
SequencingEnabled BOOLEAN NOT NULL,
|
||
|
|
SequenceIntervalSeconds INTEGER NOT NULL,
|
||
|
|
PRIMARY KEY(TreeId),
|
||
|
|
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS Subtree(
|
||
|
|
TreeId BIGINT NOT NULL,
|
||
|
|
SubtreeId VARBINARY(255) NOT NULL,
|
||
|
|
Nodes MEDIUMBLOB NOT NULL,
|
||
|
|
SubtreeRevision INTEGER NOT NULL,
|
||
|
|
PRIMARY KEY(TreeId, SubtreeId, SubtreeRevision),
|
||
|
|
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS TreeHead(
|
||
|
|
TreeId BIGINT NOT NULL,
|
||
|
|
TreeHeadTimestamp BIGINT,
|
||
|
|
TreeSize BIGINT,
|
||
|
|
RootHash VARBINARY(255) NOT NULL,
|
||
|
|
RootSignature VARBINARY(1024) NOT NULL,
|
||
|
|
TreeRevision BIGINT,
|
||
|
|
PRIMARY KEY(TreeId, TreeHeadTimestamp),
|
||
|
|
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE UNIQUE INDEX TreeHeadRevisionIdx
|
||
|
|
ON TreeHead(TreeId, TreeRevision);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS LeafData(
|
||
|
|
TreeId BIGINT NOT NULL,
|
||
|
|
LeafIdentityHash VARBINARY(255) NOT NULL,
|
||
|
|
LeafValue LONGBLOB NOT NULL,
|
||
|
|
ExtraData LONGBLOB,
|
||
|
|
QueueTimestampNanos BIGINT NOT NULL,
|
||
|
|
PRIMARY KEY(TreeId, LeafIdentityHash),
|
||
|
|
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS SequencedLeafData(
|
||
|
|
TreeId BIGINT NOT NULL,
|
||
|
|
SequenceNumber BIGINT UNSIGNED NOT NULL,
|
||
|
|
LeafIdentityHash VARBINARY(255) NOT NULL,
|
||
|
|
MerkleLeafHash VARBINARY(255) NOT NULL,
|
||
|
|
IntegrateTimestampNanos BIGINT NOT NULL,
|
||
|
|
PRIMARY KEY(TreeId, SequenceNumber),
|
||
|
|
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE,
|
||
|
|
FOREIGN KEY(TreeId, LeafIdentityHash) REFERENCES LeafData(TreeId, LeafIdentityHash) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX SequencedLeafMerkleIdx
|
||
|
|
ON SequencedLeafData(TreeId, MerkleLeafHash);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS Unsequenced(
|
||
|
|
TreeId BIGINT NOT NULL,
|
||
|
|
Bucket INTEGER NOT NULL,
|
||
|
|
LeafIdentityHash VARBINARY(255) NOT NULL,
|
||
|
|
MerkleLeafHash VARBINARY(255) NOT NULL,
|
||
|
|
QueueTimestampNanos BIGINT NOT NULL,
|
||
|
|
QueueID VARBINARY(32) DEFAULT NULL UNIQUE,
|
||
|
|
PRIMARY KEY (TreeId, Bucket, QueueTimestampNanos, LeafIdentityHash)
|
||
|
|
);
|
||
|
|
---
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: trillian-mysql
|
||
|
|
namespace: agent-trust
|
||
|
|
spec:
|
||
|
|
selector:
|
||
|
|
app.kubernetes.io/name: trillian-mysql
|
||
|
|
ports:
|
||
|
|
- name: mysql
|
||
|
|
port: 3306
|
||
|
|
targetPort: 3306
|
||
|
|
clusterIP: None
|
||
|
|
---
|
||
|
|
apiVersion: apps/v1
|
||
|
|
kind: StatefulSet
|
||
|
|
metadata:
|
||
|
|
name: trillian-mysql
|
||
|
|
namespace: agent-trust
|
||
|
|
spec:
|
||
|
|
serviceName: trillian-mysql
|
||
|
|
replicas: 1
|
||
|
|
selector:
|
||
|
|
matchLabels:
|
||
|
|
app.kubernetes.io/name: trillian-mysql
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app.kubernetes.io/name: trillian-mysql
|
||
|
|
spec:
|
||
|
|
initContainers:
|
||
|
|
- name: copy-init-sql
|
||
|
|
image: busybox:1.36.1
|
||
|
|
command:
|
||
|
|
- /bin/sh
|
||
|
|
- -c
|
||
|
|
- cp /src/storage.sql /dst/01-storage.sql
|
||
|
|
volumeMounts:
|
||
|
|
- name: init-sql-src
|
||
|
|
mountPath: /src
|
||
|
|
- name: init-sql
|
||
|
|
mountPath: /dst
|
||
|
|
containers:
|
||
|
|
- name: mysql
|
||
|
|
image: mysql:8.4
|
||
|
|
args:
|
||
|
|
# MySQL 8.4 removed --default-authentication-plugin. The server
|
||
|
|
# defaults to caching_sha2_password; the Trillian MySQL driver
|
||
|
|
# (go-sql-driver/mysql) supports it, so we leave the default.
|
||
|
|
- --character-set-server=utf8mb4
|
||
|
|
- --collation-server=utf8mb4_unicode_ci
|
||
|
|
envFrom:
|
||
|
|
- secretRef:
|
||
|
|
name: trillian-mysql
|
||
|
|
ports:
|
||
|
|
- containerPort: 3306
|
||
|
|
name: mysql
|
||
|
|
volumeMounts:
|
||
|
|
- name: data
|
||
|
|
mountPath: /var/lib/mysql
|
||
|
|
- name: init-sql
|
||
|
|
mountPath: /docker-entrypoint-initdb.d
|
||
|
|
readinessProbe:
|
||
|
|
exec:
|
||
|
|
command: ["mysqladmin", "ping", "-h", "127.0.0.1"]
|
||
|
|
initialDelaySeconds: 10
|
||
|
|
periodSeconds: 5
|
||
|
|
livenessProbe:
|
||
|
|
exec:
|
||
|
|
command: ["mysqladmin", "ping", "-h", "127.0.0.1"]
|
||
|
|
initialDelaySeconds: 60
|
||
|
|
periodSeconds: 20
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
cpu: "100m"
|
||
|
|
memory: "256Mi"
|
||
|
|
limits:
|
||
|
|
memory: "1Gi"
|
||
|
|
volumes:
|
||
|
|
- name: init-sql-src
|
||
|
|
configMap:
|
||
|
|
name: trillian-mysql-init
|
||
|
|
- name: init-sql
|
||
|
|
emptyDir: {}
|
||
|
|
volumeClaimTemplates:
|
||
|
|
- metadata:
|
||
|
|
name: data
|
||
|
|
spec:
|
||
|
|
accessModes: ["ReadWriteOnce"]
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
storage: 10Gi
|
||
|
|
storageClassName: local-path
|