// Copyright 2016-2018, Pulumi Corporation.
//
// 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";

import "plugin.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/struct.proto";

package pulumirpc;

// ResourceProvider is a service that understands how to create, read, update, or delete resources for types defined
// within a single package.  It is driven by the overall planning engine in response to resource diffs.
service ResourceProvider {
    // Configure configures the resource provider with "globals" that control its behavior.
    rpc Configure(ConfigureRequest) returns (google.protobuf.Empty) {}
    // Invoke dynamically executes a built-in function in the provider.
    rpc Invoke(InvokeRequest) returns (InvokeResponse) {}
    // Check validates that the given property bag is valid for a resource of the given type and returns the inputs
    // that should be passed to successive calls to Diff, Create, or Update for this resource. As a rule, the provider
    // inputs returned by a call to Check should preserve the original representation of the properties as present in
    // the program inputs. Though this rule is not required for correctness, violations thereof can negatively impact
    // the end-user experience, as the provider inputs are using for detecting and rendering diffs.
    rpc Check(CheckRequest) returns (CheckResponse) {}
    // Diff checks what impacts a hypothetical update will have on the resource's properties.
    rpc Diff(DiffRequest) returns (DiffResponse) {}
    // Create allocates a new instance of the provided resource and returns its unique ID afterwards.  (The input ID
    // must be blank.)  If this call fails, the resource must not have been created (i.e., it is "transacational").
    rpc Create(CreateRequest) returns (CreateResponse) {}
    // Read the current live state associated with a resource.  Enough state must be include in the inputs to uniquely
    // identify the resource; this is typically just the resource ID, but may also include some properties.
    rpc Read(ReadRequest) returns (ReadResponse) {}
    // Update updates an existing resource with new values.
    rpc Update(UpdateRequest) returns (UpdateResponse) {}
    // Delete tears down an existing resource with the given ID.  If it fails, the resource is assumed to still exist.
    rpc Delete(DeleteRequest) returns (google.protobuf.Empty) {}
    // Cancel signals the provider to abort all outstanding resource operations.
    rpc Cancel(google.protobuf.Empty) returns (google.protobuf.Empty) {}
    // GetPluginInfo returns generic information about this plugin, like its version.
    rpc GetPluginInfo(google.protobuf.Empty) returns (PluginInfo) {}
}

message ConfigureRequest {
    map<string, string> variables = 1; // a map of configuration keys to values.
}

// ConfigureErrorMissingKeys is sent as a Detail on an error returned from `ResourceProvider.Configure`.
message ConfigureErrorMissingKeys {
    message MissingKey {
        string name = 1;        // the Pulumi name (not the provider name!) of the missing config key.
        string description = 2; // a description of the missing config key, as reported by the provider.
    }

    repeated MissingKey missingKeys = 1; // a list of required configuration keys that were not supplied.
}

message InvokeRequest {
    string tok = 1;                  // the function token to invoke.
    google.protobuf.Struct args = 2; // the arguments for the function invocation.
    string provider = 3;             // an optional reference to the provider to use for this invoke.
}

message InvokeResponse {
    google.protobuf.Struct return = 1;  // the returned values, if invoke was successful.
    repeated CheckFailure failures = 2; // the failures if any arguments didn't pass verification.
}

message CheckRequest {
    string urn = 1;                  // the Pulumi URN for this resource.
    google.protobuf.Struct olds = 2; // the old Pulumi inputs for this resource, if any.
    google.protobuf.Struct news = 3; // the new Pulumi inputs for this resource.
}

message CheckResponse {
    google.protobuf.Struct inputs = 1;  // the provider inputs for this resource.
    repeated CheckFailure failures = 2; // any validation failures that occurred.
}

message CheckFailure {
    string property = 1; // the property that failed validation.
    string reason = 2;   // the reason that the property failed validation.
}

message DiffRequest {
    string id = 1;                   // the ID of the resource to diff.
    string urn = 2;                  // the Pulumi URN for this resource.
    google.protobuf.Struct olds = 3; // the old values of provider inputs to diff.
    google.protobuf.Struct news = 4; // the new values of provider inputs to diff.
}

message DiffResponse {
    repeated string replaces = 1; // if this update requires a replacement, the set of properties triggering it.
    repeated string stables = 2;  // an optional list of properties that will not ever change.
    bool deleteBeforeReplace = 3; // if true, this resource must be deleted before replacing it.
    DiffChanges changes = 4;   // if true, this diff represents an actual difference and thus requires an update.

    enum DiffChanges {
        DIFF_UNKNOWN = 0; // unknown whether there are changes or not (legacy behavior).
        DIFF_NONE    = 1; // the diff was performed, and no changes were detected that require an update.
        DIFF_SOME    = 2; // the diff was performed, and changes were detected that require an update or replacement.
    }
}

message CreateRequest {
    string urn = 1;                        // the Pulumi URN for this resource.
    google.protobuf.Struct properties = 2; // the provider inputs to set during creation.
}

message CreateResponse {
    // NOTE: The partial-update-error equivalent of this message is `ErrorResourceInitFailed`.

    string id = 1;                         // the ID of the created resource.
    google.protobuf.Struct properties = 2; // any properties that were computed during creation.
}

message ReadRequest {
    string id = 1;                         // the ID of the resource to read.
    string urn = 2;                        // the Pulumi URN for this resource.
    google.protobuf.Struct properties = 3; // the current state (sufficiently complete to identify the resource).
}

message ReadResponse {
    string id = 1;                         // the ID of the resource read back (or empty if missing).
    google.protobuf.Struct properties = 2; // the state of the resource read from the live environment.
}

message UpdateRequest {
    // NOTE: The partial-update-error equivalent of this message is `ErrorResourceInitFailed`.

    string id = 1;                   // the ID of the resource to update.
    string urn = 2;                  // the Pulumi URN for this resource.
    google.protobuf.Struct olds = 3; // the old values of provider inputs for the resource to update.
    google.protobuf.Struct news = 4; // the new values of provider inputs for the resource to update.
}

message UpdateResponse {
    google.protobuf.Struct properties = 1; // any properties that were computed during updating.
}

message DeleteRequest {
    string id = 1;                         // the ID of the resource to delete.
    string urn = 2;                        // the Pulumi URN for this resource.
    google.protobuf.Struct properties = 3; // the current properties on the resource.
}

// ErrorResourceInitFailed is sent as a Detail `ResourceProvider.{Create, Update}` fail because a
// resource was created successfully, but failed to initialize.
message ErrorResourceInitFailed {
    string id = 1;                         // the ID of the created resource.
    google.protobuf.Struct properties = 2; // any properties that were computed during updating.
    repeated string reasons = 3;           // error messages associated with initialization failure.
}