// Copyright 2021 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.osconfig.v1alpha;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/osconfig/v1alpha/os_policy.proto";
import "google/cloud/osconfig/v1alpha/osconfig_common.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.OsConfig.V1Alpha";
option go_package = "google.golang.org/genproto/googleapis/cloud/osconfig/v1alpha;osconfig";
option java_multiple_files = true;
option java_outer_classname = "OSPolicyAssignments";
option java_package = "com.google.cloud.osconfig.v1alpha";
option php_namespace = "Google\\Cloud\\OsConfig\\V1alpha";
option ruby_package = "Google::Cloud::OsConfig::V1alpha";

// OS policy assignment is an API resource that is used to
// apply a set of OS policies to a dynamically targeted group of Compute Engine
// VM instances.
//
// An OS policy is used to define the desired state configuration for a
// Compute Engine VM instance through a set of configuration resources that
// provide capabilities such as installing or removing software packages, or
// executing a script.
//
// For more information, see [OS policy and OS policy
// assignment](https://cloud.google.com/compute/docs/os-configuration-management/working-with-os-policies).
message OSPolicyAssignment {
  option (google.api.resource) = {
    type: "osconfig.googleapis.com/OSPolicyAssignment"
    pattern: "projects/{project}/locations/{location}/osPolicyAssignments/{os_policy_assignment}"
  };

  // Message representing label set.
  // * A label is a key value pair set for a VM.
  // * A LabelSet is a set of labels.
  // * Labels within a LabelSet are ANDed. In other words, a LabelSet is
  //   applicable for a VM only if it matches all the labels in the
  //   LabelSet.
  // * Example: A LabelSet with 2 labels: `env=prod` and `type=webserver` will
  //            only be applicable for those VMs with both labels
  //            present.
  message LabelSet {
    // Labels are identified by key/value pairs in this map.
    // A VM should contain all the key/value pairs specified in this
    // map to be selected.
    map<string, string> labels = 1;
  }

  // Message to represent the filters to select VMs for an assignment
  message InstanceFilter {
    // Target all VMs in the project. If true, no other criteria is
    // permitted.
    bool all = 1;

    // A VM is included if it's OS short name matches with any of the
    // values provided in this list.
    repeated string os_short_names = 2;

    // List of label sets used for VM inclusion.
    //
    // If the list has more than one `LabelSet`, the VM is included if any
    // of the label sets are applicable for the VM.
    repeated LabelSet inclusion_labels = 3;

    // List of label sets used for VM exclusion.
    //
    // If the list has more than one label set, the VM is excluded if any
    // of the label sets are applicable for the VM.
    //
    // This filter is applied last in the filtering chain and therefore a
    // VM is guaranteed to be excluded if it satisfies one of the below
    // label sets.
    repeated LabelSet exclusion_labels = 4;
  }

  // Message to configure the rollout at the zonal level for the OS policy
  // assignment.
  message Rollout {
    // Required. The maximum number (or percentage) of VMs per zone to disrupt at
    // any given moment.
    FixedOrPercent disruption_budget = 1 [(google.api.field_behavior) = REQUIRED];

    // Required. This determines the minimum duration of time to wait after the
    // configuration changes are applied through the current rollout. A
    // VM continues to count towards the `disruption_budget` at least
    // until this duration of time has passed after configuration changes are
    // applied.
    google.protobuf.Duration min_wait_duration = 2 [(google.api.field_behavior) = REQUIRED];
  }

  // OS policy assignment rollout state
  enum RolloutState {
    // Invalid value
    ROLLOUT_STATE_UNSPECIFIED = 0;

    // The rollout is in progress.
    IN_PROGRESS = 1;

    // The rollout is being cancelled.
    CANCELLING = 2;

    // The rollout is cancelled.
    CANCELLED = 3;

    // The rollout has completed successfully.
    SUCCEEDED = 4;
  }

  // Resource name.
  //
  // Format:
  // `projects/{project_number}/locations/{location}/osPolicyAssignments/{os_policy_assignment_id}`
  //
  // This field is ignored when you create an OS policy assignment.
  string name = 1;

  // OS policy assignment description.
  // Length of the description is limited to 1024 characters.
  string description = 2;

  // Required. List of OS policies to be applied to the VMs.
  repeated OSPolicy os_policies = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. Filter to select VMs.
  InstanceFilter instance_filter = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. Rollout to deploy the OS policy assignment.
  // A rollout is triggered in the following situations:
  // 1) OSPolicyAssignment is created.
  // 2) OSPolicyAssignment is updated and the update contains changes to one of
  // the following fields:
  //    - instance_filter
  //    - os_policies
  // 3) OSPolicyAssignment is deleted.
  Rollout rollout = 5 [(google.api.field_behavior) = REQUIRED];

  // Output only. The assignment revision ID
  // A new revision is committed whenever a rollout is triggered for a OS policy
  // assignment
  string revision_id = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp that the revision was created.
  google.protobuf.Timestamp revision_create_time = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. OS policy assignment rollout state
  RolloutState rollout_state = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Indicates that this revision has been successfully rolled out in this zone
  // and new VMs will be assigned OS policies from this revision.
  //
  // For a given OS policy assignment, there is only one revision with a value
  // of `true` for this field.
  bool baseline = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Indicates that this revision deletes the OS policy assignment.
  bool deleted = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Indicates that reconciliation is in progress for the revision.
  // This value is `true` when the `rollout_state` is one of:
  // * IN_PROGRESS
  // * CANCELLING
  bool reconciling = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Server generated unique id for the OS policy assignment resource.
  string uid = 13 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// OS policy assignment operation metadata provided by OS policy assignment API
// methods that return long running operations.
message OSPolicyAssignmentOperationMetadata {
  // The OS policy assignment API method.
  enum APIMethod {
    // Invalid value
    API_METHOD_UNSPECIFIED = 0;

    // Create OS policy assignment API method
    CREATE = 1;

    // Update OS policy assignment API method
    UPDATE = 2;

    // Delete OS policy assignment API method
    DELETE = 3;
  }

  // State of the rollout
  enum RolloutState {
    // Invalid value
    ROLLOUT_STATE_UNSPECIFIED = 0;

    // The rollout is in progress.
    IN_PROGRESS = 1;

    // The rollout is being cancelled.
    CANCELLING = 2;

    // The rollout is cancelled.
    CANCELLED = 3;

    // The rollout has completed successfully.
    SUCCEEDED = 4;
  }

  // Reference to the `OSPolicyAssignment` API resource.
  //
  // Format:
  // `projects/{project_number}/locations/{location}/osPolicyAssignments/{os_policy_assignment_id@revision_id}`
  string os_policy_assignment = 1 [(google.api.resource_reference) = {
                                     type: "osconfig.googleapis.com/OSPolicyAssignment"
                                   }];

  // The OS policy assignment API method.
  APIMethod api_method = 2;

  // State of the rollout
  RolloutState rollout_state = 3;

  // Rollout start time
  google.protobuf.Timestamp rollout_start_time = 4;

  // Rollout update time
  google.protobuf.Timestamp rollout_update_time = 5;
}

// A request message to create an OS policy assignment
message CreateOSPolicyAssignmentRequest {
  // Required. The parent resource name in the form:
  // projects/{project}/locations/{location}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. The OS policy assignment to be created.
  OSPolicyAssignment os_policy_assignment = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The logical name of the OS policy assignment in the project
  // with the following restrictions:
  //
  // * Must contain only lowercase letters, numbers, and hyphens.
  // * Must start with a letter.
  // * Must be between 1-63 characters.
  // * Must end with a number or a letter.
  // * Must be unique within the project.
  string os_policy_assignment_id = 3 [(google.api.field_behavior) = REQUIRED];
}

// A request message to update an OS policy assignment
message UpdateOSPolicyAssignmentRequest {
  // Required. The updated OS policy assignment.
  OSPolicyAssignment os_policy_assignment = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Field mask that controls which fields of the assignment should be updated.
  google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL];
}

