Reland "manage_dut:  initial check in."

This reverts commit fd7924070c66d7d2022635279103c8418b48fbd8.

Reason for revert: Revert of revert - this was not the cause of the build breakage

Original change's description:
> Revert "manage_dut:  initial check in."
>
> This reverts commit d29012f483256760fa56325b53592a9787a81b4f.
>
> Reason for revert: Suspected build break in chromite
>
> Original change's description:
> > manage_dut:  initial check in.
> >
> > DUT manager resource and service contract.
> >
> > BUG=None
> > TEST=None
> >
> > Change-Id: I5f7046b2fe49c83eb7eecf925b757dfae1d9c2cf
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/proto/+/2940578
> > Commit-Queue: Keith Haddow <haddowk@chromium.org>
> > Reviewed-by: C Shapiro <shapiroc@chromium.org>
>
> Bug: None
> Change-Id: Id7df5511ee1dee2837b9e9a20f93734a860ed9da
> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/proto/+/2973792
> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
> Commit-Queue: Keith Haddow <haddowk@chromium.org>
> Commit-Queue: George Engelbrecht <engeg@google.com>

Bug: None
Change-Id: I02c437f2fa163ac3d2c42f8868d27f5064774209
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/proto/+/2989630
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Keith Haddow <haddowk@chromium.org>
diff --git a/gen/golden_descriptors.json b/gen/golden_descriptors.json
index 53dffe2..0fb0cc3 100644
--- a/gen/golden_descriptors.json
+++ b/gen/golden_descriptors.json
@@ -14939,6 +14939,828 @@
     },
     {
       "dependency": [
+        "google/protobuf/timestamp.proto",
+        "chromiumos/test/api/dut_attribute.proto",
+        "chromiumos/storage_path.proto",
+        "chromiumos/config/api/mfg_config_id.proto"
+      ],
+      "messageType": [
+        {
+          "field": [
+            {
+              "jsonName": "state",
+              "label": "LABEL_OPTIONAL",
+              "name": "state",
+              "number": 1,
+              "type": "TYPE_ENUM",
+              "typeName": ".lab.ManagedDut.ManagedState"
+            },
+            {
+              "jsonName": "startTime",
+              "label": "LABEL_OPTIONAL",
+              "name": "start_time",
+              "number": 2,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".google.protobuf.Timestamp"
+            },
+            {
+              "jsonName": "endTime",
+              "label": "LABEL_OPTIONAL",
+              "name": "end_time",
+              "number": 3,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".google.protobuf.Timestamp"
+            },
+            {
+              "jsonName": "note",
+              "label": "LABEL_OPTIONAL",
+              "name": "note",
+              "number": 4,
+              "type": "TYPE_STRING"
+            },
+            {
+              "jsonName": "leaseOwner",
+              "label": "LABEL_OPTIONAL",
+              "name": "lease_owner",
+              "number": 5,
+              "type": "TYPE_STRING"
+            }
+          ],
+          "name": "HistoryRecord"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "reason",
+              "label": "LABEL_OPTIONAL",
+              "name": "reason",
+              "number": 1,
+              "type": "TYPE_STRING"
+            }
+          ],
+          "name": "Lock"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_STRING"
+            }
+          ],
+          "name": "Pool"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "ipAddress",
+              "label": "LABEL_OPTIONAL",
+              "name": "ip_address",
+              "number": 1,
+              "oneofIndex": 0,
+              "type": "TYPE_STRING"
+            },
+            {
+              "jsonName": "hostname",
+              "label": "LABEL_OPTIONAL",
+              "name": "hostname",
+              "number": 2,
+              "oneofIndex": 0,
+              "type": "TYPE_STRING"
+            }
+          ],
+          "name": "NetworkIdentifier",
+          "oneofDecl": [
+            {
+              "name": "identifier"
+            }
+          ]
+        },
+        {
+          "enumType": [
+            {
+              "name": "ManagedState",
+              "value": [
+                {
+                  "name": "UNKNOWN",
+                  "number": 0
+                },
+                {
+                  "name": "READY",
+                  "number": 1
+                },
+                {
+                  "name": "PROVISION",
+                  "number": 2
+                },
+                {
+                  "name": "VERIFY",
+                  "number": 3
+                },
+                {
+                  "name": "LEASED",
+                  "number": 4
+                },
+                {
+                  "name": "FAILED",
+                  "number": 5
+                },
+                {
+                  "name": "RESET",
+                  "number": 6
+                }
+              ]
+            }
+          ],
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.NetworkIdentifier"
+            },
+            {
+              "jsonName": "displayName",
+              "label": "LABEL_OPTIONAL",
+              "name": "display_name",
+              "number": 2,
+              "type": "TYPE_STRING"
+            },
+            {
+              "jsonName": "tag",
+              "label": "LABEL_OPTIONAL",
+              "name": "tag",
+              "number": 3,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.test.api.DutAttributeList"
+            },
+            {
+              "jsonName": "pool",
+              "label": "LABEL_REPEATED",
+              "name": "pool",
+              "number": 4,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.Pool"
+            },
+            {
+              "jsonName": "peripheral",
+              "label": "LABEL_OPTIONAL",
+              "name": "peripheral",
+              "number": 5,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.test.api.DutAttributeList"
+            },
+            {
+              "jsonName": "mfgConfigId",
+              "label": "LABEL_OPTIONAL",
+              "name": "mfg_config_id",
+              "number": 6,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.config.api.MfgConfigId"
+            },
+            {
+              "jsonName": "provisionedBuild",
+              "label": "LABEL_OPTIONAL",
+              "name": "provisioned_build",
+              "number": 7,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.StoragePath"
+            },
+            {
+              "jsonName": "state",
+              "label": "LABEL_OPTIONAL",
+              "name": "state",
+              "number": 8,
+              "type": "TYPE_ENUM",
+              "typeName": ".lab.ManagedDut.ManagedState"
+            },
+            {
+              "jsonName": "lock",
+              "label": "LABEL_OPTIONAL",
+              "name": "lock",
+              "number": 9,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.Lock"
+            },
+            {
+              "jsonName": "operatorNotes",
+              "label": "LABEL_OPTIONAL",
+              "name": "operator_notes",
+              "number": 10,
+              "type": "TYPE_STRING"
+            },
+            {
+              "jsonName": "provisionedFirmwareVersion",
+              "label": "LABEL_OPTIONAL",
+              "name": "provisioned_firmware_version",
+              "number": 11,
+              "type": "TYPE_STRING"
+            },
+            {
+              "jsonName": "history",
+              "label": "LABEL_REPEATED",
+              "name": "history",
+              "number": 12,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.HistoryRecord"
+            },
+            {
+              "jsonName": "associatedDut",
+              "label": "LABEL_REPEATED",
+              "name": "associated_dut",
+              "number": 13,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.NetworkIdentifier"
+            },
+            {
+              "jsonName": "isAssociatedDut",
+              "label": "LABEL_OPTIONAL",
+              "name": "is_associated_dut",
+              "number": 14,
+              "type": "TYPE_BOOL"
+            }
+          ],
+          "name": "ManagedDut"
+        }
+      ],
+      "name": "lab/managed_dut.proto",
+      "options": {
+        "goPackage": "go.chromium.org/chromiumos/infra/proto/go/lab"
+      },
+      "package": "lab",
+      "syntax": "proto3"
+    },
+    {
+      "dependency": [
+        "google/protobuf/timestamp.proto",
+        "google/protobuf/field_mask.proto",
+        "google/protobuf/empty.proto",
+        "chromiumos/test/api/dut_attribute.proto",
+        "chromiumos/storage_path.proto",
+        "chromiumos/longrunning/operations.proto",
+        "chromiumos/config/api/mfg_config_id.proto",
+        "lab/managed_dut.proto"
+      ],
+      "messageType": [
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.NetworkIdentifier"
+            },
+            {
+              "jsonName": "displayName",
+              "label": "LABEL_OPTIONAL",
+              "name": "display_name",
+              "number": 2,
+              "type": "TYPE_STRING"
+            }
+          ],
+          "name": "CreateManagedDutRequest"
+        },
+        {
+          "name": "CreateManagedDutResponse"
+        },
+        {
+          "name": "CreateMManagedDutMetadata"
+        },
+        {
+          "name": "CreateManagedDutMetadata"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.NetworkIdentifier"
+            }
+          ],
+          "name": "DeleteManagedDutRequest"
+        },
+        {
+          "name": "DeleteManagedDutResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "duts",
+              "label": "LABEL_REPEATED",
+              "name": "duts",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.ManagedDut"
+            }
+          ],
+          "name": "ListManagedDutsRequest"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "duts",
+              "label": "LABEL_REPEATED",
+              "name": "duts",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.ManagedDut"
+            }
+          ],
+          "name": "ListManagedDutsResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.NetworkIdentifier"
+            }
+          ],
+          "name": "GetManagedDutRequest"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "dut",
+              "label": "LABEL_OPTIONAL",
+              "name": "dut",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.ManagedDut"
+            }
+          ],
+          "name": "GetManagedDutResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "dut",
+              "label": "LABEL_OPTIONAL",
+              "name": "dut",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.ManagedDut"
+            },
+            {
+              "jsonName": "updateMask",
+              "label": "LABEL_OPTIONAL",
+              "name": "update_mask",
+              "number": 2,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".google.protobuf.FieldMask"
+            }
+          ],
+          "name": "UpdateManagedDutRequest"
+        },
+        {
+          "name": "UpdateManagedDutResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "model",
+              "label": "LABEL_OPTIONAL",
+              "name": "model",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.test.api.DutAttribute"
+            },
+            {
+              "jsonName": "leaseOwner",
+              "label": "LABEL_OPTIONAL",
+              "name": "lease_owner",
+              "number": 2,
+              "type": "TYPE_STRING"
+            },
+            {
+              "jsonName": "softwarePath",
+              "label": "LABEL_OPTIONAL",
+              "name": "software_path",
+              "number": 3,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.StoragePath"
+            },
+            {
+              "jsonName": "leaseLengthSecs",
+              "label": "LABEL_OPTIONAL",
+              "name": "lease_length_secs",
+              "number": 4,
+              "type": "TYPE_INT32"
+            },
+            {
+              "jsonName": "tag",
+              "label": "LABEL_OPTIONAL",
+              "name": "tag",
+              "number": 5,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.test.api.DutAttributeList"
+            },
+            {
+              "jsonName": "pool",
+              "label": "LABEL_OPTIONAL",
+              "name": "pool",
+              "number": 6,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.test.api.DutAttributeList"
+            },
+            {
+              "jsonName": "peripheral",
+              "label": "LABEL_OPTIONAL",
+              "name": "peripheral",
+              "number": 7,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.test.api.DutAttributeList"
+            },
+            {
+              "jsonName": "mfgConfigId",
+              "label": "LABEL_OPTIONAL",
+              "name": "mfg_config_id",
+              "number": 8,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.config.api.MfgConfigId"
+            },
+            {
+              "jsonName": "minDuts",
+              "label": "LABEL_OPTIONAL",
+              "name": "min_duts",
+              "number": 9,
+              "type": "TYPE_INT32"
+            },
+            {
+              "jsonName": "maxDuts",
+              "label": "LABEL_OPTIONAL",
+              "name": "max_duts",
+              "number": 10,
+              "type": "TYPE_INT32"
+            },
+            {
+              "jsonName": "numberAssociatedDuts",
+              "label": "LABEL_OPTIONAL",
+              "name": "number_associated_duts",
+              "number": 11,
+              "type": "TYPE_INT32"
+            }
+          ],
+          "name": "LeaseManagedDutRequest"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_REPEATED",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.NetworkIdentifier"
+            },
+            {
+              "jsonName": "expiryTimeSecs",
+              "label": "LABEL_OPTIONAL",
+              "name": "expiry_time_secs",
+              "number": 2,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".google.protobuf.Timestamp"
+            }
+          ],
+          "name": "LeaseManagedDutResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.NetworkIdentifier"
+            },
+            {
+              "jsonName": "force",
+              "label": "LABEL_OPTIONAL",
+              "name": "force",
+              "number": 2,
+              "type": "TYPE_BOOL"
+            },
+            {
+              "jsonName": "forceReason",
+              "label": "LABEL_OPTIONAL",
+              "name": "force_reason",
+              "number": 3,
+              "type": "TYPE_STRING"
+            }
+          ],
+          "name": "ReturnManagedDutLeaseRequest"
+        },
+        {
+          "name": "ReturnManagedDutLeaseResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.NetworkIdentifier"
+            },
+            {
+              "jsonName": "leaseLengthSecs",
+              "label": "LABEL_OPTIONAL",
+              "name": "lease_length_secs",
+              "number": 3,
+              "type": "TYPE_INT32"
+            }
+          ],
+          "name": "ExtendManagedDutLeaseRequest"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "expiryTimeSecs",
+              "label": "LABEL_OPTIONAL",
+              "name": "expiry_time_secs",
+              "number": 2,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".google.protobuf.Timestamp"
+            }
+          ],
+          "name": "ExtendManagedDutLeaseResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.NetworkIdentifier"
+            }
+          ],
+          "name": "VerifyManagedDutRequest"
+        },
+        {
+          "name": "VerifyManagedDutResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.NetworkIdentifier"
+            },
+            {
+              "jsonName": "buildPath",
+              "label": "LABEL_OPTIONAL",
+              "name": "build_path",
+              "number": 2,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.StoragePath"
+            }
+          ],
+          "name": "ProvisionManagedDutRequest"
+        },
+        {
+          "name": "ProvisionManagedDutResponse"
+        }
+      ],
+      "name": "lab/dut_manager.proto",
+      "options": {
+        "goPackage": "go.chromium.org/chromiumos/infra/proto/go/lab"
+      },
+      "package": "lab",
+      "service": [
+        {
+          "method": [
+            {
+              "inputType": ".lab.CreateManagedDutRequest",
+              "name": "CreateManagedDut",
+              "options": {
+                "[chromiumos.longrunning.operation_info]": {
+                  "metadataType": "CreateMManagedDutMetadata",
+                  "responseType": "CreateManagedDutResponse"
+                }
+              },
+              "outputType": ".chromiumos.longrunning.Operation"
+            },
+            {
+              "inputType": ".lab.DeleteManagedDutRequest",
+              "name": "DeleteManagedDut",
+              "outputType": ".lab.DeleteManagedDutResponse"
+            },
+            {
+              "inputType": ".lab.ListManagedDutsRequest",
+              "name": "ListManagedDuts",
+              "outputType": ".lab.ListManagedDutsResponse"
+            },
+            {
+              "inputType": ".lab.GetManagedDutRequest",
+              "name": "GetManagedDut",
+              "outputType": ".lab.GetManagedDutResponse"
+            },
+            {
+              "inputType": ".lab.UpdateManagedDutRequest",
+              "name": "UpdateManagedDut",
+              "outputType": ".lab.UpdateManagedDutResponse"
+            },
+            {
+              "inputType": ".lab.LeaseManagedDutRequest",
+              "name": "LeaseManagedDut",
+              "options": {
+                "[chromiumos.longrunning.operation_info]": {
+                  "metadataType": "LeaseManagedDutMetadata",
+                  "responseType": "LeaseManagedDutResponse"
+                }
+              },
+              "outputType": ".chromiumos.longrunning.Operation"
+            },
+            {
+              "inputType": ".lab.ReturnManagedDutLeaseRequest",
+              "name": "ReturnManagedDutLease",
+              "outputType": ".lab.ReturnManagedDutLeaseResponse"
+            },
+            {
+              "inputType": ".lab.ExtendManagedDutLeaseRequest",
+              "name": "ExtendManagedDutLease",
+              "outputType": ".lab.ExtendManagedDutLeaseResponse"
+            },
+            {
+              "inputType": ".lab.ProvisionManagedDutRequest",
+              "name": "ProvisionManagedDut",
+              "outputType": ".lab.ProvisionManagedDutResponse"
+            },
+            {
+              "inputType": ".lab.VerifyManagedDutRequest",
+              "name": "VerifyManagedDut",
+              "outputType": ".lab.VerifyManagedDutResponse"
+            }
+          ],
+          "name": "DutManagerService"
+        }
+      ],
+      "syntax": "proto3"
+    },
+    {
+      "dependency": [
+        "google/protobuf/empty.proto",
+        "google/protobuf/field_mask.proto",
+        "lab/managed_dut.proto"
+      ],
+      "messageType": [
+        {
+          "field": [
+            {
+              "jsonName": "dut",
+              "label": "LABEL_OPTIONAL",
+              "name": "dut",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.ManagedDut"
+            }
+          ],
+          "name": "CreateDutRequest"
+        },
+        {
+          "name": "CreateDutResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_STRING"
+            }
+          ],
+          "name": "DeleteDutRequest"
+        },
+        {
+          "name": "DeleteDutResponse"
+        },
+        {
+          "name": "ListDutRequest"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "duts",
+              "label": "LABEL_REPEATED",
+              "name": "duts",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.ManagedDut"
+            }
+          ],
+          "name": "ListDutResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "name",
+              "label": "LABEL_OPTIONAL",
+              "name": "name",
+              "number": 1,
+              "type": "TYPE_STRING"
+            }
+          ],
+          "name": "GetDutRequest"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "dut",
+              "label": "LABEL_OPTIONAL",
+              "name": "dut",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.ManagedDut"
+            }
+          ],
+          "name": "GetDutResponse"
+        },
+        {
+          "field": [
+            {
+              "jsonName": "dut",
+              "label": "LABEL_OPTIONAL",
+              "name": "dut",
+              "number": 1,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".lab.ManagedDut"
+            },
+            {
+              "jsonName": "updateMask",
+              "label": "LABEL_OPTIONAL",
+              "name": "update_mask",
+              "number": 2,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".google.protobuf.FieldMask"
+            }
+          ],
+          "name": "UpdateDutRequest"
+        },
+        {
+          "name": "UpdateDutResponse"
+        }
+      ],
+      "name": "lab/dut_manager_storage.proto",
+      "options": {
+        "goPackage": "go.chromium.org/chromiumos/infra/proto/go/lab"
+      },
+      "package": "lab",
+      "service": [
+        {
+          "method": [
+            {
+              "inputType": ".lab.CreateDutRequest",
+              "name": "CreateDut",
+              "outputType": ".lab.CreateDutResponse"
+            },
+            {
+              "inputType": ".lab.DeleteDutRequest",
+              "name": "DeleteDut",
+              "outputType": ".lab.DeleteDutResponse"
+            },
+            {
+              "inputType": ".lab.ListDutRequest",
+              "name": "ListDut",
+              "outputType": ".lab.ListDutResponse"
+            },
+            {
+              "inputType": ".lab.GetDutRequest",
+              "name": "GetDut",
+              "outputType": ".lab.GetDutResponse"
+            },
+            {
+              "inputType": ".lab.UpdateDutRequest",
+              "name": "UpdateDut",
+              "outputType": ".lab.UpdateDutResponse"
+            }
+          ],
+          "name": "DutManagerStorageService"
+        }
+      ],
+      "syntax": "proto3"
+    },
+    {
+      "dependency": [
         "lab/chromeos_device_id.proto"
       ],
       "enumType": [
diff --git a/go/lab/dut_manager.pb.go b/go/lab/dut_manager.pb.go
new file mode 100644
index 0000000..a88ace3
--- /dev/null
+++ b/go/lab/dut_manager.pb.go
@@ -0,0 +1,1737 @@
+// Copyright 2021 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0-devel
+// 	protoc        v3.17.1
+// source: lab/dut_manager.proto
+
+package lab
+
+import (
+	_go "go.chromium.org/chromiumos/config/go"
+	api1 "go.chromium.org/chromiumos/config/go/api"
+	longrunning "go.chromium.org/chromiumos/config/go/longrunning"
+	api "go.chromium.org/chromiumos/config/go/test/api"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	_ "google.golang.org/protobuf/types/known/emptypb"
+	fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
+	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type CreateManagedDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name        *NetworkIdentifier `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	DisplayName string             `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
+}
+
+func (x *CreateManagedDutRequest) Reset() {
+	*x = CreateManagedDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateManagedDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateManagedDutRequest) ProtoMessage() {}
+
+func (x *CreateManagedDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateManagedDutRequest.ProtoReflect.Descriptor instead.
+func (*CreateManagedDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *CreateManagedDutRequest) GetName() *NetworkIdentifier {
+	if x != nil {
+		return x.Name
+	}
+	return nil
+}
+
+func (x *CreateManagedDutRequest) GetDisplayName() string {
+	if x != nil {
+		return x.DisplayName
+	}
+	return ""
+}
+
+type CreateManagedDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *CreateManagedDutResponse) Reset() {
+	*x = CreateManagedDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateManagedDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateManagedDutResponse) ProtoMessage() {}
+
+func (x *CreateManagedDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateManagedDutResponse.ProtoReflect.Descriptor instead.
+func (*CreateManagedDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{1}
+}
+
+type CreateMManagedDutMetadata struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *CreateMManagedDutMetadata) Reset() {
+	*x = CreateMManagedDutMetadata{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateMManagedDutMetadata) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateMManagedDutMetadata) ProtoMessage() {}
+
+func (x *CreateMManagedDutMetadata) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateMManagedDutMetadata.ProtoReflect.Descriptor instead.
+func (*CreateMManagedDutMetadata) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{2}
+}
+
+type CreateManagedDutMetadata struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *CreateManagedDutMetadata) Reset() {
+	*x = CreateManagedDutMetadata{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateManagedDutMetadata) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateManagedDutMetadata) ProtoMessage() {}
+
+func (x *CreateManagedDutMetadata) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateManagedDutMetadata.ProtoReflect.Descriptor instead.
+func (*CreateManagedDutMetadata) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{3}
+}
+
+type DeleteManagedDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name *NetworkIdentifier `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *DeleteManagedDutRequest) Reset() {
+	*x = DeleteManagedDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteManagedDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteManagedDutRequest) ProtoMessage() {}
+
+func (x *DeleteManagedDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteManagedDutRequest.ProtoReflect.Descriptor instead.
+func (*DeleteManagedDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *DeleteManagedDutRequest) GetName() *NetworkIdentifier {
+	if x != nil {
+		return x.Name
+	}
+	return nil
+}
+
+type DeleteManagedDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *DeleteManagedDutResponse) Reset() {
+	*x = DeleteManagedDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteManagedDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteManagedDutResponse) ProtoMessage() {}
+
+func (x *DeleteManagedDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteManagedDutResponse.ProtoReflect.Descriptor instead.
+func (*DeleteManagedDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{5}
+}
+
+type ListManagedDutsRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Duts []*ManagedDut `protobuf:"bytes,1,rep,name=duts,proto3" json:"duts,omitempty"`
+}
+
+func (x *ListManagedDutsRequest) Reset() {
+	*x = ListManagedDutsRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListManagedDutsRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListManagedDutsRequest) ProtoMessage() {}
+
+func (x *ListManagedDutsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListManagedDutsRequest.ProtoReflect.Descriptor instead.
+func (*ListManagedDutsRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *ListManagedDutsRequest) GetDuts() []*ManagedDut {
+	if x != nil {
+		return x.Duts
+	}
+	return nil
+}
+
+type ListManagedDutsResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Duts []*ManagedDut `protobuf:"bytes,1,rep,name=duts,proto3" json:"duts,omitempty"`
+}
+
+func (x *ListManagedDutsResponse) Reset() {
+	*x = ListManagedDutsResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListManagedDutsResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListManagedDutsResponse) ProtoMessage() {}
+
+func (x *ListManagedDutsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListManagedDutsResponse.ProtoReflect.Descriptor instead.
+func (*ListManagedDutsResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *ListManagedDutsResponse) GetDuts() []*ManagedDut {
+	if x != nil {
+		return x.Duts
+	}
+	return nil
+}
+
+type GetManagedDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name *NetworkIdentifier `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *GetManagedDutRequest) Reset() {
+	*x = GetManagedDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetManagedDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetManagedDutRequest) ProtoMessage() {}
+
+func (x *GetManagedDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetManagedDutRequest.ProtoReflect.Descriptor instead.
+func (*GetManagedDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *GetManagedDutRequest) GetName() *NetworkIdentifier {
+	if x != nil {
+		return x.Name
+	}
+	return nil
+}
+
+type GetManagedDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Dut *ManagedDut `protobuf:"bytes,1,opt,name=dut,proto3" json:"dut,omitempty"`
+}
+
+func (x *GetManagedDutResponse) Reset() {
+	*x = GetManagedDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetManagedDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetManagedDutResponse) ProtoMessage() {}
+
+func (x *GetManagedDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetManagedDutResponse.ProtoReflect.Descriptor instead.
+func (*GetManagedDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *GetManagedDutResponse) GetDut() *ManagedDut {
+	if x != nil {
+		return x.Dut
+	}
+	return nil
+}
+
+type UpdateManagedDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Dut        *ManagedDut            `protobuf:"bytes,1,opt,name=dut,proto3" json:"dut,omitempty"`
+	UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
+}
+
+func (x *UpdateManagedDutRequest) Reset() {
+	*x = UpdateManagedDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UpdateManagedDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateManagedDutRequest) ProtoMessage() {}
+
+func (x *UpdateManagedDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateManagedDutRequest.ProtoReflect.Descriptor instead.
+func (*UpdateManagedDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *UpdateManagedDutRequest) GetDut() *ManagedDut {
+	if x != nil {
+		return x.Dut
+	}
+	return nil
+}
+
+func (x *UpdateManagedDutRequest) GetUpdateMask() *fieldmaskpb.FieldMask {
+	if x != nil {
+		return x.UpdateMask
+	}
+	return nil
+}
+
+type UpdateManagedDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *UpdateManagedDutResponse) Reset() {
+	*x = UpdateManagedDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UpdateManagedDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateManagedDutResponse) ProtoMessage() {}
+
+func (x *UpdateManagedDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateManagedDutResponse.ProtoReflect.Descriptor instead.
+func (*UpdateManagedDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{11}
+}
+
+type LeaseManagedDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Model                *api.DutAttribute     `protobuf:"bytes,1,opt,name=model,proto3" json:"model,omitempty"`
+	LeaseOwner           string                `protobuf:"bytes,2,opt,name=lease_owner,json=leaseOwner,proto3" json:"lease_owner,omitempty"`                   // The task id / test id of the lease holder
+	SoftwarePath         *_go.StoragePath      `protobuf:"bytes,3,opt,name=software_path,json=softwarePath,proto3" json:"software_path,omitempty"`             // provision_service.proto
+	LeaseLengthSecs      int32                 `protobuf:"varint,4,opt,name=lease_length_secs,json=leaseLengthSecs,proto3" json:"lease_length_secs,omitempty"` // requested time in second
+	Tag                  *api.DutAttributeList `protobuf:"bytes,5,opt,name=tag,proto3" json:"tag,omitempty"`
+	Pool                 *api.DutAttributeList `protobuf:"bytes,6,opt,name=pool,proto3" json:"pool,omitempty"`
+	Peripheral           *api.DutAttributeList `protobuf:"bytes,7,opt,name=peripheral,proto3" json:"peripheral,omitempty"`
+	MfgConfigId          *api1.MfgConfigId     `protobuf:"bytes,8,opt,name=mfg_config_id,json=mfgConfigId,proto3" json:"mfg_config_id,omitempty"`
+	MinDuts              int32                 `protobuf:"varint,9,opt,name=min_duts,json=minDuts,proto3" json:"min_duts,omitempty"`                                           // Minimum number of Duts requested, for multi dut
+	MaxDuts              int32                 `protobuf:"varint,10,opt,name=max_duts,json=maxDuts,proto3" json:"max_duts,omitempty"`                                          // Maximum number of Duts requested, for multi dut
+	NumberAssociatedDuts int32                 `protobuf:"varint,11,opt,name=number_associated_duts,json=numberAssociatedDuts,proto3" json:"number_associated_duts,omitempty"` // Get a lease on a Dut that is associated with another DUT and not generally available for lease.
+}
+
+func (x *LeaseManagedDutRequest) Reset() {
+	*x = LeaseManagedDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LeaseManagedDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LeaseManagedDutRequest) ProtoMessage() {}
+
+func (x *LeaseManagedDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LeaseManagedDutRequest.ProtoReflect.Descriptor instead.
+func (*LeaseManagedDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *LeaseManagedDutRequest) GetModel() *api.DutAttribute {
+	if x != nil {
+		return x.Model
+	}
+	return nil
+}
+
+func (x *LeaseManagedDutRequest) GetLeaseOwner() string {
+	if x != nil {
+		return x.LeaseOwner
+	}
+	return ""
+}
+
+func (x *LeaseManagedDutRequest) GetSoftwarePath() *_go.StoragePath {
+	if x != nil {
+		return x.SoftwarePath
+	}
+	return nil
+}
+
+func (x *LeaseManagedDutRequest) GetLeaseLengthSecs() int32 {
+	if x != nil {
+		return x.LeaseLengthSecs
+	}
+	return 0
+}
+
+func (x *LeaseManagedDutRequest) GetTag() *api.DutAttributeList {
+	if x != nil {
+		return x.Tag
+	}
+	return nil
+}
+
+func (x *LeaseManagedDutRequest) GetPool() *api.DutAttributeList {
+	if x != nil {
+		return x.Pool
+	}
+	return nil
+}
+
+func (x *LeaseManagedDutRequest) GetPeripheral() *api.DutAttributeList {
+	if x != nil {
+		return x.Peripheral
+	}
+	return nil
+}
+
+func (x *LeaseManagedDutRequest) GetMfgConfigId() *api1.MfgConfigId {
+	if x != nil {
+		return x.MfgConfigId
+	}
+	return nil
+}
+
+func (x *LeaseManagedDutRequest) GetMinDuts() int32 {
+	if x != nil {
+		return x.MinDuts
+	}
+	return 0
+}
+
+func (x *LeaseManagedDutRequest) GetMaxDuts() int32 {
+	if x != nil {
+		return x.MaxDuts
+	}
+	return 0
+}
+
+func (x *LeaseManagedDutRequest) GetNumberAssociatedDuts() int32 {
+	if x != nil {
+		return x.NumberAssociatedDuts
+	}
+	return 0
+}
+
+type LeaseManagedDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name           []*NetworkIdentifier   `protobuf:"bytes,1,rep,name=name,proto3" json:"name,omitempty"`
+	ExpiryTimeSecs *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=expiry_time_secs,json=expiryTimeSecs,proto3" json:"expiry_time_secs,omitempty"`
+}
+
+func (x *LeaseManagedDutResponse) Reset() {
+	*x = LeaseManagedDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LeaseManagedDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LeaseManagedDutResponse) ProtoMessage() {}
+
+func (x *LeaseManagedDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LeaseManagedDutResponse.ProtoReflect.Descriptor instead.
+func (*LeaseManagedDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *LeaseManagedDutResponse) GetName() []*NetworkIdentifier {
+	if x != nil {
+		return x.Name
+	}
+	return nil
+}
+
+func (x *LeaseManagedDutResponse) GetExpiryTimeSecs() *timestamppb.Timestamp {
+	if x != nil {
+		return x.ExpiryTimeSecs
+	}
+	return nil
+}
+
+type ReturnManagedDutLeaseRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name        *NetworkIdentifier `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Force       bool               `protobuf:"varint,2,opt,name=force,proto3" json:"force,omitempty"`                               // someone other than the leaseholder is expiring the lease.
+	ForceReason string             `protobuf:"bytes,3,opt,name=force_reason,json=forceReason,proto3" json:"force_reason,omitempty"` // why a forced lease return not by the owner was necessary.
+}
+
+func (x *ReturnManagedDutLeaseRequest) Reset() {
+	*x = ReturnManagedDutLeaseRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ReturnManagedDutLeaseRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ReturnManagedDutLeaseRequest) ProtoMessage() {}
+
+func (x *ReturnManagedDutLeaseRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ReturnManagedDutLeaseRequest.ProtoReflect.Descriptor instead.
+func (*ReturnManagedDutLeaseRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *ReturnManagedDutLeaseRequest) GetName() *NetworkIdentifier {
+	if x != nil {
+		return x.Name
+	}
+	return nil
+}
+
+func (x *ReturnManagedDutLeaseRequest) GetForce() bool {
+	if x != nil {
+		return x.Force
+	}
+	return false
+}
+
+func (x *ReturnManagedDutLeaseRequest) GetForceReason() string {
+	if x != nil {
+		return x.ForceReason
+	}
+	return ""
+}
+
+type ReturnManagedDutLeaseResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *ReturnManagedDutLeaseResponse) Reset() {
+	*x = ReturnManagedDutLeaseResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ReturnManagedDutLeaseResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ReturnManagedDutLeaseResponse) ProtoMessage() {}
+
+func (x *ReturnManagedDutLeaseResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ReturnManagedDutLeaseResponse.ProtoReflect.Descriptor instead.
+func (*ReturnManagedDutLeaseResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{15}
+}
+
+type ExtendManagedDutLeaseRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name            *NetworkIdentifier `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	LeaseLengthSecs int32              `protobuf:"varint,3,opt,name=lease_length_secs,json=leaseLengthSecs,proto3" json:"lease_length_secs,omitempty"`
+}
+
+func (x *ExtendManagedDutLeaseRequest) Reset() {
+	*x = ExtendManagedDutLeaseRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[16]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ExtendManagedDutLeaseRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ExtendManagedDutLeaseRequest) ProtoMessage() {}
+
+func (x *ExtendManagedDutLeaseRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[16]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ExtendManagedDutLeaseRequest.ProtoReflect.Descriptor instead.
+func (*ExtendManagedDutLeaseRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{16}
+}
+
+func (x *ExtendManagedDutLeaseRequest) GetName() *NetworkIdentifier {
+	if x != nil {
+		return x.Name
+	}
+	return nil
+}
+
+func (x *ExtendManagedDutLeaseRequest) GetLeaseLengthSecs() int32 {
+	if x != nil {
+		return x.LeaseLengthSecs
+	}
+	return 0
+}
+
+type ExtendManagedDutLeaseResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ExpiryTimeSecs *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=expiry_time_secs,json=expiryTimeSecs,proto3" json:"expiry_time_secs,omitempty"`
+}
+
+func (x *ExtendManagedDutLeaseResponse) Reset() {
+	*x = ExtendManagedDutLeaseResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[17]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ExtendManagedDutLeaseResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ExtendManagedDutLeaseResponse) ProtoMessage() {}
+
+func (x *ExtendManagedDutLeaseResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[17]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ExtendManagedDutLeaseResponse.ProtoReflect.Descriptor instead.
+func (*ExtendManagedDutLeaseResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{17}
+}
+
+func (x *ExtendManagedDutLeaseResponse) GetExpiryTimeSecs() *timestamppb.Timestamp {
+	if x != nil {
+		return x.ExpiryTimeSecs
+	}
+	return nil
+}
+
+type VerifyManagedDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name *NetworkIdentifier `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *VerifyManagedDutRequest) Reset() {
+	*x = VerifyManagedDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[18]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *VerifyManagedDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*VerifyManagedDutRequest) ProtoMessage() {}
+
+func (x *VerifyManagedDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[18]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use VerifyManagedDutRequest.ProtoReflect.Descriptor instead.
+func (*VerifyManagedDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{18}
+}
+
+func (x *VerifyManagedDutRequest) GetName() *NetworkIdentifier {
+	if x != nil {
+		return x.Name
+	}
+	return nil
+}
+
+type VerifyManagedDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *VerifyManagedDutResponse) Reset() {
+	*x = VerifyManagedDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[19]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *VerifyManagedDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*VerifyManagedDutResponse) ProtoMessage() {}
+
+func (x *VerifyManagedDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[19]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use VerifyManagedDutResponse.ProtoReflect.Descriptor instead.
+func (*VerifyManagedDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{19}
+}
+
+type ProvisionManagedDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name      *NetworkIdentifier `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	BuildPath *_go.StoragePath   `protobuf:"bytes,2,opt,name=build_path,json=buildPath,proto3" json:"build_path,omitempty"`
+}
+
+func (x *ProvisionManagedDutRequest) Reset() {
+	*x = ProvisionManagedDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[20]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ProvisionManagedDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ProvisionManagedDutRequest) ProtoMessage() {}
+
+func (x *ProvisionManagedDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[20]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ProvisionManagedDutRequest.ProtoReflect.Descriptor instead.
+func (*ProvisionManagedDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{20}
+}
+
+func (x *ProvisionManagedDutRequest) GetName() *NetworkIdentifier {
+	if x != nil {
+		return x.Name
+	}
+	return nil
+}
+
+func (x *ProvisionManagedDutRequest) GetBuildPath() *_go.StoragePath {
+	if x != nil {
+		return x.BuildPath
+	}
+	return nil
+}
+
+type ProvisionManagedDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *ProvisionManagedDutResponse) Reset() {
+	*x = ProvisionManagedDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_proto_msgTypes[21]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ProvisionManagedDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ProvisionManagedDutResponse) ProtoMessage() {}
+
+func (x *ProvisionManagedDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_proto_msgTypes[21]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ProvisionManagedDutResponse.ProtoReflect.Descriptor instead.
+func (*ProvisionManagedDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_proto_rawDescGZIP(), []int{21}
+}
+
+var File_lab_dut_manager_proto protoreflect.FileDescriptor
+
+var file_lab_dut_manager_proto_rawDesc = []byte{
+	0x0a, 0x15, 0x6c, 0x61, 0x62, 0x2f, 0x64, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+	0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x6c, 0x61, 0x62, 0x1a, 0x1f, 0x67, 0x6f,
+	0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69,
+	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66,
+	0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
+	0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x63, 0x68,
+	0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x61, 0x70,
+	0x69, 0x2f, 0x64, 0x75, 0x74, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f,
+	0x73, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73,
+	0x2f, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2f, 0x6f, 0x70, 0x65,
+	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x63,
+	0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x66, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
+	0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x6c, 0x61, 0x62, 0x2f, 0x6d, 0x61,
+	0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, 0x64, 0x75, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
+	0x68, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64,
+	0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4e,
+	0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61,
+	0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69,
+	0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x43, 0x72, 0x65,
+	0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d,
+	0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
+	0x74, 0x61, 0x22, 0x1a, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61,
+	0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x45,
+	0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44,
+	0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4e, 0x65,
+	0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d,
+	0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x22, 0x3d, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64,
+	0x44, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x04, 0x64,
+	0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x61, 0x62, 0x2e,
+	0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x04, 0x64, 0x75, 0x74, 0x73,
+	0x22, 0x3e, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44,
+	0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x64,
+	0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x61, 0x62, 0x2e,
+	0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x04, 0x64, 0x75, 0x74, 0x73,
+	0x22, 0x42, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75,
+	0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4e, 0x65, 0x74,
+	0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x04,
+	0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67,
+	0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a,
+	0x03, 0x64, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x61, 0x62,
+	0x2e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x03, 0x64, 0x75, 0x74,
+	0x22, 0x79, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+	0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x03, 0x64,
+	0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4d,
+	0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x03, 0x64, 0x75, 0x74, 0x12, 0x3b,
+	0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52,
+	0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x1a, 0x0a, 0x18, 0x55,
+	0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xcb, 0x04, 0x0a, 0x16, 0x4c, 0x65, 0x61, 0x73,
+	0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x37, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x21, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x74,
+	0x65, 0x73, 0x74, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69,
+	0x62, 0x75, 0x74, 0x65, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x6c,
+	0x65, 0x61, 0x73, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0a, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x0d,
+	0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73,
+	0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x0c, 0x73, 0x6f,
+	0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x65,
+	0x61, 0x73, 0x65, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, 0x73, 0x65, 0x63, 0x73, 0x18,
+	0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4c, 0x65, 0x6e, 0x67,
+	0x74, 0x68, 0x53, 0x65, 0x63, 0x73, 0x12, 0x37, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73,
+	0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x74, 0x41, 0x74, 0x74,
+	0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12,
+	0x39, 0x0a, 0x04, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e,
+	0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e,
+	0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+	0x4c, 0x69, 0x73, 0x74, 0x52, 0x04, 0x70, 0x6f, 0x6f, 0x6c, 0x12, 0x45, 0x0a, 0x0a, 0x70, 0x65,
+	0x72, 0x69, 0x70, 0x68, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25,
+	0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74,
+	0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+	0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x69, 0x70, 0x68, 0x65, 0x72, 0x61,
+	0x6c, 0x12, 0x46, 0x0a, 0x0d, 0x6d, 0x66, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
+	0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d,
+	0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x61, 0x70, 0x69,
+	0x2e, 0x4d, 0x66, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x52, 0x0b, 0x6d, 0x66,
+	0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x69, 0x6e,
+	0x5f, 0x64, 0x75, 0x74, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x69, 0x6e,
+	0x44, 0x75, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x75, 0x74, 0x73,
+	0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x44, 0x75, 0x74, 0x73, 0x12,
+	0x34, 0x0a, 0x16, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69,
+	0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x75, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x14, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65,
+	0x64, 0x44, 0x75, 0x74, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x17, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x4d,
+	0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x2a, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65,
+	0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x44, 0x0a,
+	0x10, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x63,
+	0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x53,
+	0x65, 0x63, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x4d, 0x61,
+	0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+	0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52,
+	0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f,
+	0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x6f,
+	0x72, 0x63, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x1f, 0x0a, 0x1d, 0x52, 0x65, 0x74,
+	0x75, 0x72, 0x6e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4c, 0x65, 0x61,
+	0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x76, 0x0a, 0x1c, 0x45, 0x78,
+	0x74, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4c, 0x65,
+	0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4e,
+	0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
+	0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, 0x73, 0x65, 0x63, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x0f, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x53, 0x65,
+	0x63, 0x73, 0x22, 0x65, 0x0a, 0x1d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, 0x61,
+	0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x10, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x74, 0x69,
+	0x6d, 0x65, 0x5f, 0x73, 0x65, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+	0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x69, 0x72,
+	0x79, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x63, 0x73, 0x22, 0x45, 0x0a, 0x17, 0x56, 0x65, 0x72,
+	0x69, 0x66, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+	0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x22, 0x1a, 0x0a, 0x18, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+	0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x80, 0x01, 0x0a,
+	0x1a, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+	0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e,
+	0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65,
+	0x72, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64,
+	0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x68,
+	0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
+	0x50, 0x61, 0x74, 0x68, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x74, 0x68, 0x22,
+	0x1d, 0x0a, 0x1b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x61,
+	0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xd1,
+	0x07, 0x0a, 0x11, 0x44, 0x75, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d,
+	0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x12, 0x1c, 0x2e, 0x6c, 0x61, 0x62, 0x2e,
+	0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69,
+	0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67,
+	0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x38, 0xd2, 0x41, 0x35, 0x0a,
+	0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x4d, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4d, 0x65, 0x74, 0x61,
+	0x64, 0x61, 0x74, 0x61, 0x12, 0x4f, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61,
+	0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x12, 0x1c, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x44,
+	0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x44, 0x65, 0x6c,
+	0x65, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e,
+	0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4c,
+	0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74,
+	0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+	0x64, 0x44, 0x75, 0x74, 0x12, 0x19, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61,
+	0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x1a, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64,
+	0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x10, 0x55,
+	0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x12,
+	0x1c, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61,
+	0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e,
+	0x6c, 0x61, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+	0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a,
+	0x0f, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74,
+	0x12, 0x1b, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x4d, 0x61, 0x6e, 0x61,
+	0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e,
+	0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72,
+	0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x22, 0x35, 0xd2, 0x41, 0x32, 0x0a, 0x17, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x4d, 0x61, 0x6e, 0x61,
+	0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17,
+	0x4c, 0x65, 0x61, 0x73, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4d,
+	0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x5e, 0x0a, 0x15, 0x52, 0x65, 0x74, 0x75, 0x72,
+	0x6e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65,
+	0x12, 0x21, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x4d, 0x61, 0x6e,
+	0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e,
+	0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x15, 0x45, 0x78, 0x74, 0x65, 0x6e,
+	0x64, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65,
+	0x12, 0x21, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e,
+	0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64,
+	0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x76, 0x69,
+	0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x12, 0x1f,
+	0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x61,
+	0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x20, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d,
+	0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x4f, 0x0a, 0x10, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67,
+	0x65, 0x64, 0x44, 0x75, 0x74, 0x12, 0x1c, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x56, 0x65, 0x72, 0x69,
+	0x66, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79,
+	0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x6f, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75,
+	0x6d, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73,
+	0x2f, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f,
+	0x6c, 0x61, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_lab_dut_manager_proto_rawDescOnce sync.Once
+	file_lab_dut_manager_proto_rawDescData = file_lab_dut_manager_proto_rawDesc
+)
+
+func file_lab_dut_manager_proto_rawDescGZIP() []byte {
+	file_lab_dut_manager_proto_rawDescOnce.Do(func() {
+		file_lab_dut_manager_proto_rawDescData = protoimpl.X.CompressGZIP(file_lab_dut_manager_proto_rawDescData)
+	})
+	return file_lab_dut_manager_proto_rawDescData
+}
+
+var file_lab_dut_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 22)
+var file_lab_dut_manager_proto_goTypes = []interface{}{
+	(*CreateManagedDutRequest)(nil),       // 0: lab.CreateManagedDutRequest
+	(*CreateManagedDutResponse)(nil),      // 1: lab.CreateManagedDutResponse
+	(*CreateMManagedDutMetadata)(nil),     // 2: lab.CreateMManagedDutMetadata
+	(*CreateManagedDutMetadata)(nil),      // 3: lab.CreateManagedDutMetadata
+	(*DeleteManagedDutRequest)(nil),       // 4: lab.DeleteManagedDutRequest
+	(*DeleteManagedDutResponse)(nil),      // 5: lab.DeleteManagedDutResponse
+	(*ListManagedDutsRequest)(nil),        // 6: lab.ListManagedDutsRequest
+	(*ListManagedDutsResponse)(nil),       // 7: lab.ListManagedDutsResponse
+	(*GetManagedDutRequest)(nil),          // 8: lab.GetManagedDutRequest
+	(*GetManagedDutResponse)(nil),         // 9: lab.GetManagedDutResponse
+	(*UpdateManagedDutRequest)(nil),       // 10: lab.UpdateManagedDutRequest
+	(*UpdateManagedDutResponse)(nil),      // 11: lab.UpdateManagedDutResponse
+	(*LeaseManagedDutRequest)(nil),        // 12: lab.LeaseManagedDutRequest
+	(*LeaseManagedDutResponse)(nil),       // 13: lab.LeaseManagedDutResponse
+	(*ReturnManagedDutLeaseRequest)(nil),  // 14: lab.ReturnManagedDutLeaseRequest
+	(*ReturnManagedDutLeaseResponse)(nil), // 15: lab.ReturnManagedDutLeaseResponse
+	(*ExtendManagedDutLeaseRequest)(nil),  // 16: lab.ExtendManagedDutLeaseRequest
+	(*ExtendManagedDutLeaseResponse)(nil), // 17: lab.ExtendManagedDutLeaseResponse
+	(*VerifyManagedDutRequest)(nil),       // 18: lab.VerifyManagedDutRequest
+	(*VerifyManagedDutResponse)(nil),      // 19: lab.VerifyManagedDutResponse
+	(*ProvisionManagedDutRequest)(nil),    // 20: lab.ProvisionManagedDutRequest
+	(*ProvisionManagedDutResponse)(nil),   // 21: lab.ProvisionManagedDutResponse
+	(*NetworkIdentifier)(nil),             // 22: lab.NetworkIdentifier
+	(*ManagedDut)(nil),                    // 23: lab.ManagedDut
+	(*fieldmaskpb.FieldMask)(nil),         // 24: google.protobuf.FieldMask
+	(*api.DutAttribute)(nil),              // 25: chromiumos.test.api.DutAttribute
+	(*_go.StoragePath)(nil),               // 26: chromiumos.StoragePath
+	(*api.DutAttributeList)(nil),          // 27: chromiumos.test.api.DutAttributeList
+	(*api1.MfgConfigId)(nil),              // 28: chromiumos.config.api.MfgConfigId
+	(*timestamppb.Timestamp)(nil),         // 29: google.protobuf.Timestamp
+	(*longrunning.Operation)(nil),         // 30: chromiumos.longrunning.Operation
+}
+var file_lab_dut_manager_proto_depIdxs = []int32{
+	22, // 0: lab.CreateManagedDutRequest.name:type_name -> lab.NetworkIdentifier
+	22, // 1: lab.DeleteManagedDutRequest.name:type_name -> lab.NetworkIdentifier
+	23, // 2: lab.ListManagedDutsRequest.duts:type_name -> lab.ManagedDut
+	23, // 3: lab.ListManagedDutsResponse.duts:type_name -> lab.ManagedDut
+	22, // 4: lab.GetManagedDutRequest.name:type_name -> lab.NetworkIdentifier
+	23, // 5: lab.GetManagedDutResponse.dut:type_name -> lab.ManagedDut
+	23, // 6: lab.UpdateManagedDutRequest.dut:type_name -> lab.ManagedDut
+	24, // 7: lab.UpdateManagedDutRequest.update_mask:type_name -> google.protobuf.FieldMask
+	25, // 8: lab.LeaseManagedDutRequest.model:type_name -> chromiumos.test.api.DutAttribute
+	26, // 9: lab.LeaseManagedDutRequest.software_path:type_name -> chromiumos.StoragePath
+	27, // 10: lab.LeaseManagedDutRequest.tag:type_name -> chromiumos.test.api.DutAttributeList
+	27, // 11: lab.LeaseManagedDutRequest.pool:type_name -> chromiumos.test.api.DutAttributeList
+	27, // 12: lab.LeaseManagedDutRequest.peripheral:type_name -> chromiumos.test.api.DutAttributeList
+	28, // 13: lab.LeaseManagedDutRequest.mfg_config_id:type_name -> chromiumos.config.api.MfgConfigId
+	22, // 14: lab.LeaseManagedDutResponse.name:type_name -> lab.NetworkIdentifier
+	29, // 15: lab.LeaseManagedDutResponse.expiry_time_secs:type_name -> google.protobuf.Timestamp
+	22, // 16: lab.ReturnManagedDutLeaseRequest.name:type_name -> lab.NetworkIdentifier
+	22, // 17: lab.ExtendManagedDutLeaseRequest.name:type_name -> lab.NetworkIdentifier
+	29, // 18: lab.ExtendManagedDutLeaseResponse.expiry_time_secs:type_name -> google.protobuf.Timestamp
+	22, // 19: lab.VerifyManagedDutRequest.name:type_name -> lab.NetworkIdentifier
+	22, // 20: lab.ProvisionManagedDutRequest.name:type_name -> lab.NetworkIdentifier
+	26, // 21: lab.ProvisionManagedDutRequest.build_path:type_name -> chromiumos.StoragePath
+	0,  // 22: lab.DutManagerService.CreateManagedDut:input_type -> lab.CreateManagedDutRequest
+	4,  // 23: lab.DutManagerService.DeleteManagedDut:input_type -> lab.DeleteManagedDutRequest
+	6,  // 24: lab.DutManagerService.ListManagedDuts:input_type -> lab.ListManagedDutsRequest
+	8,  // 25: lab.DutManagerService.GetManagedDut:input_type -> lab.GetManagedDutRequest
+	10, // 26: lab.DutManagerService.UpdateManagedDut:input_type -> lab.UpdateManagedDutRequest
+	12, // 27: lab.DutManagerService.LeaseManagedDut:input_type -> lab.LeaseManagedDutRequest
+	14, // 28: lab.DutManagerService.ReturnManagedDutLease:input_type -> lab.ReturnManagedDutLeaseRequest
+	16, // 29: lab.DutManagerService.ExtendManagedDutLease:input_type -> lab.ExtendManagedDutLeaseRequest
+	20, // 30: lab.DutManagerService.ProvisionManagedDut:input_type -> lab.ProvisionManagedDutRequest
+	18, // 31: lab.DutManagerService.VerifyManagedDut:input_type -> lab.VerifyManagedDutRequest
+	30, // 32: lab.DutManagerService.CreateManagedDut:output_type -> chromiumos.longrunning.Operation
+	5,  // 33: lab.DutManagerService.DeleteManagedDut:output_type -> lab.DeleteManagedDutResponse
+	7,  // 34: lab.DutManagerService.ListManagedDuts:output_type -> lab.ListManagedDutsResponse
+	9,  // 35: lab.DutManagerService.GetManagedDut:output_type -> lab.GetManagedDutResponse
+	11, // 36: lab.DutManagerService.UpdateManagedDut:output_type -> lab.UpdateManagedDutResponse
+	30, // 37: lab.DutManagerService.LeaseManagedDut:output_type -> chromiumos.longrunning.Operation
+	15, // 38: lab.DutManagerService.ReturnManagedDutLease:output_type -> lab.ReturnManagedDutLeaseResponse
+	17, // 39: lab.DutManagerService.ExtendManagedDutLease:output_type -> lab.ExtendManagedDutLeaseResponse
+	21, // 40: lab.DutManagerService.ProvisionManagedDut:output_type -> lab.ProvisionManagedDutResponse
+	19, // 41: lab.DutManagerService.VerifyManagedDut:output_type -> lab.VerifyManagedDutResponse
+	32, // [32:42] is the sub-list for method output_type
+	22, // [22:32] is the sub-list for method input_type
+	22, // [22:22] is the sub-list for extension type_name
+	22, // [22:22] is the sub-list for extension extendee
+	0,  // [0:22] is the sub-list for field type_name
+}
+
+func init() { file_lab_dut_manager_proto_init() }
+func file_lab_dut_manager_proto_init() {
+	if File_lab_dut_manager_proto != nil {
+		return
+	}
+	file_lab_managed_dut_proto_init()
+	if !protoimpl.UnsafeEnabled {
+		file_lab_dut_manager_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateManagedDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateManagedDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateMManagedDutMetadata); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateManagedDutMetadata); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteManagedDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteManagedDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListManagedDutsRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListManagedDutsResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetManagedDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetManagedDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateManagedDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateManagedDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*LeaseManagedDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*LeaseManagedDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ReturnManagedDutLeaseRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ReturnManagedDutLeaseResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ExtendManagedDutLeaseRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ExtendManagedDutLeaseResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*VerifyManagedDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*VerifyManagedDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ProvisionManagedDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ProvisionManagedDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_lab_dut_manager_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   22,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_lab_dut_manager_proto_goTypes,
+		DependencyIndexes: file_lab_dut_manager_proto_depIdxs,
+		MessageInfos:      file_lab_dut_manager_proto_msgTypes,
+	}.Build()
+	File_lab_dut_manager_proto = out.File
+	file_lab_dut_manager_proto_rawDesc = nil
+	file_lab_dut_manager_proto_goTypes = nil
+	file_lab_dut_manager_proto_depIdxs = nil
+}
diff --git a/go/lab/dut_manager_grpc.pb.go b/go/lab/dut_manager_grpc.pb.go
new file mode 100644
index 0000000..26e8001
--- /dev/null
+++ b/go/lab/dut_manager_grpc.pb.go
@@ -0,0 +1,464 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package lab
+
+import (
+	context "context"
+	longrunning "go.chromium.org/chromiumos/config/go/longrunning"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+// DutManagerServiceClient is the client API for DutManagerService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type DutManagerServiceClient interface {
+	// Give the DutManager control over a Dut.
+	CreateManagedDut(ctx context.Context, in *CreateManagedDutRequest, opts ...grpc.CallOption) (*longrunning.Operation, error)
+	DeleteManagedDut(ctx context.Context, in *DeleteManagedDutRequest, opts ...grpc.CallOption) (*DeleteManagedDutResponse, error)
+	// List all the Dut's and their current state.
+	// this is a MVP - future versions will allow filter params to be
+	// passed in so you can list all the failed Dut's etc/
+	// The state history will not be populated in List requests.
+	ListManagedDuts(ctx context.Context, in *ListManagedDutsRequest, opts ...grpc.CallOption) (*ListManagedDutsResponse, error)
+	// Get details including state history for a given Dut.
+	GetManagedDut(ctx context.Context, in *GetManagedDutRequest, opts ...grpc.CallOption) (*GetManagedDutResponse, error)
+	UpdateManagedDut(ctx context.Context, in *UpdateManagedDutRequest, opts ...grpc.CallOption) (*UpdateManagedDutResponse, error)
+	// Tests request temporary ownership of a Dut to run test on.
+	// test metadata specifies what type of hardware/software is required.
+	// Leases should be given a timeout, ideally the request would indicate the
+	// length of lease required and that lease time would be used.
+	LeaseManagedDut(ctx context.Context, in *LeaseManagedDutRequest, opts ...grpc.CallOption) (*longrunning.Operation, error)
+	// When a test is done with a Dut it should return the lease.
+	ReturnManagedDutLease(ctx context.Context, in *ReturnManagedDutLeaseRequest, opts ...grpc.CallOption) (*ReturnManagedDutLeaseResponse, error)
+	// If a test needs to extend the time it owns the Dut is should renew
+	// the lease.
+	ExtendManagedDutLease(ctx context.Context, in *ExtendManagedDutLeaseRequest, opts ...grpc.CallOption) (*ExtendManagedDutLeaseResponse, error)
+	// Provision a Dut, used in the Moblab "flashstation" user journey.
+	ProvisionManagedDut(ctx context.Context, in *ProvisionManagedDutRequest, opts ...grpc.CallOption) (*ProvisionManagedDutResponse, error)
+	// Request that a Dut be verified, if the verify fails it should be
+	// put into repairs.  The call returns when the verification has started
+	// not when complete/repaired.
+	// Use case is when a Dut has been manually repaired this is how a user
+	// can request that the Dut be checked and returned to READY state.
+	VerifyManagedDut(ctx context.Context, in *VerifyManagedDutRequest, opts ...grpc.CallOption) (*VerifyManagedDutResponse, error)
+}
+
+type dutManagerServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewDutManagerServiceClient(cc grpc.ClientConnInterface) DutManagerServiceClient {
+	return &dutManagerServiceClient{cc}
+}
+
+func (c *dutManagerServiceClient) CreateManagedDut(ctx context.Context, in *CreateManagedDutRequest, opts ...grpc.CallOption) (*longrunning.Operation, error) {
+	out := new(longrunning.Operation)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerService/CreateManagedDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerServiceClient) DeleteManagedDut(ctx context.Context, in *DeleteManagedDutRequest, opts ...grpc.CallOption) (*DeleteManagedDutResponse, error) {
+	out := new(DeleteManagedDutResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerService/DeleteManagedDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerServiceClient) ListManagedDuts(ctx context.Context, in *ListManagedDutsRequest, opts ...grpc.CallOption) (*ListManagedDutsResponse, error) {
+	out := new(ListManagedDutsResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerService/ListManagedDuts", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerServiceClient) GetManagedDut(ctx context.Context, in *GetManagedDutRequest, opts ...grpc.CallOption) (*GetManagedDutResponse, error) {
+	out := new(GetManagedDutResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerService/GetManagedDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerServiceClient) UpdateManagedDut(ctx context.Context, in *UpdateManagedDutRequest, opts ...grpc.CallOption) (*UpdateManagedDutResponse, error) {
+	out := new(UpdateManagedDutResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerService/UpdateManagedDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerServiceClient) LeaseManagedDut(ctx context.Context, in *LeaseManagedDutRequest, opts ...grpc.CallOption) (*longrunning.Operation, error) {
+	out := new(longrunning.Operation)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerService/LeaseManagedDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerServiceClient) ReturnManagedDutLease(ctx context.Context, in *ReturnManagedDutLeaseRequest, opts ...grpc.CallOption) (*ReturnManagedDutLeaseResponse, error) {
+	out := new(ReturnManagedDutLeaseResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerService/ReturnManagedDutLease", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerServiceClient) ExtendManagedDutLease(ctx context.Context, in *ExtendManagedDutLeaseRequest, opts ...grpc.CallOption) (*ExtendManagedDutLeaseResponse, error) {
+	out := new(ExtendManagedDutLeaseResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerService/ExtendManagedDutLease", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerServiceClient) ProvisionManagedDut(ctx context.Context, in *ProvisionManagedDutRequest, opts ...grpc.CallOption) (*ProvisionManagedDutResponse, error) {
+	out := new(ProvisionManagedDutResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerService/ProvisionManagedDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerServiceClient) VerifyManagedDut(ctx context.Context, in *VerifyManagedDutRequest, opts ...grpc.CallOption) (*VerifyManagedDutResponse, error) {
+	out := new(VerifyManagedDutResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerService/VerifyManagedDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// DutManagerServiceServer is the server API for DutManagerService service.
+// All implementations must embed UnimplementedDutManagerServiceServer
+// for forward compatibility
+type DutManagerServiceServer interface {
+	// Give the DutManager control over a Dut.
+	CreateManagedDut(context.Context, *CreateManagedDutRequest) (*longrunning.Operation, error)
+	DeleteManagedDut(context.Context, *DeleteManagedDutRequest) (*DeleteManagedDutResponse, error)
+	// List all the Dut's and their current state.
+	// this is a MVP - future versions will allow filter params to be
+	// passed in so you can list all the failed Dut's etc/
+	// The state history will not be populated in List requests.
+	ListManagedDuts(context.Context, *ListManagedDutsRequest) (*ListManagedDutsResponse, error)
+	// Get details including state history for a given Dut.
+	GetManagedDut(context.Context, *GetManagedDutRequest) (*GetManagedDutResponse, error)
+	UpdateManagedDut(context.Context, *UpdateManagedDutRequest) (*UpdateManagedDutResponse, error)
+	// Tests request temporary ownership of a Dut to run test on.
+	// test metadata specifies what type of hardware/software is required.
+	// Leases should be given a timeout, ideally the request would indicate the
+	// length of lease required and that lease time would be used.
+	LeaseManagedDut(context.Context, *LeaseManagedDutRequest) (*longrunning.Operation, error)
+	// When a test is done with a Dut it should return the lease.
+	ReturnManagedDutLease(context.Context, *ReturnManagedDutLeaseRequest) (*ReturnManagedDutLeaseResponse, error)
+	// If a test needs to extend the time it owns the Dut is should renew
+	// the lease.
+	ExtendManagedDutLease(context.Context, *ExtendManagedDutLeaseRequest) (*ExtendManagedDutLeaseResponse, error)
+	// Provision a Dut, used in the Moblab "flashstation" user journey.
+	ProvisionManagedDut(context.Context, *ProvisionManagedDutRequest) (*ProvisionManagedDutResponse, error)
+	// Request that a Dut be verified, if the verify fails it should be
+	// put into repairs.  The call returns when the verification has started
+	// not when complete/repaired.
+	// Use case is when a Dut has been manually repaired this is how a user
+	// can request that the Dut be checked and returned to READY state.
+	VerifyManagedDut(context.Context, *VerifyManagedDutRequest) (*VerifyManagedDutResponse, error)
+	mustEmbedUnimplementedDutManagerServiceServer()
+}
+
+// UnimplementedDutManagerServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedDutManagerServiceServer struct {
+}
+
+func (UnimplementedDutManagerServiceServer) CreateManagedDut(context.Context, *CreateManagedDutRequest) (*longrunning.Operation, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CreateManagedDut not implemented")
+}
+func (UnimplementedDutManagerServiceServer) DeleteManagedDut(context.Context, *DeleteManagedDutRequest) (*DeleteManagedDutResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeleteManagedDut not implemented")
+}
+func (UnimplementedDutManagerServiceServer) ListManagedDuts(context.Context, *ListManagedDutsRequest) (*ListManagedDutsResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ListManagedDuts not implemented")
+}
+func (UnimplementedDutManagerServiceServer) GetManagedDut(context.Context, *GetManagedDutRequest) (*GetManagedDutResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetManagedDut not implemented")
+}
+func (UnimplementedDutManagerServiceServer) UpdateManagedDut(context.Context, *UpdateManagedDutRequest) (*UpdateManagedDutResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdateManagedDut not implemented")
+}
+func (UnimplementedDutManagerServiceServer) LeaseManagedDut(context.Context, *LeaseManagedDutRequest) (*longrunning.Operation, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method LeaseManagedDut not implemented")
+}
+func (UnimplementedDutManagerServiceServer) ReturnManagedDutLease(context.Context, *ReturnManagedDutLeaseRequest) (*ReturnManagedDutLeaseResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ReturnManagedDutLease not implemented")
+}
+func (UnimplementedDutManagerServiceServer) ExtendManagedDutLease(context.Context, *ExtendManagedDutLeaseRequest) (*ExtendManagedDutLeaseResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ExtendManagedDutLease not implemented")
+}
+func (UnimplementedDutManagerServiceServer) ProvisionManagedDut(context.Context, *ProvisionManagedDutRequest) (*ProvisionManagedDutResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ProvisionManagedDut not implemented")
+}
+func (UnimplementedDutManagerServiceServer) VerifyManagedDut(context.Context, *VerifyManagedDutRequest) (*VerifyManagedDutResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method VerifyManagedDut not implemented")
+}
+func (UnimplementedDutManagerServiceServer) mustEmbedUnimplementedDutManagerServiceServer() {}
+
+// UnsafeDutManagerServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to DutManagerServiceServer will
+// result in compilation errors.
+type UnsafeDutManagerServiceServer interface {
+	mustEmbedUnimplementedDutManagerServiceServer()
+}
+
+func RegisterDutManagerServiceServer(s grpc.ServiceRegistrar, srv DutManagerServiceServer) {
+	s.RegisterService(&DutManagerService_ServiceDesc, srv)
+}
+
+func _DutManagerService_CreateManagedDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(CreateManagedDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerServiceServer).CreateManagedDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerService/CreateManagedDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerServiceServer).CreateManagedDut(ctx, req.(*CreateManagedDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerService_DeleteManagedDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(DeleteManagedDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerServiceServer).DeleteManagedDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerService/DeleteManagedDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerServiceServer).DeleteManagedDut(ctx, req.(*DeleteManagedDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerService_ListManagedDuts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ListManagedDutsRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerServiceServer).ListManagedDuts(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerService/ListManagedDuts",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerServiceServer).ListManagedDuts(ctx, req.(*ListManagedDutsRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerService_GetManagedDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetManagedDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerServiceServer).GetManagedDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerService/GetManagedDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerServiceServer).GetManagedDut(ctx, req.(*GetManagedDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerService_UpdateManagedDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(UpdateManagedDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerServiceServer).UpdateManagedDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerService/UpdateManagedDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerServiceServer).UpdateManagedDut(ctx, req.(*UpdateManagedDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerService_LeaseManagedDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(LeaseManagedDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerServiceServer).LeaseManagedDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerService/LeaseManagedDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerServiceServer).LeaseManagedDut(ctx, req.(*LeaseManagedDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerService_ReturnManagedDutLease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ReturnManagedDutLeaseRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerServiceServer).ReturnManagedDutLease(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerService/ReturnManagedDutLease",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerServiceServer).ReturnManagedDutLease(ctx, req.(*ReturnManagedDutLeaseRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerService_ExtendManagedDutLease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ExtendManagedDutLeaseRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerServiceServer).ExtendManagedDutLease(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerService/ExtendManagedDutLease",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerServiceServer).ExtendManagedDutLease(ctx, req.(*ExtendManagedDutLeaseRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerService_ProvisionManagedDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ProvisionManagedDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerServiceServer).ProvisionManagedDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerService/ProvisionManagedDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerServiceServer).ProvisionManagedDut(ctx, req.(*ProvisionManagedDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerService_VerifyManagedDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(VerifyManagedDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerServiceServer).VerifyManagedDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerService/VerifyManagedDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerServiceServer).VerifyManagedDut(ctx, req.(*VerifyManagedDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// DutManagerService_ServiceDesc is the grpc.ServiceDesc for DutManagerService service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var DutManagerService_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "lab.DutManagerService",
+	HandlerType: (*DutManagerServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "CreateManagedDut",
+			Handler:    _DutManagerService_CreateManagedDut_Handler,
+		},
+		{
+			MethodName: "DeleteManagedDut",
+			Handler:    _DutManagerService_DeleteManagedDut_Handler,
+		},
+		{
+			MethodName: "ListManagedDuts",
+			Handler:    _DutManagerService_ListManagedDuts_Handler,
+		},
+		{
+			MethodName: "GetManagedDut",
+			Handler:    _DutManagerService_GetManagedDut_Handler,
+		},
+		{
+			MethodName: "UpdateManagedDut",
+			Handler:    _DutManagerService_UpdateManagedDut_Handler,
+		},
+		{
+			MethodName: "LeaseManagedDut",
+			Handler:    _DutManagerService_LeaseManagedDut_Handler,
+		},
+		{
+			MethodName: "ReturnManagedDutLease",
+			Handler:    _DutManagerService_ReturnManagedDutLease_Handler,
+		},
+		{
+			MethodName: "ExtendManagedDutLease",
+			Handler:    _DutManagerService_ExtendManagedDutLease_Handler,
+		},
+		{
+			MethodName: "ProvisionManagedDut",
+			Handler:    _DutManagerService_ProvisionManagedDut_Handler,
+		},
+		{
+			MethodName: "VerifyManagedDut",
+			Handler:    _DutManagerService_VerifyManagedDut_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "lab/dut_manager.proto",
+}
diff --git a/go/lab/dut_manager_storage.pb.go b/go/lab/dut_manager_storage.pb.go
new file mode 100644
index 0000000..ca5c29c
--- /dev/null
+++ b/go/lab/dut_manager_storage.pb.go
@@ -0,0 +1,731 @@
+// Copyright 2021 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0-devel
+// 	protoc        v3.17.1
+// source: lab/dut_manager_storage.proto
+
+package lab
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	_ "google.golang.org/protobuf/types/known/emptypb"
+	fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type CreateDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Dut *ManagedDut `protobuf:"bytes,1,opt,name=dut,proto3" json:"dut,omitempty"`
+}
+
+func (x *CreateDutRequest) Reset() {
+	*x = CreateDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_storage_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateDutRequest) ProtoMessage() {}
+
+func (x *CreateDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_storage_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateDutRequest.ProtoReflect.Descriptor instead.
+func (*CreateDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_storage_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *CreateDutRequest) GetDut() *ManagedDut {
+	if x != nil {
+		return x.Dut
+	}
+	return nil
+}
+
+type CreateDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *CreateDutResponse) Reset() {
+	*x = CreateDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_storage_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateDutResponse) ProtoMessage() {}
+
+func (x *CreateDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_storage_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateDutResponse.ProtoReflect.Descriptor instead.
+func (*CreateDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_storage_proto_rawDescGZIP(), []int{1}
+}
+
+type DeleteDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *DeleteDutRequest) Reset() {
+	*x = DeleteDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_storage_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteDutRequest) ProtoMessage() {}
+
+func (x *DeleteDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_storage_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteDutRequest.ProtoReflect.Descriptor instead.
+func (*DeleteDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_storage_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *DeleteDutRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+type DeleteDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *DeleteDutResponse) Reset() {
+	*x = DeleteDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_storage_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteDutResponse) ProtoMessage() {}
+
+func (x *DeleteDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_storage_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteDutResponse.ProtoReflect.Descriptor instead.
+func (*DeleteDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_storage_proto_rawDescGZIP(), []int{3}
+}
+
+type ListDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *ListDutRequest) Reset() {
+	*x = ListDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_storage_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListDutRequest) ProtoMessage() {}
+
+func (x *ListDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_storage_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListDutRequest.ProtoReflect.Descriptor instead.
+func (*ListDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_storage_proto_rawDescGZIP(), []int{4}
+}
+
+type ListDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Duts []*ManagedDut `protobuf:"bytes,1,rep,name=duts,proto3" json:"duts,omitempty"`
+}
+
+func (x *ListDutResponse) Reset() {
+	*x = ListDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_storage_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListDutResponse) ProtoMessage() {}
+
+func (x *ListDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_storage_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListDutResponse.ProtoReflect.Descriptor instead.
+func (*ListDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_storage_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *ListDutResponse) GetDuts() []*ManagedDut {
+	if x != nil {
+		return x.Duts
+	}
+	return nil
+}
+
+type GetDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *GetDutRequest) Reset() {
+	*x = GetDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_storage_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetDutRequest) ProtoMessage() {}
+
+func (x *GetDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_storage_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetDutRequest.ProtoReflect.Descriptor instead.
+func (*GetDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_storage_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *GetDutRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+type GetDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Dut *ManagedDut `protobuf:"bytes,1,opt,name=dut,proto3" json:"dut,omitempty"`
+}
+
+func (x *GetDutResponse) Reset() {
+	*x = GetDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_storage_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetDutResponse) ProtoMessage() {}
+
+func (x *GetDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_storage_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetDutResponse.ProtoReflect.Descriptor instead.
+func (*GetDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_storage_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *GetDutResponse) GetDut() *ManagedDut {
+	if x != nil {
+		return x.Dut
+	}
+	return nil
+}
+
+type UpdateDutRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Dut        *ManagedDut            `protobuf:"bytes,1,opt,name=dut,proto3" json:"dut,omitempty"`
+	UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
+}
+
+func (x *UpdateDutRequest) Reset() {
+	*x = UpdateDutRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_storage_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UpdateDutRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateDutRequest) ProtoMessage() {}
+
+func (x *UpdateDutRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_storage_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateDutRequest.ProtoReflect.Descriptor instead.
+func (*UpdateDutRequest) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_storage_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *UpdateDutRequest) GetDut() *ManagedDut {
+	if x != nil {
+		return x.Dut
+	}
+	return nil
+}
+
+func (x *UpdateDutRequest) GetUpdateMask() *fieldmaskpb.FieldMask {
+	if x != nil {
+		return x.UpdateMask
+	}
+	return nil
+}
+
+type UpdateDutResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *UpdateDutResponse) Reset() {
+	*x = UpdateDutResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_dut_manager_storage_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UpdateDutResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateDutResponse) ProtoMessage() {}
+
+func (x *UpdateDutResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_dut_manager_storage_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateDutResponse.ProtoReflect.Descriptor instead.
+func (*UpdateDutResponse) Descriptor() ([]byte, []int) {
+	return file_lab_dut_manager_storage_proto_rawDescGZIP(), []int{9}
+}
+
+var File_lab_dut_manager_storage_proto protoreflect.FileDescriptor
+
+var file_lab_dut_manager_storage_proto_rawDesc = []byte{
+	0x0a, 0x1d, 0x6c, 0x61, 0x62, 0x2f, 0x64, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+	0x72, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
+	0x03, 0x6c, 0x61, 0x62, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x6c, 0x61, 0x62, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64,
+	0x5f, 0x64, 0x75, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x10, 0x43, 0x72,
+	0x65, 0x61, 0x74, 0x65, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21,
+	0x0a, 0x03, 0x64, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x61,
+	0x62, 0x2e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x03, 0x64, 0x75,
+	0x74, 0x22, 0x13, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x75, 0x74, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+	0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x13,
+	0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x75, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x36, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x75, 0x74,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x64, 0x75, 0x74, 0x73,
+	0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4d, 0x61, 0x6e,
+	0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x04, 0x64, 0x75, 0x74, 0x73, 0x22, 0x23, 0x0a,
+	0x0d, 0x47, 0x65, 0x74, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12,
+	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x22, 0x33, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x03, 0x64, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44,
+	0x75, 0x74, 0x52, 0x03, 0x64, 0x75, 0x74, 0x22, 0x72, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x03, 0x64,
+	0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4d,
+	0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x52, 0x03, 0x64, 0x75, 0x74, 0x12, 0x3b,
+	0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52,
+	0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x13, 0x0a, 0x11, 0x55,
+	0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x32, 0xb7, 0x02, 0x0a, 0x18, 0x44, 0x75, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53,
+	0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3a, 0x0a,
+	0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x75, 0x74, 0x12, 0x15, 0x2e, 0x6c, 0x61, 0x62,
+	0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x75,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x44, 0x65, 0x6c,
+	0x65, 0x74, 0x65, 0x44, 0x75, 0x74, 0x12, 0x15, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x44, 0x65, 0x6c,
+	0x65, 0x74, 0x65, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
+	0x6c, 0x61, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x75, 0x74,
+	0x12, 0x13, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x75, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74,
+	0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x47,
+	0x65, 0x74, 0x44, 0x75, 0x74, 0x12, 0x12, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x44,
+	0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x61, 0x62, 0x2e,
+	0x47, 0x65, 0x74, 0x44, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a,
+	0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x75, 0x74, 0x12, 0x15, 0x2e, 0x6c, 0x61,
+	0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44,
+	0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x6f,
+	0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x63, 0x68,
+	0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2f, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x2f, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x6c, 0x61, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x33,
+}
+
+var (
+	file_lab_dut_manager_storage_proto_rawDescOnce sync.Once
+	file_lab_dut_manager_storage_proto_rawDescData = file_lab_dut_manager_storage_proto_rawDesc
+)
+
+func file_lab_dut_manager_storage_proto_rawDescGZIP() []byte {
+	file_lab_dut_manager_storage_proto_rawDescOnce.Do(func() {
+		file_lab_dut_manager_storage_proto_rawDescData = protoimpl.X.CompressGZIP(file_lab_dut_manager_storage_proto_rawDescData)
+	})
+	return file_lab_dut_manager_storage_proto_rawDescData
+}
+
+var file_lab_dut_manager_storage_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
+var file_lab_dut_manager_storage_proto_goTypes = []interface{}{
+	(*CreateDutRequest)(nil),      // 0: lab.CreateDutRequest
+	(*CreateDutResponse)(nil),     // 1: lab.CreateDutResponse
+	(*DeleteDutRequest)(nil),      // 2: lab.DeleteDutRequest
+	(*DeleteDutResponse)(nil),     // 3: lab.DeleteDutResponse
+	(*ListDutRequest)(nil),        // 4: lab.ListDutRequest
+	(*ListDutResponse)(nil),       // 5: lab.ListDutResponse
+	(*GetDutRequest)(nil),         // 6: lab.GetDutRequest
+	(*GetDutResponse)(nil),        // 7: lab.GetDutResponse
+	(*UpdateDutRequest)(nil),      // 8: lab.UpdateDutRequest
+	(*UpdateDutResponse)(nil),     // 9: lab.UpdateDutResponse
+	(*ManagedDut)(nil),            // 10: lab.ManagedDut
+	(*fieldmaskpb.FieldMask)(nil), // 11: google.protobuf.FieldMask
+}
+var file_lab_dut_manager_storage_proto_depIdxs = []int32{
+	10, // 0: lab.CreateDutRequest.dut:type_name -> lab.ManagedDut
+	10, // 1: lab.ListDutResponse.duts:type_name -> lab.ManagedDut
+	10, // 2: lab.GetDutResponse.dut:type_name -> lab.ManagedDut
+	10, // 3: lab.UpdateDutRequest.dut:type_name -> lab.ManagedDut
+	11, // 4: lab.UpdateDutRequest.update_mask:type_name -> google.protobuf.FieldMask
+	0,  // 5: lab.DutManagerStorageService.CreateDut:input_type -> lab.CreateDutRequest
+	2,  // 6: lab.DutManagerStorageService.DeleteDut:input_type -> lab.DeleteDutRequest
+	4,  // 7: lab.DutManagerStorageService.ListDut:input_type -> lab.ListDutRequest
+	6,  // 8: lab.DutManagerStorageService.GetDut:input_type -> lab.GetDutRequest
+	8,  // 9: lab.DutManagerStorageService.UpdateDut:input_type -> lab.UpdateDutRequest
+	1,  // 10: lab.DutManagerStorageService.CreateDut:output_type -> lab.CreateDutResponse
+	3,  // 11: lab.DutManagerStorageService.DeleteDut:output_type -> lab.DeleteDutResponse
+	5,  // 12: lab.DutManagerStorageService.ListDut:output_type -> lab.ListDutResponse
+	7,  // 13: lab.DutManagerStorageService.GetDut:output_type -> lab.GetDutResponse
+	9,  // 14: lab.DutManagerStorageService.UpdateDut:output_type -> lab.UpdateDutResponse
+	10, // [10:15] is the sub-list for method output_type
+	5,  // [5:10] is the sub-list for method input_type
+	5,  // [5:5] is the sub-list for extension type_name
+	5,  // [5:5] is the sub-list for extension extendee
+	0,  // [0:5] is the sub-list for field type_name
+}
+
+func init() { file_lab_dut_manager_storage_proto_init() }
+func file_lab_dut_manager_storage_proto_init() {
+	if File_lab_dut_manager_storage_proto != nil {
+		return
+	}
+	file_lab_managed_dut_proto_init()
+	if !protoimpl.UnsafeEnabled {
+		file_lab_dut_manager_storage_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_storage_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_storage_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_storage_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_storage_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_storage_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_storage_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_storage_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_storage_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateDutRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_dut_manager_storage_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateDutResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_lab_dut_manager_storage_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   10,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_lab_dut_manager_storage_proto_goTypes,
+		DependencyIndexes: file_lab_dut_manager_storage_proto_depIdxs,
+		MessageInfos:      file_lab_dut_manager_storage_proto_msgTypes,
+	}.Build()
+	File_lab_dut_manager_storage_proto = out.File
+	file_lab_dut_manager_storage_proto_rawDesc = nil
+	file_lab_dut_manager_storage_proto_goTypes = nil
+	file_lab_dut_manager_storage_proto_depIdxs = nil
+}
diff --git a/go/lab/dut_manager_storage_grpc.pb.go b/go/lab/dut_manager_storage_grpc.pb.go
new file mode 100644
index 0000000..3308df4
--- /dev/null
+++ b/go/lab/dut_manager_storage_grpc.pb.go
@@ -0,0 +1,246 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package lab
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+// DutManagerStorageServiceClient is the client API for DutManagerStorageService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type DutManagerStorageServiceClient interface {
+	CreateDut(ctx context.Context, in *CreateDutRequest, opts ...grpc.CallOption) (*CreateDutResponse, error)
+	DeleteDut(ctx context.Context, in *DeleteDutRequest, opts ...grpc.CallOption) (*DeleteDutResponse, error)
+	ListDut(ctx context.Context, in *ListDutRequest, opts ...grpc.CallOption) (*ListDutResponse, error)
+	GetDut(ctx context.Context, in *GetDutRequest, opts ...grpc.CallOption) (*GetDutResponse, error)
+	UpdateDut(ctx context.Context, in *UpdateDutRequest, opts ...grpc.CallOption) (*UpdateDutResponse, error)
+}
+
+type dutManagerStorageServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewDutManagerStorageServiceClient(cc grpc.ClientConnInterface) DutManagerStorageServiceClient {
+	return &dutManagerStorageServiceClient{cc}
+}
+
+func (c *dutManagerStorageServiceClient) CreateDut(ctx context.Context, in *CreateDutRequest, opts ...grpc.CallOption) (*CreateDutResponse, error) {
+	out := new(CreateDutResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerStorageService/CreateDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerStorageServiceClient) DeleteDut(ctx context.Context, in *DeleteDutRequest, opts ...grpc.CallOption) (*DeleteDutResponse, error) {
+	out := new(DeleteDutResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerStorageService/DeleteDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerStorageServiceClient) ListDut(ctx context.Context, in *ListDutRequest, opts ...grpc.CallOption) (*ListDutResponse, error) {
+	out := new(ListDutResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerStorageService/ListDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerStorageServiceClient) GetDut(ctx context.Context, in *GetDutRequest, opts ...grpc.CallOption) (*GetDutResponse, error) {
+	out := new(GetDutResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerStorageService/GetDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *dutManagerStorageServiceClient) UpdateDut(ctx context.Context, in *UpdateDutRequest, opts ...grpc.CallOption) (*UpdateDutResponse, error) {
+	out := new(UpdateDutResponse)
+	err := c.cc.Invoke(ctx, "/lab.DutManagerStorageService/UpdateDut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// DutManagerStorageServiceServer is the server API for DutManagerStorageService service.
+// All implementations must embed UnimplementedDutManagerStorageServiceServer
+// for forward compatibility
+type DutManagerStorageServiceServer interface {
+	CreateDut(context.Context, *CreateDutRequest) (*CreateDutResponse, error)
+	DeleteDut(context.Context, *DeleteDutRequest) (*DeleteDutResponse, error)
+	ListDut(context.Context, *ListDutRequest) (*ListDutResponse, error)
+	GetDut(context.Context, *GetDutRequest) (*GetDutResponse, error)
+	UpdateDut(context.Context, *UpdateDutRequest) (*UpdateDutResponse, error)
+	mustEmbedUnimplementedDutManagerStorageServiceServer()
+}
+
+// UnimplementedDutManagerStorageServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedDutManagerStorageServiceServer struct {
+}
+
+func (UnimplementedDutManagerStorageServiceServer) CreateDut(context.Context, *CreateDutRequest) (*CreateDutResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CreateDut not implemented")
+}
+func (UnimplementedDutManagerStorageServiceServer) DeleteDut(context.Context, *DeleteDutRequest) (*DeleteDutResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeleteDut not implemented")
+}
+func (UnimplementedDutManagerStorageServiceServer) ListDut(context.Context, *ListDutRequest) (*ListDutResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ListDut not implemented")
+}
+func (UnimplementedDutManagerStorageServiceServer) GetDut(context.Context, *GetDutRequest) (*GetDutResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetDut not implemented")
+}
+func (UnimplementedDutManagerStorageServiceServer) UpdateDut(context.Context, *UpdateDutRequest) (*UpdateDutResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdateDut not implemented")
+}
+func (UnimplementedDutManagerStorageServiceServer) mustEmbedUnimplementedDutManagerStorageServiceServer() {
+}
+
+// UnsafeDutManagerStorageServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to DutManagerStorageServiceServer will
+// result in compilation errors.
+type UnsafeDutManagerStorageServiceServer interface {
+	mustEmbedUnimplementedDutManagerStorageServiceServer()
+}
+
+func RegisterDutManagerStorageServiceServer(s grpc.ServiceRegistrar, srv DutManagerStorageServiceServer) {
+	s.RegisterService(&DutManagerStorageService_ServiceDesc, srv)
+}
+
+func _DutManagerStorageService_CreateDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(CreateDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerStorageServiceServer).CreateDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerStorageService/CreateDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerStorageServiceServer).CreateDut(ctx, req.(*CreateDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerStorageService_DeleteDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(DeleteDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerStorageServiceServer).DeleteDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerStorageService/DeleteDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerStorageServiceServer).DeleteDut(ctx, req.(*DeleteDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerStorageService_ListDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ListDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerStorageServiceServer).ListDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerStorageService/ListDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerStorageServiceServer).ListDut(ctx, req.(*ListDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerStorageService_GetDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerStorageServiceServer).GetDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerStorageService/GetDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerStorageServiceServer).GetDut(ctx, req.(*GetDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _DutManagerStorageService_UpdateDut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(UpdateDutRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DutManagerStorageServiceServer).UpdateDut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/lab.DutManagerStorageService/UpdateDut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DutManagerStorageServiceServer).UpdateDut(ctx, req.(*UpdateDutRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// DutManagerStorageService_ServiceDesc is the grpc.ServiceDesc for DutManagerStorageService service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var DutManagerStorageService_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "lab.DutManagerStorageService",
+	HandlerType: (*DutManagerStorageServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "CreateDut",
+			Handler:    _DutManagerStorageService_CreateDut_Handler,
+		},
+		{
+			MethodName: "DeleteDut",
+			Handler:    _DutManagerStorageService_DeleteDut_Handler,
+		},
+		{
+			MethodName: "ListDut",
+			Handler:    _DutManagerStorageService_ListDut_Handler,
+		},
+		{
+			MethodName: "GetDut",
+			Handler:    _DutManagerStorageService_GetDut_Handler,
+		},
+		{
+			MethodName: "UpdateDut",
+			Handler:    _DutManagerStorageService_UpdateDut_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "lab/dut_manager_storage.proto",
+}
diff --git a/go/lab/managed_dut.pb.go b/go/lab/managed_dut.pb.go
new file mode 100644
index 0000000..f8d9529
--- /dev/null
+++ b/go/lab/managed_dut.pb.go
@@ -0,0 +1,746 @@
+// Copyright 2021 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0-devel
+// 	protoc        v3.17.1
+// source: lab/managed_dut.proto
+
+package lab
+
+import (
+	_go "go.chromium.org/chromiumos/config/go"
+	api1 "go.chromium.org/chromiumos/config/go/api"
+	api "go.chromium.org/chromiumos/config/go/test/api"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type ManagedDut_ManagedState int32
+
+const (
+	ManagedDut_UNKNOWN   ManagedDut_ManagedState = 0
+	ManagedDut_READY     ManagedDut_ManagedState = 1 //AIP says use ACTIVE - but in this context I disagree.
+	ManagedDut_PROVISION ManagedDut_ManagedState = 2
+	ManagedDut_VERIFY    ManagedDut_ManagedState = 3
+	ManagedDut_LEASED    ManagedDut_ManagedState = 4
+	ManagedDut_FAILED    ManagedDut_ManagedState = 5
+	ManagedDut_RESET     ManagedDut_ManagedState = 6
+)
+
+// Enum value maps for ManagedDut_ManagedState.
+var (
+	ManagedDut_ManagedState_name = map[int32]string{
+		0: "UNKNOWN",
+		1: "READY",
+		2: "PROVISION",
+		3: "VERIFY",
+		4: "LEASED",
+		5: "FAILED",
+		6: "RESET",
+	}
+	ManagedDut_ManagedState_value = map[string]int32{
+		"UNKNOWN":   0,
+		"READY":     1,
+		"PROVISION": 2,
+		"VERIFY":    3,
+		"LEASED":    4,
+		"FAILED":    5,
+		"RESET":     6,
+	}
+)
+
+func (x ManagedDut_ManagedState) Enum() *ManagedDut_ManagedState {
+	p := new(ManagedDut_ManagedState)
+	*p = x
+	return p
+}
+
+func (x ManagedDut_ManagedState) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ManagedDut_ManagedState) Descriptor() protoreflect.EnumDescriptor {
+	return file_lab_managed_dut_proto_enumTypes[0].Descriptor()
+}
+
+func (ManagedDut_ManagedState) Type() protoreflect.EnumType {
+	return &file_lab_managed_dut_proto_enumTypes[0]
+}
+
+func (x ManagedDut_ManagedState) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ManagedDut_ManagedState.Descriptor instead.
+func (ManagedDut_ManagedState) EnumDescriptor() ([]byte, []int) {
+	return file_lab_managed_dut_proto_rawDescGZIP(), []int{4, 0}
+}
+
+type HistoryRecord struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	State      ManagedDut_ManagedState `protobuf:"varint,1,opt,name=state,proto3,enum=lab.ManagedDut_ManagedState" json:"state,omitempty"`
+	StartTime  *timestamppb.Timestamp  `protobuf:"bytes,2,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"`
+	EndTime    *timestamppb.Timestamp  `protobuf:"bytes,3,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"`
+	Note       string                  `protobuf:"bytes,4,opt,name=note,proto3" json:"note,omitempty"`
+	LeaseOwner string                  `protobuf:"bytes,5,opt,name=lease_owner,json=leaseOwner,proto3" json:"lease_owner,omitempty"`
+}
+
+func (x *HistoryRecord) Reset() {
+	*x = HistoryRecord{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_managed_dut_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *HistoryRecord) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HistoryRecord) ProtoMessage() {}
+
+func (x *HistoryRecord) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_managed_dut_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use HistoryRecord.ProtoReflect.Descriptor instead.
+func (*HistoryRecord) Descriptor() ([]byte, []int) {
+	return file_lab_managed_dut_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *HistoryRecord) GetState() ManagedDut_ManagedState {
+	if x != nil {
+		return x.State
+	}
+	return ManagedDut_UNKNOWN
+}
+
+func (x *HistoryRecord) GetStartTime() *timestamppb.Timestamp {
+	if x != nil {
+		return x.StartTime
+	}
+	return nil
+}
+
+func (x *HistoryRecord) GetEndTime() *timestamppb.Timestamp {
+	if x != nil {
+		return x.EndTime
+	}
+	return nil
+}
+
+func (x *HistoryRecord) GetNote() string {
+	if x != nil {
+		return x.Note
+	}
+	return ""
+}
+
+func (x *HistoryRecord) GetLeaseOwner() string {
+	if x != nil {
+		return x.LeaseOwner
+	}
+	return ""
+}
+
+type Lock struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Reason string `protobuf:"bytes,1,opt,name=reason,proto3" json:"reason,omitempty"`
+}
+
+func (x *Lock) Reset() {
+	*x = Lock{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_managed_dut_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Lock) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Lock) ProtoMessage() {}
+
+func (x *Lock) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_managed_dut_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Lock.ProtoReflect.Descriptor instead.
+func (*Lock) Descriptor() ([]byte, []int) {
+	return file_lab_managed_dut_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *Lock) GetReason() string {
+	if x != nil {
+		return x.Reason
+	}
+	return ""
+}
+
+type Pool struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *Pool) Reset() {
+	*x = Pool{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_managed_dut_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Pool) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Pool) ProtoMessage() {}
+
+func (x *Pool) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_managed_dut_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Pool.ProtoReflect.Descriptor instead.
+func (*Pool) Descriptor() ([]byte, []int) {
+	return file_lab_managed_dut_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Pool) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+type NetworkIdentifier struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to Identifier:
+	//	*NetworkIdentifier_IpAddress
+	//	*NetworkIdentifier_Hostname
+	Identifier isNetworkIdentifier_Identifier `protobuf_oneof:"identifier"`
+}
+
+func (x *NetworkIdentifier) Reset() {
+	*x = NetworkIdentifier{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_managed_dut_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *NetworkIdentifier) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*NetworkIdentifier) ProtoMessage() {}
+
+func (x *NetworkIdentifier) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_managed_dut_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use NetworkIdentifier.ProtoReflect.Descriptor instead.
+func (*NetworkIdentifier) Descriptor() ([]byte, []int) {
+	return file_lab_managed_dut_proto_rawDescGZIP(), []int{3}
+}
+
+func (m *NetworkIdentifier) GetIdentifier() isNetworkIdentifier_Identifier {
+	if m != nil {
+		return m.Identifier
+	}
+	return nil
+}
+
+func (x *NetworkIdentifier) GetIpAddress() string {
+	if x, ok := x.GetIdentifier().(*NetworkIdentifier_IpAddress); ok {
+		return x.IpAddress
+	}
+	return ""
+}
+
+func (x *NetworkIdentifier) GetHostname() string {
+	if x, ok := x.GetIdentifier().(*NetworkIdentifier_Hostname); ok {
+		return x.Hostname
+	}
+	return ""
+}
+
+type isNetworkIdentifier_Identifier interface {
+	isNetworkIdentifier_Identifier()
+}
+
+type NetworkIdentifier_IpAddress struct {
+	IpAddress string `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3,oneof"`
+}
+
+type NetworkIdentifier_Hostname struct {
+	Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3,oneof"`
+}
+
+func (*NetworkIdentifier_IpAddress) isNetworkIdentifier_Identifier() {}
+
+func (*NetworkIdentifier_Hostname) isNetworkIdentifier_Identifier() {}
+
+type ManagedDut struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name        *NetworkIdentifier `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Hostname or IP address or other network identifier.
+	DisplayName string             `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
+	// Arbitrary test fields describing characteristics of a Dut that are used
+	// Tests, specify similar tags for test constraints e.g. touchscreen these
+	// tags are used to match a Dut to a test.
+	Tag *api.DutAttributeList `protobuf:"bytes,3,opt,name=tag,proto3" json:"tag,omitempty"`
+	// Pools are just arbitrary groupings of Duts useful for test scheduling.
+	// for example allowing a lab to split half the devices for one particular
+	// test suite and the rest for a different.
+	// Pools are really just arbitrary strings and could be in the tags field,
+	// but for better user administration of pools it is better to keep them
+	// separate.
+	Pool []*Pool `protobuf:"bytes,4,rep,name=pool,proto3" json:"pool,omitempty"`
+	// Tags that detail if a Dut has a particular periheral or not, example
+	// servo.   These again are kept separate from generic tags for ease of
+	// administration.
+	Peripheral                 *api.DutAttributeList   `protobuf:"bytes,5,opt,name=peripheral,proto3" json:"peripheral,omitempty"` // Labels that users configure for servo etc.
+	MfgConfigId                *api1.MfgConfigId       `protobuf:"bytes,6,opt,name=mfg_config_id,json=mfgConfigId,proto3" json:"mfg_config_id,omitempty"`
+	ProvisionedBuild           *_go.StoragePath        `protobuf:"bytes,7,opt,name=provisioned_build,json=provisionedBuild,proto3" json:"provisioned_build,omitempty"` // provision_service.proto
+	State                      ManagedDut_ManagedState `protobuf:"varint,8,opt,name=state,proto3,enum=lab.ManagedDut_ManagedState" json:"state,omitempty"`
+	Lock                       *Lock                   `protobuf:"bytes,9,opt,name=lock,proto3" json:"lock,omitempty"`                                                                                  // A lock can be in any state, so it is a separate field.
+	OperatorNotes              string                  `protobuf:"bytes,10,opt,name=operator_notes,json=operatorNotes,proto3" json:"operator_notes,omitempty"`                                          // Lock reason or any other free text information.
+	ProvisionedFirmwareVersion string                  `protobuf:"bytes,11,opt,name=provisioned_firmware_version,json=provisionedFirmwareVersion,proto3" json:"provisioned_firmware_version,omitempty"` // Current Dut RW firmware.
+	History                    []*HistoryRecord        `protobuf:"bytes,12,rep,name=history,proto3" json:"history,omitempty"`                                                                           // State changes over time.
+	// DUT's that are associated ( close by ) this DUT, the string should be a network identifier and
+	// the DUT should be known to the DUT Manager.
+	// Schedulers that wish to give the assoiciated Dut to a test must obtain a
+	// lease on that Dut.
+	AssociatedDut   []*NetworkIdentifier `protobuf:"bytes,13,rep,name=associated_dut,json=associatedDut,proto3" json:"associated_dut,omitempty"`
+	IsAssociatedDut bool                 `protobuf:"varint,14,opt,name=is_associated_dut,json=isAssociatedDut,proto3" json:"is_associated_dut,omitempty"` // Associated DUT's should be excluded from general lease requests ?
+}
+
+func (x *ManagedDut) Reset() {
+	*x = ManagedDut{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lab_managed_dut_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ManagedDut) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ManagedDut) ProtoMessage() {}
+
+func (x *ManagedDut) ProtoReflect() protoreflect.Message {
+	mi := &file_lab_managed_dut_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ManagedDut.ProtoReflect.Descriptor instead.
+func (*ManagedDut) Descriptor() ([]byte, []int) {
+	return file_lab_managed_dut_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *ManagedDut) GetName() *NetworkIdentifier {
+	if x != nil {
+		return x.Name
+	}
+	return nil
+}
+
+func (x *ManagedDut) GetDisplayName() string {
+	if x != nil {
+		return x.DisplayName
+	}
+	return ""
+}
+
+func (x *ManagedDut) GetTag() *api.DutAttributeList {
+	if x != nil {
+		return x.Tag
+	}
+	return nil
+}
+
+func (x *ManagedDut) GetPool() []*Pool {
+	if x != nil {
+		return x.Pool
+	}
+	return nil
+}
+
+func (x *ManagedDut) GetPeripheral() *api.DutAttributeList {
+	if x != nil {
+		return x.Peripheral
+	}
+	return nil
+}
+
+func (x *ManagedDut) GetMfgConfigId() *api1.MfgConfigId {
+	if x != nil {
+		return x.MfgConfigId
+	}
+	return nil
+}
+
+func (x *ManagedDut) GetProvisionedBuild() *_go.StoragePath {
+	if x != nil {
+		return x.ProvisionedBuild
+	}
+	return nil
+}
+
+func (x *ManagedDut) GetState() ManagedDut_ManagedState {
+	if x != nil {
+		return x.State
+	}
+	return ManagedDut_UNKNOWN
+}
+
+func (x *ManagedDut) GetLock() *Lock {
+	if x != nil {
+		return x.Lock
+	}
+	return nil
+}
+
+func (x *ManagedDut) GetOperatorNotes() string {
+	if x != nil {
+		return x.OperatorNotes
+	}
+	return ""
+}
+
+func (x *ManagedDut) GetProvisionedFirmwareVersion() string {
+	if x != nil {
+		return x.ProvisionedFirmwareVersion
+	}
+	return ""
+}
+
+func (x *ManagedDut) GetHistory() []*HistoryRecord {
+	if x != nil {
+		return x.History
+	}
+	return nil
+}
+
+func (x *ManagedDut) GetAssociatedDut() []*NetworkIdentifier {
+	if x != nil {
+		return x.AssociatedDut
+	}
+	return nil
+}
+
+func (x *ManagedDut) GetIsAssociatedDut() bool {
+	if x != nil {
+		return x.IsAssociatedDut
+	}
+	return false
+}
+
+var File_lab_managed_dut_proto protoreflect.FileDescriptor
+
+var file_lab_managed_dut_proto_rawDesc = []byte{
+	0x0a, 0x15, 0x6c, 0x61, 0x62, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, 0x64, 0x75,
+	0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x6c, 0x61, 0x62, 0x1a, 0x1f, 0x67, 0x6f,
+	0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69,
+	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x63,
+	0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x61,
+	0x70, 0x69, 0x2f, 0x64, 0x75, 0x74, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d,
+	0x6f, 0x73, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f,
+	0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x66, 0x67,
+	0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x22, 0xea, 0x01, 0x0a, 0x0d, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x63, 0x6f,
+	0x72, 0x64, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0e, 0x32, 0x1c, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44,
+	0x75, 0x74, 0x2e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52,
+	0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f,
+	0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,
+	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d,
+	0x65, 0x12, 0x35, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
+	0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b,
+	0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0a, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x1e, 0x0a,
+	0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x1a, 0x0a,
+	0x04, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x60, 0x0a, 0x11, 0x4e, 0x65, 0x74,
+	0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x1f,
+	0x0a, 0x0a, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12,
+	0x1c, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x48, 0x00, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0c, 0x0a,
+	0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0xc3, 0x06, 0x0a, 0x0a,
+	0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4e,
+	0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61,
+	0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69,
+	0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x03, 0x74, 0x61, 0x67,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75,
+	0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x74,
+	0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x03, 0x74,
+	0x61, 0x67, 0x12, 0x1d, 0x0a, 0x04, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x09, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x04, 0x70, 0x6f, 0x6f,
+	0x6c, 0x12, 0x45, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x69, 0x70, 0x68, 0x65, 0x72, 0x61, 0x6c, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d,
+	0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x74, 0x41,
+	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x65,
+	0x72, 0x69, 0x70, 0x68, 0x65, 0x72, 0x61, 0x6c, 0x12, 0x46, 0x0a, 0x0d, 0x6d, 0x66, 0x67, 0x5f,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x22, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x66, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x49, 0x64, 0x52, 0x0b, 0x6d, 0x66, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64,
+	0x12, 0x44, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x5f,
+	0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x68,
+	0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
+	0x50, 0x61, 0x74, 0x68, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
+	0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18,
+	0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4d, 0x61, 0x6e, 0x61,
+	0x67, 0x65, 0x64, 0x44, 0x75, 0x74, 0x2e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x53, 0x74,
+	0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x04, 0x6c, 0x6f,
+	0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4c,
+	0x6f, 0x63, 0x6b, 0x52, 0x04, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x70, 0x65,
+	0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x6f, 0x74, 0x65, 0x73,
+	0x12, 0x40, 0x0a, 0x1c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x5f,
+	0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+	0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1a, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
+	0x6e, 0x65, 0x64, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x0c, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72,
+	0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
+	0x12, 0x3d, 0x0a, 0x0e, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64,
+	0x75, 0x74, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x4e,
+	0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
+	0x52, 0x0d, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74, 0x12,
+	0x2a, 0x0a, 0x11, 0x69, 0x73, 0x5f, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64,
+	0x5f, 0x64, 0x75, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x73, 0x41, 0x73,
+	0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74, 0x22, 0x64, 0x0a, 0x0c, 0x4d,
+	0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55,
+	0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44,
+	0x59, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e,
+	0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x10, 0x03, 0x12, 0x0a,
+	0x0a, 0x06, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41,
+	0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x53, 0x45, 0x54, 0x10,
+	0x06, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x6f, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d,
+	0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2f,
+	0x69, 0x6e, 0x66, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x6c,
+	0x61, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_lab_managed_dut_proto_rawDescOnce sync.Once
+	file_lab_managed_dut_proto_rawDescData = file_lab_managed_dut_proto_rawDesc
+)
+
+func file_lab_managed_dut_proto_rawDescGZIP() []byte {
+	file_lab_managed_dut_proto_rawDescOnce.Do(func() {
+		file_lab_managed_dut_proto_rawDescData = protoimpl.X.CompressGZIP(file_lab_managed_dut_proto_rawDescData)
+	})
+	return file_lab_managed_dut_proto_rawDescData
+}
+
+var file_lab_managed_dut_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_lab_managed_dut_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
+var file_lab_managed_dut_proto_goTypes = []interface{}{
+	(ManagedDut_ManagedState)(0),  // 0: lab.ManagedDut.ManagedState
+	(*HistoryRecord)(nil),         // 1: lab.HistoryRecord
+	(*Lock)(nil),                  // 2: lab.Lock
+	(*Pool)(nil),                  // 3: lab.Pool
+	(*NetworkIdentifier)(nil),     // 4: lab.NetworkIdentifier
+	(*ManagedDut)(nil),            // 5: lab.ManagedDut
+	(*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp
+	(*api.DutAttributeList)(nil),  // 7: chromiumos.test.api.DutAttributeList
+	(*api1.MfgConfigId)(nil),      // 8: chromiumos.config.api.MfgConfigId
+	(*_go.StoragePath)(nil),       // 9: chromiumos.StoragePath
+}
+var file_lab_managed_dut_proto_depIdxs = []int32{
+	0,  // 0: lab.HistoryRecord.state:type_name -> lab.ManagedDut.ManagedState
+	6,  // 1: lab.HistoryRecord.start_time:type_name -> google.protobuf.Timestamp
+	6,  // 2: lab.HistoryRecord.end_time:type_name -> google.protobuf.Timestamp
+	4,  // 3: lab.ManagedDut.name:type_name -> lab.NetworkIdentifier
+	7,  // 4: lab.ManagedDut.tag:type_name -> chromiumos.test.api.DutAttributeList
+	3,  // 5: lab.ManagedDut.pool:type_name -> lab.Pool
+	7,  // 6: lab.ManagedDut.peripheral:type_name -> chromiumos.test.api.DutAttributeList
+	8,  // 7: lab.ManagedDut.mfg_config_id:type_name -> chromiumos.config.api.MfgConfigId
+	9,  // 8: lab.ManagedDut.provisioned_build:type_name -> chromiumos.StoragePath
+	0,  // 9: lab.ManagedDut.state:type_name -> lab.ManagedDut.ManagedState
+	2,  // 10: lab.ManagedDut.lock:type_name -> lab.Lock
+	1,  // 11: lab.ManagedDut.history:type_name -> lab.HistoryRecord
+	4,  // 12: lab.ManagedDut.associated_dut:type_name -> lab.NetworkIdentifier
+	13, // [13:13] is the sub-list for method output_type
+	13, // [13:13] is the sub-list for method input_type
+	13, // [13:13] is the sub-list for extension type_name
+	13, // [13:13] is the sub-list for extension extendee
+	0,  // [0:13] is the sub-list for field type_name
+}
+
+func init() { file_lab_managed_dut_proto_init() }
+func file_lab_managed_dut_proto_init() {
+	if File_lab_managed_dut_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_lab_managed_dut_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*HistoryRecord); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_managed_dut_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Lock); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_managed_dut_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Pool); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_managed_dut_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*NetworkIdentifier); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_lab_managed_dut_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ManagedDut); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_lab_managed_dut_proto_msgTypes[3].OneofWrappers = []interface{}{
+		(*NetworkIdentifier_IpAddress)(nil),
+		(*NetworkIdentifier_Hostname)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_lab_managed_dut_proto_rawDesc,
+			NumEnums:      1,
+			NumMessages:   5,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_lab_managed_dut_proto_goTypes,
+		DependencyIndexes: file_lab_managed_dut_proto_depIdxs,
+		EnumInfos:         file_lab_managed_dut_proto_enumTypes,
+		MessageInfos:      file_lab_managed_dut_proto_msgTypes,
+	}.Build()
+	File_lab_managed_dut_proto = out.File
+	file_lab_managed_dut_proto_rawDesc = nil
+	file_lab_managed_dut_proto_goTypes = nil
+	file_lab_managed_dut_proto_depIdxs = nil
+}
diff --git a/src/lab/dut_manager.proto b/src/lab/dut_manager.proto
new file mode 100644
index 0000000..a5de504
--- /dev/null
+++ b/src/lab/dut_manager.proto
@@ -0,0 +1,160 @@
+// Copyright 2021 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto3";
+
+package lab;
+
+option go_package = "go.chromium.org/chromiumos/infra/proto/go/lab";
+
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/empty.proto";
+
+import "chromiumos/test/api/dut_attribute.proto";
+import "chromiumos/storage_path.proto";
+import "chromiumos/longrunning/operations.proto";
+import "chromiumos/config/api/mfg_config_id.proto";
+
+import "lab/managed_dut.proto";
+
+// Dut manager is a service the controls access to Dut's that are
+service DutManagerService {
+  // Give the DutManager control over a Dut.
+  rpc CreateManagedDut(CreateManagedDutRequest) returns (chromiumos.longrunning.Operation) {
+    option (chromiumos.longrunning.operation_info) = {
+      response_type: "CreateManagedDutResponse",
+      metadata_type: "CreateMManagedDutMetadata"
+    };
+  }
+  rpc DeleteManagedDut(DeleteManagedDutRequest) returns (DeleteManagedDutResponse);
+  // List all the Dut's and their current state.
+  // this is a MVP - future versions will allow filter params to be
+  // passed in so you can list all the failed Dut's etc/
+  // The state history will not be populated in List requests.
+  rpc ListManagedDuts(ListManagedDutsRequest) returns (ListManagedDutsResponse);
+  // Get details including state history for a given Dut.
+  rpc GetManagedDut(GetManagedDutRequest) returns (GetManagedDutResponse);
+  rpc UpdateManagedDut(UpdateManagedDutRequest) returns (UpdateManagedDutResponse);
+  // Tests request temporary ownership of a Dut to run test on.
+  // test metadata specifies what type of hardware/software is required.
+  // Leases should be given a timeout, ideally the request would indicate the
+  // length of lease required and that lease time would be used.
+  rpc LeaseManagedDut(LeaseManagedDutRequest) returns (chromiumos.longrunning.Operation) {
+    option (chromiumos.longrunning.operation_info) = {
+      response_type: "LeaseManagedDutResponse",
+      metadata_type: "LeaseManagedDutMetadata"
+    };
+  }
+  // When a test is done with a Dut it should return the lease.
+  rpc ReturnManagedDutLease(ReturnManagedDutLeaseRequest) returns (ReturnManagedDutLeaseResponse);
+  // If a test needs to extend the time it owns the Dut is should renew
+  // the lease.
+  rpc ExtendManagedDutLease(ExtendManagedDutLeaseRequest) returns (ExtendManagedDutLeaseResponse);
+  // Provision a Dut, used in the Moblab "flashstation" user journey.
+  rpc ProvisionManagedDut(ProvisionManagedDutRequest) returns (ProvisionManagedDutResponse);
+  // Request that a Dut be verified, if the verify fails it should be
+  // put into repairs.  The call returns when the verification has started
+  // not when complete/repaired.
+  // Use case is when a Dut has been manually repaired this is how a user
+  // can request that the Dut be checked and returned to READY state.
+  rpc VerifyManagedDut(VerifyManagedDutRequest) returns (VerifyManagedDutResponse);
+}
+
+message CreateManagedDutRequest {
+  NetworkIdentifier name = 1 ;
+  string display_name = 2;
+}
+
+message CreateManagedDutResponse{
+}
+
+message CreateMManagedDutMetadata{
+}
+
+message CreateManagedDutMetadata{
+}
+
+message DeleteManagedDutRequest {
+  NetworkIdentifier name = 1 ;
+}
+
+message DeleteManagedDutResponse {
+}
+
+message ListManagedDutsRequest {
+  repeated ManagedDut duts = 1;
+}
+
+message ListManagedDutsResponse {
+  repeated ManagedDut duts = 1;
+}
+
+message GetManagedDutRequest {
+  NetworkIdentifier name = 1 ;
+}
+
+message GetManagedDutResponse {
+  ManagedDut dut = 1;
+}
+
+message UpdateManagedDutRequest {
+  ManagedDut dut = 1 ;
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+message UpdateManagedDutResponse {
+}
+
+message LeaseManagedDutRequest {
+  chromiumos.test.api.DutAttribute model = 1;
+  string lease_owner = 2 ; // The task id / test id of the lease holder
+  chromiumos.StoragePath software_path = 3 ;  // provision_service.proto
+  int32 lease_length_secs = 4 ; // requested time in second
+  chromiumos.test.api.DutAttributeList tag = 5;
+  chromiumos.test.api.DutAttributeList pool = 6;
+  chromiumos.test.api.DutAttributeList peripheral = 7;
+  chromiumos.config.api.MfgConfigId mfg_config_id = 8;
+  int32 min_duts = 9;  // Minimum number of Duts requested, for multi dut
+  int32 max_duts = 10;  // Maximum number of Duts requested, for multi dut
+  int32 number_associated_duts = 11; // Get a lease on a Dut that is associated with another DUT and not generally available for lease.
+}
+
+message LeaseManagedDutResponse {
+  repeated NetworkIdentifier name = 1;
+  google.protobuf.Timestamp expiry_time_secs = 2;
+}
+
+message ReturnManagedDutLeaseRequest {
+  NetworkIdentifier name = 1;
+  bool force = 2;  // someone other than the leaseholder is expiring the lease.
+  string force_reason = 3; // why a forced lease return not by the owner was necessary.
+}
+
+message ReturnManagedDutLeaseResponse {
+}
+
+message ExtendManagedDutLeaseRequest {
+  NetworkIdentifier name = 1;
+  int32 lease_length_secs = 3;
+}
+
+message ExtendManagedDutLeaseResponse {
+  google.protobuf.Timestamp expiry_time_secs = 2;
+}
+
+message VerifyManagedDutRequest {
+  NetworkIdentifier name = 1;
+}
+
+message VerifyManagedDutResponse {
+}
+
+message ProvisionManagedDutRequest {
+  NetworkIdentifier name = 1;
+  chromiumos.StoragePath build_path = 2;
+}
+
+message ProvisionManagedDutResponse {
+}
\ No newline at end of file
diff --git a/src/lab/dut_manager_storage.proto b/src/lab/dut_manager_storage.proto
new file mode 100644
index 0000000..ac94b9b
--- /dev/null
+++ b/src/lab/dut_manager_storage.proto
@@ -0,0 +1,66 @@
+// Copyright 2021 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto3";
+
+package lab;
+
+option go_package = "go.chromium.org/chromiumos/infra/proto/go/lab";
+
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+
+import "lab/managed_dut.proto";
+
+// DutManagerStorageService is the service that the provides persistant storage for
+// ManagedDut information in an TLE.
+
+// The only customer of this contract is the DutManager - it allows the
+// business logic of the DutManager to be re-used no matter how the
+// information about managed Duts is stored persistently.
+
+service DutManagerStorageService {
+  rpc CreateDut(CreateDutRequest) returns (CreateDutResponse);
+  rpc DeleteDut(DeleteDutRequest) returns (DeleteDutResponse);
+  rpc ListDut(ListDutRequest) returns (ListDutResponse);
+  rpc GetDut(GetDutRequest) returns (GetDutResponse);
+  rpc UpdateDut(UpdateDutRequest) returns (UpdateDutResponse);
+}
+
+message CreateDutRequest {
+    lab.ManagedDut dut = 1;
+}
+
+message CreateDutResponse {
+}
+
+message DeleteDutRequest {
+    string name = 1;
+}
+
+message DeleteDutResponse {
+}
+
+message ListDutRequest {
+}
+
+message ListDutResponse {
+    repeated lab.ManagedDut duts = 1;
+}
+
+message GetDutRequest {
+    string name = 1;
+}
+
+message GetDutResponse {
+    lab.ManagedDut dut = 1;
+}
+
+message UpdateDutRequest {
+    lab.ManagedDut dut = 1;
+    google.protobuf.FieldMask update_mask = 2;
+}
+
+message UpdateDutResponse {
+}
\ No newline at end of file
diff --git a/src/lab/managed_dut.proto b/src/lab/managed_dut.proto
new file mode 100644
index 0000000..d7508cc
--- /dev/null
+++ b/src/lab/managed_dut.proto
@@ -0,0 +1,83 @@
+// Copyright 2021 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto3";
+
+package lab;
+
+option go_package = "go.chromium.org/chromiumos/infra/proto/go/lab";
+
+import "google/protobuf/timestamp.proto";
+
+import "chromiumos/test/api/dut_attribute.proto";
+import "chromiumos/storage_path.proto";
+import "chromiumos/config/api/mfg_config_id.proto";
+
+
+message HistoryRecord {
+    ManagedDut.ManagedState state = 1 ;
+    google.protobuf.Timestamp start_time = 2 ;
+    google.protobuf.Timestamp end_time = 3;
+    string note = 4;
+    string lease_owner = 5;
+}
+
+message Lock {
+    string reason = 1;
+    }
+
+message Pool {
+    string name = 1;
+}
+
+message NetworkIdentifier {
+    oneof identifier {
+        string ip_address = 1;
+        string hostname = 2;
+    }
+}
+
+message ManagedDut {
+
+    enum ManagedState {
+        UNKNOWN = 0;
+        READY = 1;  //AIP says use ACTIVE - but in this context I disagree.
+        PROVISION = 2;
+        VERIFY = 3;
+        LEASED = 4;
+        FAILED = 5;
+        RESET = 6;
+      }
+
+    NetworkIdentifier name = 1 ;  // Hostname or IP address or other network identifier.
+    string display_name = 2;
+    // Arbitrary test fields describing characteristics of a Dut that are used
+    // Tests, specify similar tags for test constraints e.g. touchscreen these
+    // tags are used to match a Dut to a test.
+    chromiumos.test.api.DutAttributeList tag = 3;
+    // Pools are just arbitrary groupings of Duts useful for test scheduling.
+    // for example allowing a lab to split half the devices for one particular
+    // test suite and the rest for a different.
+    // Pools are really just arbitrary strings and could be in the tags field,
+    // but for better user administration of pools it is better to keep them
+    // separate.
+    repeated Pool pool = 4;
+    // Tags that detail if a Dut has a particular periheral or not, example
+    // servo.   These again are kept separate from generic tags for ease of
+    // administration.
+    chromiumos.test.api.DutAttributeList peripheral = 5;  // Labels that users configure for servo etc.
+    chromiumos.config.api.MfgConfigId mfg_config_id = 6 ;
+    chromiumos.StoragePath provisioned_build = 7 ; // provision_service.proto
+    ManagedState state = 8 ;
+    Lock lock = 9;  // A lock can be in any state, so it is a separate field.
+    string operator_notes = 10;  // Lock reason or any other free text information.
+    string provisioned_firmware_version = 11 ;  // Current Dut RW firmware.
+    repeated HistoryRecord history = 12 ;   // State changes over time.
+     // DUT's that are associated ( close by ) this DUT, the string should be a network identifier and
+     // the DUT should be known to the DUT Manager.
+     // Schedulers that wish to give the assoiciated Dut to a test must obtain a
+     // lease on that Dut.
+    repeated NetworkIdentifier associated_dut = 13;
+    bool is_associated_dut = 14;  // Associated DUT's should be excluded from general lease requests ?
+  }