// Copyright 2020 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.v1beta;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/osconfig/v1beta/patch_jobs.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
import "google/type/datetime.proto";
import "google/type/dayofweek.proto";
import "google/type/timeofday.proto";

option go_package = "cloud.google.com/go/osconfig/apiv1beta/osconfigpb;osconfigpb";
option java_outer_classname = "PatchDeployments";
option java_package = "com.google.cloud.osconfig.v1beta";

// Patch deployments are configurations that individual patch jobs use to
// complete a patch. These configurations include instance filter, package
// repository settings, and a schedule. For more information about creating and
// managing patch deployments, see [Scheduling patch
// jobs](https://cloud.google.com/compute/docs/os-patch-management/schedule-patch-jobs).
message PatchDeployment {
  option (google.api.resource) = {
    type: "osconfig.googleapis.com/PatchDeployment"
    pattern: "projects/{project}/patchDeployments/{patch_deployment}"
  };

  // Represents state of patch peployment.
  enum State {
    // The default value. This value is used if the state is omitted.
    STATE_UNSPECIFIED = 0;

    // Active value means that patch deployment generates Patch Jobs.
    ACTIVE = 1;

    // Paused value means that patch deployment does not generate
    // Patch jobs. Requires user action to move in and out from this state.
    PAUSED = 2;
  }

  // Unique name for the patch deployment resource in a project. The patch
  // deployment name is in the form:
  // `projects/{project_id}/patchDeployments/{patch_deployment_id}`.
  // This field is ignored when you create a new patch deployment.
  string name = 1;

  // Optional. Description of the patch deployment. Length of the description is limited
  // to 1024 characters.
  string description = 2 [(google.api.field_behavior) = OPTIONAL];

  // Required. VM instances to patch.
  PatchInstanceFilter instance_filter = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. Patch configuration that is applied.
  PatchConfig patch_config = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Duration of the patch. After the duration ends, the patch times out.
  google.protobuf.Duration duration = 5 [(google.api.field_behavior) = OPTIONAL];

  // Schedule for the patch.
  oneof schedule {
    // Required. Schedule a one-time execution.
    OneTimeSchedule one_time_schedule = 6 [(google.api.field_behavior) = REQUIRED];

    // Required. Schedule recurring executions.
    RecurringSchedule recurring_schedule = 7 [(google.api.field_behavior) = REQUIRED];
  }

  // Output only. Time the patch deployment was created. Timestamp is in
  // [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format.
  google.protobuf.Timestamp create_time = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time the patch deployment was last updated. Timestamp is in
  // [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format.
  google.protobuf.Timestamp update_time = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The last time a patch job was started by this deployment.
  // Timestamp is in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text
  // format.
  google.protobuf.Timestamp last_execute_time = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Rollout strategy of the patch job.
  PatchRollout rollout = 11 [(google.api.field_behavior) = OPTIONAL];

  // Output only. Current state of the patch deployment.
  State state = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Sets the time for a one time patch deployment. Timestamp is in
// [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format.
message OneTimeSchedule {
  // Required. The desired patch job execution time.
  google.protobuf.Timestamp execute_time = 1 [(google.api.field_behavior) = REQUIRED];
}

// Sets the time for recurring patch deployments.
message RecurringSchedule {
  // Specifies the frequency of the recurring patch deployments.
  enum Frequency {
    // Invalid. A frequency must be specified.
    FREQUENCY_UNSPECIFIED = 0;

    // Indicates that the frequency of recurrence should be expressed in terms
    // of weeks.
    WEEKLY = 1;

    // Indicates that the frequency of recurrence should be expressed in terms
    // of months.
    MONTHLY = 2;

    // Indicates that the frequency of recurrence should be expressed in terms
    // of days.
    DAILY = 3;
  }

  // Required. Defines the time zone that `time_of_day` is relative to.
  // The rules for daylight saving time are determined by the chosen time zone.
  google.type.TimeZone time_zone = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The time that the recurring schedule becomes effective.
  // Defaults to `create_time` of the patch deployment.
  google.protobuf.Timestamp start_time = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The end time at which a recurring patch deployment schedule is no longer
  // active.
  google.protobuf.Timestamp end_time = 3 [(google.api.field_behavior) = OPTIONAL];

  // Required. Time of the day to run a recurring deployment.
  google.type.TimeOfDay time_of_day = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. The frequency unit of this recurring schedule.
  Frequency frequency = 5 [(google.api.field_behavior) = REQUIRED];

  // Configurations for this recurring schedule.
  // Configurations must match frequency.
  oneof schedule_config {
    // Required. Schedule with weekly executions.
    WeeklySchedule weekly = 6 [(google.api.field_behavior) = REQUIRED];

    // Required. Schedule with monthly executions.
    MonthlySchedule monthly = 7 [(google.api.field_behavior) = REQUIRED];
  }

  // Output only. The time the last patch job ran successfully.
  google.protobuf.Timestamp last_execute_time = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time the next patch job is scheduled to run.
  google.protobuf.Timestamp next_execute_time = 10 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Represents a weekly schedule.
message WeeklySchedule {
  // Required. Day of the week.
  google.type.DayOfWeek day_of_week = 1 [(google.api.field_behavior) = REQUIRED];
}

// Represents a monthly schedule. An example of a valid monthly schedule is
// "on the third Tuesday of the month" or "on the 15th of the month".
message MonthlySchedule {
  // One day in a month.
  oneof day_of_month {
    // Required. Week day in a month.
    WeekDayOfMonth week_day_of_month = 1 [(google.api.field_behavior) = REQUIRED];

    // Required. One day of the month. 1-31 indicates the 1st to the 31st day. -1
    // indicates the last day of the month.
    // Months without the target day will be skipped. For example, a schedule to
    // run "every month on the 31st" will not run in February, April, June, etc.
    int32 month_day = 2 [(google.api.field_behavior) = REQUIRED];
  }
}

// Represents one week day in a month. An example is "the 4th Sunday".
message WeekDayOfMonth {
  // Required. Week number in a month. 1-4 indicates the 1st to 4th week of the month. -1
  // indicates the last week of the month.
  int32 week_ordinal = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. A day of the week.
  google.type.DayOfWeek day_of_week = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. Represents the number of days before or after the given week day of month
  // that the patch deployment is scheduled for. For example if `week_ordinal`
  // and `day_of_week` values point to the second day of the month and this
  // `day_offset` value is set to `3`, the patch deployment takes place three
  // days after the second Tuesday of the month. If this value is negative, for
  // example -5, the patches  are deployed five days before before the second
  // Tuesday of the month. Allowed values are in range `[-30, 30]`.
  int32 day_offset = 3 [(google.api.field_behavior) = OPTIONAL];
}

// A request message for creating a patch deployment.
message CreatePatchDeploymentRequest {
  // Required. The project to apply this patch deployment to in the form `projects/*`.
  string parent = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. A name for the patch deployment in the project. When creating a name
  // the following rules apply:
  // * 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 patch_deployment_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The patch deployment to create.
  PatchDeployment patch_deployment = 3 [(google.api.field_behavior) = REQUIRED];
}

// A request message for retrieving a patch deployment.
message GetPatchDeploymentRequest {
  // Required. The resource name of the patch deployment in the form
  // `projects/*/patchDeployments/*`.
  string name = 1 [(google.api.field_behavior) = REQUIRED];
}

// A request message for listing patch deployments.
message ListPatchDeploymentsRequest {
  // Required. The resource name of the parent in the form `projects/*`.
  string parent = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The maximum number of patch deployments to return. Default is 100.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A pagination token returned from a previous call to ListPatchDeployments
  // that indicates where this listing should continue from.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// A response message for listing patch deployments.
message ListPatchDeploymentsResponse {
  // The list of patch deployments.
  repeated PatchDeployment patch_deployments = 1;

  // A pagination token that can be used to get the next page of patch
  // deployments.
  string next_page_token = 2;
}

// A request message for deleting a patch deployment.
message DeletePatchDeploymentRequest {
  // Required. The resource name of the patch deployment in the form
  // `projects/*/patchDeployments/*`.
  string name = 1 [(google.api.field_behavior) = REQUIRED];
}

// A request message for updating a patch deployment.
message UpdatePatchDeploymentRequest {
  // Required. The patch deployment to Update.
  PatchDeployment patch_deployment = 1 [(google.api.field_behavior) = REQUIRED];

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

// A request message for pausing a patch deployment.
message PausePatchDeploymentRequest {
  // Required. The resource name of the patch deployment in the form
  // `projects/*/patchDeployments/*`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "osconfig.googleapis.com/PatchDeployment"
    }
  ];
}

// A request message for resuming a patch deployment.
message ResumePatchDeploymentRequest {
  // Required. The resource name of the patch deployment in the form
  // `projects/*/patchDeployments/*`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "osconfig.googleapis.com/PatchDeployment"
    }
  ];
}
