// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.cloud.baremetalsolution.v2;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/baremetalsolution/v2/common.proto";
import "google/cloud/baremetalsolution/v2/network.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.BareMetalSolution.V2";
option go_package = "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb;baremetalsolutionpb";
option java_multiple_files = true;
option java_outer_classname = "ProvisioningProto";
option java_package = "com.google.cloud.baremetalsolution.v2";
option php_namespace = "Google\\Cloud\\BareMetalSolution\\V2";
option ruby_package = "Google::Cloud::BareMetalSolution::V2";

// A provisioning configuration.
message ProvisioningConfig {
  option (google.api.resource) = {
    type: "baremetalsolution.googleapis.com/ProvisioningConfig"
    pattern: "projects/{project}/locations/{location}/provisioningConfigs/{provisioning_config}"
  };

  // The possible states for this ProvisioningConfig.
  enum State {
    // State wasn't specified.
    STATE_UNSPECIFIED = 0;

    // ProvisioningConfig is a draft and can be freely modified.
    DRAFT = 1;

    // ProvisioningConfig was already submitted and cannot be modified.
    SUBMITTED = 2;

    // ProvisioningConfig was in the provisioning state.  Initially this state
    // comes from the work order table in big query when SNOW is used.  Later
    // this field can be set by the work order API.
    PROVISIONING = 3;

    // ProvisioningConfig was provisioned, meaning the resources exist.
    PROVISIONED = 4;

    // ProvisioningConfig was validated.  A validation tool will be run to
    // set this state.
    VALIDATED = 5;

    // ProvisioningConfig was canceled.
    CANCELLED = 6;

    // The request is submitted for provisioning, with error return.
    FAILED = 7;
  }

  // Output only. The system-generated name of the provisioning config. This
  // follows the UUID format.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Instances to be created.
  repeated InstanceConfig instances = 2;

  // Networks to be created.
  repeated NetworkConfig networks = 3;

  // Volumes to be created.
  repeated VolumeConfig volumes = 4;

  // A generated ticket id to track provisioning request.
  string ticket_id = 5;

  // A service account to enable customers to access instance credentials upon
  // handover.
  string handover_service_account = 6;

  // Email provided to send a confirmation with provisioning config to.
  // Deprecated in favour of email field in request messages.
  string email = 7 [deprecated = true];

  // Output only. State of ProvisioningConfig.
  State state = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Location name of this ProvisioningConfig.
  // It is optional only for Intake UI transition period.
  string location = 9 [(google.api.field_behavior) = OPTIONAL];

  // Output only. Last update timestamp.
  google.protobuf.Timestamp update_time = 10
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. URI to Cloud Console UI view of this provisioning config.
  string cloud_console_uri = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // If true, VPC SC is enabled for the cluster.
  bool vpc_sc_enabled = 12;

  // Optional status messages associated with the FAILED state.
  string status_message = 13;

  // Optional. The user-defined identifier of the provisioning config.
  string custom_id = 14 [(google.api.field_behavior) = OPTIONAL];
}

