Commit Graph
1950 Commits
Author SHA1 Message Date
Timothy Messier fe7c87dc82 feat(bsr/ssh): Add open failure details to ChannelSummary (#3297) 2023-06-08 11:17:32 -04:00
Cameron Perera eaaaae5cce chore: bump ui commit (#3296) 2023-06-07 16:28:11 -07:00
Todd 5a68d789ec Initialize base context when creating New worker and not at start (#3294) 2023-06-07 11:42:16 -07:00
Timothy Messier f7386a5d53 Merge pull request #3280 from hashicorp/tmessi-fix-session-list
fix(session): List performance with large number of session connections

This includes the backported migration and a migration to ensure the next
release has the correct view.
2023-06-06 14:34:15 -04:00
Michael Milton fbf56793c6 Add snapshot job (#3282)
* snapshot job

* update census to include context, controller to include snapshot registry

* no need to export runFn in snapshot
2023-06-06 14:26:01 -04:00
Timothy Messier 603642f271 fix(session): List performance with large number of session connections (#3288)
As part of the performance improvements for listing sessions for v0.9.0,
the view used to retrieve sessions for listing was updated to no longer
include a join on session_connection. However, a later migration that
was adding additional columns to this view inadvertently re-added the
join and session_connection columns. This resulted in requests to list
sessions performing this join, and returning additional rows for each
connection in a session. The application would ignore this additional
data, since it is no longer returned via the API. This would be
particularly impactful in cases where there are a large number of
connections per session, as this would greatly increase the amount of
data returned by the database.

This fix removes the session_connection join from this view, which
should restore the original performance improvements even in cases where
there is a large number of session connections per session.

See: https://github.com/hashicorp/boundary/pull/2160
Ref: 32070678dc
Fixes: 1e3c941be1

(cherry picked from commit 7aef341682e65b42c1b919e03936bdf81e26e87c)
2023-06-06 17:45:53 +00:00
Timothy Messier 876f9bb07f fix(session): List performance with large number of session connections
As part of the performance improvements for listing sessions for v0.9.0,
the view used to retrieve sessions for listing was updated to no longer
include a join on session_connection. However, a later migration that
was adding additional columns to this view inadvertently re-added the
join and session_connection columns. This resulted in requests to list
sessions performing this join, and returning additional rows for each
connection in a session. The application would ignore this additional
data, since it is no longer returned via the API. This would be
particularly impactful in cases where there are a large number of
connections per session, as this would greatly increase the amount of
data returned by the database.

This fix removes the session_connection join from this view, which
should restore the original performance improvements even in cases where
there is a large number of session connections per session.

See: https://github.com/hashicorp/boundary/pull/2160
Ref: 32070678dc
Fixes: 1e3c941be1
2023-06-06 17:45:30 +00:00
Timothy Messier 7e094d824f feat(bsr/convert): Remove asciicast minimum window size (#3287)
This removes the minimum on width and height, instead it will just used
the largest width, height seen as the initial size for the asciicast.
This also provides the ability to still set a minimum via options to
convert.ToAsciicast if the caller has a known minimum size. Also note
that in cases where there is no size information, ie if there was no pty
request, this will still pick a default size of 80x24.
2023-06-06 12:26:46 -04:00
Michael Gaffney 99a8777866 fix(db): Add index to session connection table
This index improves the performance for two queries on the
`session_connection` table. The execution time for the first query went
from 40.105 ms to 1.405 ms. The execution time for the second query went
from 13.808 ms to 0.217 ms.

Query 1 explain plan before index:

    Update on session_connection  (cost=6465.17..6557.68 rows=11 width=50) (actual time=38.868..39.147 rows=3 loops=1)
      ->  Nested Loop  (cost=6465.17..6557.68 rows=11 width=50) (actual time=38.471..38.506 rows=3 loops=1)
            ->  HashAggregate  (cost=6464.75..6464.86 rows=11 width=40) (actual time=38.447..38.450 rows=3 loops=1)
                  Group Key: (session_connection_1.public_id)::text
                  Batches: 1  Memory Usage: 24kB
                  ->  Nested Loop Semi Join  (cost=0.42..6464.72 rows=11 width=40) (actual time=29.184..38.434 rows=3 loops=1)
                        ->  Seq Scan on session_connection session_connection_1  (cost=0.00..6329.38 rows=16 width=20) (actual time=15.744..38.014 rows=23 loops=1)
                              Filter: ((worker_id)::text = 'w__________k'::text)
                              Rows Removed by Filter: 163607
                        ->  Index Scan using session_connection_state_connection_id_end_time_key on session_connection_state  (cost=0.42..8.45 rows=1 width=20) (actual time=0.016..0.016 rows=0 loops=23)
                              Index Cond: (((connection_id)::text = (session_connection_1.public_id)::text) AND (end_time IS NULL))
                              Filter: ((state = ANY ('{authorized,connected}'::text[])) AND (start_time < (CURRENT_TIMESTAMP - '00:00:05'::interval)))
                              Rows Removed by Filter: 1
            ->  Index Scan using session_connection_pkey on session_connection  (cost=0.42..8.44 rows=1 width=20) (actual time=0.016..0.016 rows=1 loops=3)
                  Index Cond: ((public_id)::text = (session_connection_1.public_id)::text)
    Planning Time: 0.793 ms
    Trigger immutable_columns: time=0.474 calls=3
    Trigger update_connection_state_on_closed_reason: time=0.159 calls=3
    Trigger update_time_column: time=0.034 calls=3
    Trigger update_version_column: time=0.041 calls=3
    Trigger wh_update_session_connection: time=0.688 calls=3
    Execution Time: 40.105 ms

Query 1 explain plan after index:

    Update on session_connection  (cost=152.71..219.87 rows=8 width=50) (actual time=0.497..0.683 rows=3 loops=1)
      ->  Nested Loop  (cost=152.71..219.87 rows=8 width=50) (actual time=0.266..0.292 rows=3 loops=1)
            ->  HashAggregate  (cost=152.29..152.37 rows=8 width=40) (actual time=0.256..0.258 rows=3 loops=1)
                  Group Key: (session_connection_1.public_id)::text
                  Batches: 1  Memory Usage: 24kB
                  ->  Nested Loop Semi Join  (cost=4.94..152.27 rows=8 width=40) (actual time=0.199..0.251 rows=3 loops=1)
                        ->  Bitmap Heap Scan on session_connection session_connection_1  (cost=4.51..50.76 rows=12 width=20) (actual time=0.017..0.035 rows=10 loops=1)
                              Recheck Cond: ((worker_id)::text = 'w__________k'::text)
                              Heap Blocks: exact=9
                              ->  Bitmap Index Scan on session_connection_worker_id_closed_reason_ix  (cost=0.00..4.51 rows=12 width=0) (actual time=0.011..0.011 rows=10 loops=1)
                                    Index Cond: ((worker_id)::text = 'w__________k'::text)
                        ->  Index Scan using session_connection_state_connection_id_end_time_key on session_connection_state  (cost=0.42..8.45 rows=1 width=20) (actual time=0.021..0.021 rows=0 loops=10)
                              Index Cond: (((connection_id)::text = (session_connection_1.public_id)::text) AND (end_time IS NULL))
                              Filter: ((state = ANY ('{authorized,connected}'::text[])) AND (start_time < (CURRENT_TIMESTAMP - '00:00:05'::interval)))
                              Rows Removed by Filter: 1
            ->  Index Scan using session_connection_pkey on session_connection  (cost=0.42..8.44 rows=1 width=20) (actual time=0.010..0.010 rows=1 loops=3)
                  Index Cond: ((public_id)::text = (session_connection_1.public_id)::text)
    Planning Time: 0.614 ms
    Trigger immutable_columns: time=0.279 calls=3
    Trigger update_connection_state_on_closed_reason: time=0.185 calls=3
    Trigger update_time_column: time=0.027 calls=3
    Trigger update_version_column: time=0.032 calls=3
    Trigger wh_update_session_connection: time=0.450 calls=3
    Execution Time: 1.405 ms

Query 2 explain plan before index:

    Limit  (cost=1002.40..6147.94 rows=1 width=253) (actual time=12.244..13.726 rows=1 loops=1)
      ->  Nested Loop Left Join  (cost=1002.40..6147.93 rows=1 width=253) (actual time=12.243..13.724 rows=1 loops=1)
            Join Filter: ((w.public_id)::text = (session_connection.worker_id)::text)
            CTE worker_config_tags
              ->  GroupAggregate  (cost=1.71..2.26 rows=22 width=59) (actual time=0.044..0.082 rows=22 loops=1)
                    Group Key: ct_1.worker_id, ct_1.source
                    ->  Sort  (cost=1.71..1.77 rows=22 width=49) (actual time=0.031..0.034 rows=22 loops=1)
                          Sort Key: ct_1.worker_id, ct_1.source
                          Sort Method: quicksort  Memory: 27kB
                          ->  Seq Scan on server_worker_tag ct_1  (cost=0.00..1.22 rows=22 width=49) (actual time=0.007..0.010 rows=22 loops=1)
            ->  Nested Loop Left Join  (cost=0.14..9.28 rows=1 width=245) (actual time=0.106..0.108 rows=1 loops=1)
                  Join Filter: ((w.public_id)::text = (ct.worker_id)::text)
                  ->  Nested Loop Left Join  (cost=0.14..8.72 rows=1 width=213) (actual time=0.103..0.104 rows=1 loops=1)
                        Join Filter: ((w.public_id)::text = (wt.worker_id)::text)
                        ->  Index Scan using server_worker_pkey on server_worker w  (cost=0.14..8.15 rows=1 width=181) (actual time=0.012..0.012 rows=1 loops=1)
                              Index Cond: ((public_id)::text = 'w__________k'::text)
                        ->  CTE Scan on worker_config_tags wt  (cost=0.00..0.55 rows=1 width=64) (actual time=0.090..0.090 rows=0 loops=1)
                              Filter: (((worker_id)::text = 'w__________k'::text) AND (source = 'api'::text))
                              Rows Removed by Filter: 22
                  ->  CTE Scan on worker_config_tags ct  (cost=0.00..0.55 rows=1 width=64) (actual time=0.001..0.002 rows=1 loops=1)
                        Filter: (((worker_id)::text = 'w__________k'::text) AND (source = 'configuration'::text))
                        Rows Removed by Filter: 8
            ->  GroupAggregate  (cost=1000.00..6136.36 rows=1 width=21) (actual time=12.133..13.610 rows=0 loops=1)
                  Group Key: session_connection.worker_id
                  ->  Gather  (cost=1000.00..6136.35 rows=1 width=13) (actual time=12.132..13.608 rows=0 loops=1)
                        Workers Planned: 2
                        Workers Launched: 2
                        ->  Parallel Seq Scan on session_connection  (cost=0.00..5136.25 rows=1 width=13) (actual time=9.012..9.012 rows=0 loops=3)
                              Filter: ((closed_reason IS NULL) AND ((worker_id)::text = 'w__________k'::text))
                              Rows Removed by Filter: 54544
    Planning Time: 0.398 ms
    Execution Time: 13.808 ms

Query 2 explain plan after index:

    Limit  (cost=2.82..20.03 rows=1 width=253) (actual time=0.132..0.134 rows=1 loops=1)
      ->  Nested Loop Left Join  (cost=2.82..20.02 rows=1 width=253) (actual time=0.131..0.133 rows=1 loops=1)
            Join Filter: ((w.public_id)::text = (session_connection.worker_id)::text)
            CTE worker_config_tags
              ->  GroupAggregate  (cost=1.71..2.26 rows=22 width=59) (actual time=0.046..0.086 rows=22 loops=1)
                    Group Key: ct_1.worker_id, ct_1.source
                    ->  Sort  (cost=1.71..1.77 rows=22 width=49) (actual time=0.033..0.035 rows=22 loops=1)
                          Sort Key: ct_1.worker_id, ct_1.source
                          Sort Method: quicksort  Memory: 27kB
                          ->  Seq Scan on server_worker_tag ct_1  (cost=0.00..1.22 rows=22 width=49) (actual time=0.007..0.011 rows=22 loops=1)
            ->  Nested Loop Left Join  (cost=0.14..9.28 rows=1 width=245) (actual time=0.120..0.120 rows=1 loops=1)
                  Join Filter: ((w.public_id)::text = (ct.worker_id)::text)
                  ->  Nested Loop Left Join  (cost=0.14..8.72 rows=1 width=213) (actual time=0.117..0.118 rows=1 loops=1)
                        Join Filter: ((w.public_id)::text = (wt.worker_id)::text)
                        ->  Index Scan using server_worker_pkey on server_worker w  (cost=0.14..8.15 rows=1 width=181) (actual time=0.011..0.012 rows=1 loops=1)
                              Index Cond: ((public_id)::text = 'w__________k'::text)
                        ->  CTE Scan on worker_config_tags wt  (cost=0.00..0.55 rows=1 width=64) (actual time=0.104..0.105 rows=0 loops=1)
                              Filter: (((worker_id)::text = 'w__________k'::text) AND (source = 'api'::text))
                              Rows Removed by Filter: 22
                  ->  CTE Scan on worker_config_tags ct  (cost=0.00..0.55 rows=1 width=64) (actual time=0.002..0.002 rows=1 loops=1)
                        Filter: (((worker_id)::text = 'w__________k'::text) AND (source = 'configuration'::text))
                        Rows Removed by Filter: 8
            ->  GroupAggregate  (cost=0.42..8.45 rows=1 width=21) (actual time=0.010..0.010 rows=0 loops=1)
                  Group Key: session_connection.worker_id
                  ->  Index Only Scan using session_connection_worker_id_closed_reason_ix on session_connection  (cost=0.42..8.44 rows=1 width=13) (actual time=0.010..0.010 rows=0 loops=1)
                        Index Cond: ((worker_id = 'w__________k'::text) AND (closed_reason IS NULL))
                        Heap Fetches: 0
    Planning Time: 0.544 ms
    Execution Time: 0.217 ms

Closes #3281
2023-06-05 15:22:41 -04:00
Johan Brandhorst-Satzkorn 610df9892b all: propagate more history metadata (#3279)
A few target and host properties were missed when reading historical
data from the history tables.
2023-06-05 10:19:11 -07:00
Jim 2b3e50ebdd fix (listing): return all resources from listing requests (#3278) 2023-06-05 12:53:59 -04:00
Michael Gaffney 8159ddb08e feat(db): Add function to update billing snapshot table
This adds the `update_sessions_pending_daily_snapshot` SQL function
which updates the `sessions_pending_daily_snapshot` table by inserting
values for any days missing from the table.

This also adds a check constraint to the
`sessions_pending_daily_snapshot` table along with a `comment on table`.

This also removes the hcp daily billing views since they are no longer
needed.

Ref: ace2def49d
2023-06-05 12:48:15 -04:00
Michael Gaffney 41bdfb4406 fix(db): Fix time zone consistency issues in monthly billing views
The hcp monthly billing views build a range of buckets using the
`generate_series` and the `now()` functions along with relative offsets
like `+ 1 month`. The calculated start and end times for these views can
vary depending on the time zone setting of the PostgreSQL server.

This adds 3 table functions that call their respective views with the
time zone set to UTC. Calling these functions instead of their
underlying views directly prevents the returned values from varying when
the server's time zone is not set to UTC.

This also drops support for PostgreSQL 11. The included tests use the
`date_trunc(field, source [, time_zone ])` function added in PostgreSQL
12.

Fixes: 41b1b5b4b7
2023-06-05 12:48:15 -04:00
Michael Gaffney 47ddd2e40a fix(db): Fix generated series to yield consistent results
The hcp billing `_all` views built a range of buckets using the
`generate_series` function using the minimum value of the
`session_pending_time` column from the `wh_session_accumulating_fact`
table as the start time and `now()` as the end time. It then truncated
values in the series using the `date_trunc` function. This allowed the
generated series of buckets returned to vary and could result in one
additional bucket being included in the series depending on the current
time and the start time.

As an illustrative example, the `hourly_all` query used:

    select date_trunc('hour',time)
      from generate_series(
             (select min(session_pending_time) -- start time
                from wh_session_accumulating_fact),
              now(),
              '1 hour'::interval
           ) as time;

Substituting the start time with a hard coded value to show the issue:

    -- Show current time, where the minutes portion is 55
    select now();
                  now
    -------------------------------
     2023-05-22 14:55:40.567605+00
    (1 row)

    -- generate series with start time's minutes portion at 57
    select date_trunc('hour',time)
      from generate_series(
              '2023-05-22 01:57:00'::timestamptz,
              now(),
              '1 hour'::interval
           ) as time;

           date_trunc
    ------------------------
     2023-05-22 01:00:00+00
     2023-05-22 02:00:00+00
     2023-05-22 03:00:00+00
     2023-05-22 04:00:00+00
     2023-05-22 05:00:00+00
     2023-05-22 06:00:00+00
     2023-05-22 07:00:00+00
     2023-05-22 08:00:00+00
     2023-05-22 09:00:00+00
     2023-05-22 10:00:00+00
     2023-05-22 11:00:00+00
     2023-05-22 12:00:00+00
     2023-05-22 13:00:00+00
    (13 rows)

    -- Wait a few minutes
    select now();
                 now
    ------------------------------
     2023-05-22 14:58:48.75287+00
    (1 row)

    -- Now run again and get an extra result, even though still
    -- within the same hour
    select date_trunc('hour',time)
      from generate_series(
              '2023-05-22 01:57:00'::timestamptz,
              now(),
              '1 hour'::interval
           ) as time;

           date_trunc
    ------------------------
     2023-05-22 01:00:00+00
     2023-05-22 02:00:00+00
     2023-05-22 03:00:00+00
     2023-05-22 04:00:00+00
     2023-05-22 05:00:00+00
     2023-05-22 06:00:00+00
     2023-05-22 07:00:00+00
     2023-05-22 08:00:00+00
     2023-05-22 09:00:00+00
     2023-05-22 10:00:00+00
     2023-05-22 11:00:00+00
     2023-05-22 12:00:00+00
     2023-05-22 13:00:00+00
     2023-05-22 14:00:00+00
    (14 rows)

To fix this, we call the `generate_series` function truncating the start
time argument to the bucket size:

    -- Hourly
    select bucket
      from generate_series(
              date_trunc('hour', select min(session_pending_time)
                                   from wh_session_accumulating_fact)),
              now(),
              '1 hour'::interval
           ) as bucket;

    -- Monthly
    select bucket
      from generate_series(
              date_trunc('month', select min(session_pending_time)
                                    from wh_session_accumulating_fact)),
              now(),
              '1 month'::interval
           ) as bucket;

Fixes: 41b1b5b4b7
2023-06-05 12:48:15 -04:00
Jim 5029be9999 fix: allow responses larger than the default 4194304 recv msg size (#3276) 2023-06-05 12:13:05 -04:00
Michael Gaffney 053e74f66c feat(db): Add table for census upload job status 2023-06-05 11:32:26 -04:00
Michael Gaffney 8bf80e0544 test(db): Conditionally skip monthly billing view tests
Certain tests fail when run on the first day of the month because of
edge cases in the setup of test data. This adds conditional logic to
skip those tests when run on the first day of a month.
2023-06-04 09:31:40 -04:00
Dharini Jeeva 9f5e2020ba Chore UI bump (#3271)
* ui changes

* ui changes
2023-06-02 16:18:06 -07:00
Todd 2d102a61c5 HcpbWorkers no longer must be KMS workers for LookupHcpbWorkers (#3269) 2023-06-02 13:53:37 -07:00
Jeff Mitchell 1b0330ad8e Update dev worker auth flag names (#3265)
This brings it in line with the updated names that have been settled on
in light of deprecating the old KMS method.
2023-06-02 12:47:59 -04:00
Louis Ruch 281f217dcc feat(plugins): Refactor host plugins to boundary plugins (#3262) 2023-06-02 08:04:50 -07:00
Johan Brandhorst-Satzkorn 97977f1995 update perms table for session recordings and storage buckets (#3253) 2023-06-01 12:45:27 -07:00
Cameron Perera 5a64946f9d chore: bump ui commit (#3261) 2023-06-01 11:47:48 -05:00
Cameron Perera 1cd084459d chore: bump UI commit (#3259) 2023-06-01 09:35:17 -05:00
Johan Brandhorst-Satzkorn 0c8177590f Upgrade grpc-gateway dependency (#3257)
* proto: correct classification of authz token

The target authorization token had the invalid classification
"private". Fortunately, classification is a fail-closed system,
so this won't have exposed users authorization tokens, but
we should still use the correct classification. Use "secret".

* scripts: add Go script to remove gotags comments

The new version of grpc-gateway includes our gotags
comments in the generate swagger documentation. This
script removes all mentions of these.

* Upgrade grpc-gateway dependency

Mainly we need this to fix generation of our docs side API docs,
but it also includes a nice fix for the new Download RPC, i.e. it
now contains the correct response schema (a binary stream).
2023-06-01 06:41:09 -07:00
Jim d4e537c88d chore: updgrade pgx direct deps to v5 (#3258) 2023-06-01 08:59:38 -04:00
Jim 536551dc0c fix: update go-dbw dep and refactor conversion of pgx errors (#3242) 2023-05-31 20:23:33 -04:00
Jeff Mitchell 3d5bed9ce8 Don't allow managed workers to be deleted (#3254)
This also adds checks to ensure the tag cannot be added to workers via
the API.
2023-05-31 14:23:57 -04:00
Timothy Messier 61a37ef4a4 fix(schema): Add missing endpoint column to session recording view 2023-05-31 15:53:16 +00:00
Timothy Messier f64f03ed46 fix(targets): Support authorize session request with target name (#3252)
For requests to the target authorize session endpoint we support passing
a target name instead of an id. This means that `req.GetId()` might not
be the target's public id. Since the first thing authorize session does
includes retrieving the target as part of the authorization checks, this
subtype check can leverage the public id of the target instead of using
the request.

Fixes: 6178dd516e
2023-05-31 11:25:03 -04:00
Timothy Messier c2da88d2a5 test(cmd/config): Fix test compilation error
Refs: 9ae2bdfae
2023-05-31 12:47:20 +00:00
Timothy Messier cdf18b6369 test(cli/targets): Add test case for default client port 2023-05-31 12:18:24 +00:00
Todd fb1ea92a30 Pass both the control and data context into handle 2023-05-31 12:18:24 +00:00
irenarindos 8c96d3ef9b fix(cmd): add session recording resource prefixes 2023-05-31 12:18:24 +00:00
Johan Brandhorst-Satzkorn 3e07b2ffaf bsr: rename fields and remove project id from meta 2023-05-31 12:18:24 +00:00
Johan Brandhorst-Satzkorn 64764e29e5 bsr: invert credential, cred store relationship
This lifts the credential sources up to the top of
the SessionMeta struct, avoiding indirection through
the credential stores.
2023-05-31 12:18:24 +00:00
Johan Brandhorst-Satzkorn e0700570a2 bsr: add endpoint to session meta
The endpoint stores the address of the host
the egress worker proxies to.
2023-05-31 12:18:24 +00:00
Johan Brandhorst-Satzkorn 59f78ac1f8 config: allow wasm execution under UI CSP
The wasm-unsafe-eval option is necessary for the asciinema
player on the Admin UI
2023-05-31 12:18:24 +00:00
Danielle Miu b4137a14c3 update test.sh to use loopback flag 2023-05-31 12:18:24 +00:00
Damian Debkowski e7420eb690 fix(plugin): correct spelling mistake 2023-05-31 12:18:24 +00:00
Todd 6178dd516e Let a target subtype validate the authorize session's session state 2023-05-31 12:18:23 +00:00
Timothy Messier 9f2c83f3b0 refact(bsr): Rename const to denote when interpolation is needed 2023-05-31 12:18:23 +00:00
Jim 21e4827178 fix(Upstream Msg): limit types used in tests 2023-05-31 12:18:23 +00:00
Timothy Messier b88b4cce75 feat(bsr/ssh): Add file transfer direction to channel summary
When an SSH channel is used for a file transfer, the summary will report
the detected direction of the file transfer as either an upload or
download, relative to the end client.
2023-05-31 12:18:23 +00:00
Timothy Messier 78ea1a9f3a refact(bsr): Use JSON for session meta and summary data
The session metadata is provided all at once when a new bsr is opened.
While the session recording metadata records metadata about a recording
while the recording is happening, notably it records each time a new
connection occurs.

The nested structure of the session metadata does not lend itself to the
append-only syntax of the recording meta file. In addition we do not
want to mix different kinds of metadata together. Thus the session
metadata is now written to a separate file in the BSR, and is written as
JSON which better handles the nested structure and allows for simpler
encoding/decoding.

Similarly the summary files are intended to be written to as containers
close and have been switched to JSON.
2023-05-31 12:18:23 +00:00
Jim 7dc15f1f39 fix(Upstream Msg): limit types supported in toMsgType(...) 2023-05-31 12:18:23 +00:00
Louis Ruch 203d4bb048 fix(storage): Remove client 2023-05-31 12:18:23 +00:00
Danielle Miu 1052118836 remove field masks from proto 2023-05-31 12:18:23 +00:00
Louis Ruch f0e95d7267 docs(storage): Update comments 2023-05-31 12:18:23 +00:00
Timothy Messier f53d65eacd refact(sql): Rename migrations to avoid number conflicts 2023-05-31 12:18:23 +00:00