// A request message to get an OS policy assignment
message GetOSPolicyAssignmentRequest {
  // Required. The resource name of OS policy assignment.
  //
  // Format:
  // `projects/{project}/locations/{location}/osPolicyAssignments/{os_policy_assignment}@{revisionId}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "osconfig.googleapis.com/OSPolicyAssignment"
    }
  ];
}

// A request message to list OS policy assignments for a parent resource
message ListOSPolicyAssignmentsRequest {
  // Required. The parent resource name.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // The maximum number of assignments to return.
  int32 page_size = 2;

  // A pagination token returned from a previous call to
  // `ListOSPolicyAssignments` that indicates where this listing should continue
  // from.
  string page_token = 3;
}

// A response message for listing all assignments under given parent.
message ListOSPolicyAssignmentsResponse {
  // The list of assignments
  repeated OSPolicyAssignment os_policy_assignments = 1;

  // The pagination token to retrieve the next page of OS policy assignments.
  string next_page_token = 2;
}

// A request message to list revisions for a OS policy assignment
message ListOSPolicyAssignmentRevisionsRequest {
  // Required. The name of the OS policy assignment to list revisions for.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "osconfig.googleapis.com/OSPolicyAssignment"
    }
  ];

  // The maximum number of revisions to return.
  int32 page_size = 2;

  // A pagination token returned from a previous call to
  // `ListOSPolicyAssignmentRevisions` that indicates where this listing should
  // continue from.
  string page_token = 3;
}

// A response message for listing all revisions for a OS policy assignment.
message ListOSPolicyAssignmentRevisionsResponse {
  // The OS policy assignment revisions
  repeated OSPolicyAssignment os_policy_assignments = 1;

  // The pagination token to retrieve the next page of OS policy assignment
  // revisions.
  string next_page_token = 2;
}

// A request message for deleting a OS policy assignment.
message DeleteOSPolicyAssignmentRequest {
  // Required. The name of the OS policy assignment to be deleted
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "osconfig.googleapis.com/OSPolicyAssignment"
    }
  ];
}