// Request for SubmitProvisioningConfig.
message SubmitProvisioningConfigRequest {
  // Required. The parent project and location containing the
  // ProvisioningConfig.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. The ProvisioningConfig to create.
  ProvisioningConfig provisioning_config = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Email provided to send a confirmation with provisioning config
  // to.
  string email = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response for SubmitProvisioningConfig.
message SubmitProvisioningConfigResponse {
  // The submitted provisioning config.
  ProvisioningConfig provisioning_config = 1;
}

// A provisioning quota for a given project.
message ProvisioningQuota {
  option (google.api.resource) = {
    type: "baremetalsolution.googleapis.com/ProvisioningQuota"
    pattern: "projects/{project}/locations/{location}/provisioningQuotas/{provisioning_quota}"
  };

  // The available asset types for intake.
  enum AssetType {
    // The unspecified type.
    ASSET_TYPE_UNSPECIFIED = 0;

    // The server asset type.
    ASSET_TYPE_SERVER = 1;

    // The storage asset type.
    ASSET_TYPE_STORAGE = 2;

    // The network asset type.
    ASSET_TYPE_NETWORK = 3;
  }

  // Output only. The name of the provisioning quota.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The asset type of this provisioning quota.
  AssetType asset_type = 2;

  // The gcp service of the provisioning quota.
  string gcp_service = 3;

  // The specific location of the provisioining quota.
  string location = 4;

  // The available count of the provisioning quota.
  int32 available_count = 5;

  // The quota of one asset type.
  oneof quota {
    // Instance quota.
    InstanceQuota instance_quota = 6;
  }

  // Available quantity based on asset type.
  oneof availability {
    // Server count.
    int64 server_count = 7;

    // Network bandwidth, Gbps
    int64 network_bandwidth = 8;

    // Storage size (GB).
    int64 storage_gib = 9;
  }
}

// Message for requesting the list of provisioning quotas.
message ListProvisioningQuotasRequest {
  // Required. Parent value for ListProvisioningQuotasRequest.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Requested page size. The server might return fewer items than requested.
  // If unspecified, server will pick an appropriate default.
  // Notice that page_size field is not supported and won't be respected in
  // the API request for now, will be updated when pagination is supported.
  int32 page_size = 2;

  // A token identifying a page of results from the server.
  string page_token = 3;
}

// Response message for the list of provisioning quotas.
message ListProvisioningQuotasResponse {
  // The provisioning quotas registered in this project.
  repeated ProvisioningQuota provisioning_quotas = 1;

  // Token to retrieve the next page of results, or empty if there are no more
  // results in the list.
  string next_page_token = 2;
}

// Configuration parameters for a new instance.
message InstanceConfig {
  option (google.api.resource) = {
    type: "baremetalsolution.googleapis.com/InstanceConfig"
    pattern: "projects/{project}/locations/{location}/instanceConfigs/{instance_config}"
  };

  // A network.
  message NetworkAddress {
    // Id of the network to use, within the same ProvisioningConfig request.
    string network_id = 1;

    // IPv4 address to be assigned to the server.
    string address = 2;

    // Name of the existing network to use.
    string existing_network_id = 3;
  }

  // The network configuration of the instance.
  enum NetworkConfig {
    // The unspecified network configuration.
    NETWORKCONFIG_UNSPECIFIED = 0;

    // Instance part of single client network and single private network.
    SINGLE_VLAN = 1;

    // Instance part of multiple (or single) client networks and private
    // networks.
    MULTI_VLAN = 2;
  }

  // Output only. The name of the instance config.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // A transient unique identifier to idenfity an instance within an
  // ProvisioningConfig request.
  string id = 2;

  // Instance type.
  // [Available
  // types](https://cloud.google.com/bare-metal/docs/bms-planning#server_configurations)
  string instance_type = 3;

  // Whether the instance should be provisioned with Hyperthreading enabled.
  bool hyperthreading = 4;

  // OS image to initialize the instance.
  // [Available
  // images](https://cloud.google.com/bare-metal/docs/bms-planning#server_configurations)
  string os_image = 5;

  // Client network address. Filled if InstanceConfig.multivlan_config is false.
  NetworkAddress client_network = 6 [deprecated = true];

  // Private network address, if any. Filled if InstanceConfig.multivlan_config
  // is false.
  NetworkAddress private_network = 7 [deprecated = true];

  // User note field, it can be used by customers to add additional information
  // for the BMS Ops team .
  string user_note = 8;

  // If true networks can be from different projects of the same vendor account.
  bool account_networks_enabled = 9;

  // The type of network configuration on the instance.
  NetworkConfig network_config = 10;

  // Server network template name. Filled if InstanceConfig.multivlan_config is
  // true.
  string network_template = 11;

  // List of logical interfaces for the instance. The number of logical
  // interfaces will be the same as number of hardware bond/nic on the chosen
  // network template. Filled if InstanceConfig.multivlan_config is true.
  repeated LogicalInterface logical_interfaces = 12;

  // List of names of ssh keys used to provision the instance.
  repeated string ssh_key_names = 13;
}

// Configuration parameters for a new volume.
message VolumeConfig {
  option (google.api.resource) = {
    type: "baremetalsolution.googleapis.com/VolumeConfig"
    pattern: "projects/{project}/locations/{location}/volumeConfigs/{volume_config}"
  };

  // The types of Volumes.
  enum Type {
    // The unspecified type.
    TYPE_UNSPECIFIED = 0;

    // This Volume is on flash.
    FLASH = 1;

    // This Volume is on disk.
    DISK = 2;
  }

  // The protocol used to access the volume.
  enum Protocol {
    // Unspecified value.
    PROTOCOL_UNSPECIFIED = 0;

    // Fibre channel.
    PROTOCOL_FC = 1;

    // Network file system.
    PROTOCOL_NFS = 2;
  }

  // A LUN(Logical Unit Number) range.
  message LunRange {
    // Number of LUNs to create.
    int32 quantity = 1;

    // The requested size of each LUN, in GB.
    int32 size_gb = 2;
  }

  // A NFS export entry.
  message NfsExport {
    // Permissions that can granted for an export.
    enum Permissions {
      // Unspecified value.
      PERMISSIONS_UNSPECIFIED = 0;

      // Read-only permission.
      READ_ONLY = 1;

      // Read-write permission.
      READ_WRITE = 2;
    }

    // Network to use to publish the export.
    string network_id = 1;

    // A client object.
    oneof client {
      // Either a single machine, identified by an ID, or a comma-separated
      // list of machine IDs.
      string machine_id = 2;

      // A CIDR range.
      string cidr = 3;
    }

    // Export permissions.
    Permissions permissions = 4;

    // Disable root squashing, which is a feature of NFS.
    // Root squash is a special mapping of the remote superuser (root) identity
    // when using identity authentication.
    bool no_root_squash = 5;

    // Allow the setuid flag.
    bool allow_suid = 6;

    // Allow dev flag in NfsShare AllowedClientsRequest.
    bool allow_dev = 7;
  }

  // Output only. The name of the volume config.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // A transient unique identifier to identify a volume within an
  // ProvisioningConfig request.
  string id = 2;

  // Whether snapshots should be enabled.
  bool snapshots_enabled = 3;

  // The type of this Volume.
  Type type = 4;

  // Volume protocol.
  Protocol protocol = 5;

  // The requested size of this volume, in GB.
  int32 size_gb = 6;

  // LUN ranges to be configured. Set only when protocol is PROTOCOL_FC.
  repeated LunRange lun_ranges = 7;

  // Machine ids connected to this volume. Set only when protocol is
  // PROTOCOL_FC.
  repeated string machine_ids = 8;

  // NFS exports. Set only when protocol is PROTOCOL_NFS.
  repeated NfsExport nfs_exports = 9;

  // User note field, it can be used by customers to add additional information
  // for the BMS Ops team .
  string user_note = 10;

  // The GCP service of the storage volume. Available gcp_service are in
  // https://cloud.google.com/bare-metal/docs/bms-planning.
  string gcp_service = 11;

  // Performance tier of the Volume.
  // Default is SHARED.
  VolumePerformanceTier performance_tier = 12;
}

// Configuration parameters for a new network.
message NetworkConfig {
  option (google.api.resource) = {
    type: "baremetalsolution.googleapis.com/NetworkConfig"
    pattern: "projects/{project}/locations/{location}/networkConfigs/{network_config}"
  };

  // Network type.
  enum Type {
    // Unspecified value.
    TYPE_UNSPECIFIED = 0;

    // Client network, that is a network peered to a GCP VPC.
    CLIENT = 1;

    // Private network, that is a network local to the BMS POD.
    PRIVATE = 2;
  }

  // Interconnect bandwidth.
  enum Bandwidth {
    // Unspecified value.
    BANDWIDTH_UNSPECIFIED = 0;

    // 1 Gbps.
    BW_1_GBPS = 1;

    // 2 Gbps.
    BW_2_GBPS = 2;

    // 5 Gbps.
    BW_5_GBPS = 3;

    // 10 Gbps.
    BW_10_GBPS = 4;
  }

  // A GCP vlan attachment.
  message IntakeVlanAttachment {
    // Identifier of the VLAN attachment.
    string id = 1;

    // Attachment pairing key.
    string pairing_key = 2;
  }

  // Service network block.
  enum ServiceCidr {
    // Unspecified value.
    SERVICE_CIDR_UNSPECIFIED = 0;

    // Services are disabled for the given network.
    DISABLED = 1;

    // Use the highest /26 block of the network to host services.
    HIGH_26 = 2;

    // Use the highest /27 block of the network to host services.
    HIGH_27 = 3;

    // Use the highest /28 block of the network to host services.
    HIGH_28 = 4;
  }

  // Output only. The name of the network config.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // A transient unique identifier to identify a volume within an
  // ProvisioningConfig request.
  string id = 2;

  // The type of this network, either Client or Private.
  Type type = 3;

  // Interconnect bandwidth. Set only when type is CLIENT.
  Bandwidth bandwidth = 4;

  // List of VLAN attachments. As of now there are always 2 attachments, but it
  // is going to change in  the future (multi vlan).
  repeated IntakeVlanAttachment vlan_attachments = 5;

  // CIDR range of the network.
  string cidr = 6;

  // Service CIDR, if any.
  ServiceCidr service_cidr = 7;

  // User note field, it can be used by customers to add additional information
  // for the BMS Ops team .
  string user_note = 8;

  // The GCP service of the network. Available gcp_service are in
  // https://cloud.google.com/bare-metal/docs/bms-planning.
  string gcp_service = 9;

  // Whether the VLAN attachment pair is located in the same project.
  bool vlan_same_project = 10;

  // The JumboFramesEnabled option for customer to set.
  bool jumbo_frames_enabled = 11;
}

// A resource budget.
message InstanceQuota {
  option (google.api.resource) = {
    type: "baremetalsolution.googleapis.com/InstanceQuota"
    pattern: "projects/{project}/locations/{location}/instanceQuotas/{instance_quota}"
  };

  // Output only. The name of the instance quota.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Instance type.
  // Deprecated: use gcp_service.
  string instance_type = 2 [deprecated = true];

  // The gcp service of the provisioning quota.
  string gcp_service = 5;

  // Location where the quota applies.
  string location = 3;

  // Number of machines than can be created for the given location and
  // instance_type.
  int32 available_machine_count = 4;
}

// Request for GetProvisioningConfig.
message GetProvisioningConfigRequest {
  // Required. Name of the ProvisioningConfig.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "baremetalsolution.googleapis.com/ProvisioningConfig"
    }
  ];
}

// Request for CreateProvisioningConfig.
message CreateProvisioningConfigRequest {
  // Required. The parent project and location containing the
  // ProvisioningConfig.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. The ProvisioningConfig to create.
  ProvisioningConfig provisioning_config = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Email provided to send a confirmation with provisioning config
  // to.
  string email = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Message for updating a ProvisioningConfig.
message UpdateProvisioningConfigRequest {
  // Required. The ProvisioningConfig to update.
  ProvisioningConfig provisioning_config = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The list of fields to update.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Email provided to send a confirmation with provisioning config
  // to.
  string email = 3 [(google.api.field_behavior) = OPTIONAL];
}
