001 /*
002 * SPDX-License-Identifier: Apache-2.0
003 *
004 * Copyright 2019-2022 Andres Almiray.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.kordamp.gradle.plugin.oci.tasks.instance
019
020 import com.oracle.bmc.core.ComputeClient
021 import com.oracle.bmc.core.model.Instance
022 import com.oracle.bmc.core.requests.GetInstanceRequest
023 import com.oracle.bmc.core.requests.InstanceActionRequest
024 import com.oracle.bmc.core.requests.ListInstancesRequest
025 import groovy.transform.CompileStatic
026 import org.gradle.api.provider.Property
027 import org.gradle.api.provider.Provider
028 import org.gradle.api.tasks.Input
029 import org.gradle.api.tasks.Internal
030 import org.gradle.api.tasks.options.Option
031 import org.gradle.api.tasks.options.OptionValues
032 import org.kordamp.gradle.plugin.oci.tasks.AbstractOCITask
033 import org.kordamp.gradle.plugin.oci.tasks.interfaces.OCITask
034 import org.kordamp.gradle.plugin.oci.tasks.traits.CompartmentIdAwareTrait
035 import org.kordamp.gradle.plugin.oci.tasks.traits.OptionalInstanceIdAwareTrait
036 import org.kordamp.gradle.plugin.oci.tasks.traits.OptionalInstanceNameAwareTrait
037 import org.kordamp.gradle.plugin.oci.tasks.traits.WaitForCompletionAwareTrait
038 import org.kordamp.jipsy.annotations.TypeProviderFor
039
040 import static org.kordamp.gradle.PropertyUtils.resolveValue
041 import static org.kordamp.gradle.util.StringUtils.isBlank
042 import static org.kordamp.gradle.util.StringUtils.isNotBlank
043
044 /**
045 * @author Andres Almiray
046 * @since 0.1.0
047 */
048 @CompileStatic
049 @TypeProviderFor(OCITask)
050 class InstanceActionTask extends AbstractOCITask implements CompartmentIdAwareTrait,
051 OptionalInstanceIdAwareTrait,
052 OptionalInstanceNameAwareTrait,
053 WaitForCompletionAwareTrait {
054 static final String TASK_DESCRIPTION = 'Performs a given action on an Instance.'
055
056 private static enum InstanceAction {
057 START(Instance.LifecycleState.Running),
058 STOP(Instance.LifecycleState.Stopped),
059 SOFTRESET(Instance.LifecycleState.Running),
060 SOFTSTOP(Instance.LifecycleState.Stopped),
061 RESET(Instance.LifecycleState.Running)
062
063 private Instance.LifecycleState state
064
065 InstanceAction(Instance.LifecycleState state) {
066 this.state = state
067 }
068
069 Instance.LifecycleState state() {
070 this.state
071 }
072 }
073
074 @Internal
075 final Property<InstanceAction> action = project.objects.property(InstanceAction)
076
077 @Option(option = 'action', description = 'The action to be executed (REQUIRED).')
078 void setAction(InstanceAction action) {
079 getAction().set(action)
080 }
081
082 @Input
083 Provider<InstanceAction> getResolvedAction() {
084 project.providers.provider {
085 String value = resolveValue('OCI_INSTANCE_ACTION', 'oci.instance.action', this, project.name)
086 isNotBlank(value) ? InstanceAction.valueOf(value) : action.getOrElse(InstanceAction.STOP)
087 }
088 }
089
090 @OptionValues("action")
091 List<InstanceAction> getAvailableActions() {
092 return new ArrayList<InstanceAction>(Arrays.asList(InstanceAction.values()))
093 }
094
095 @Override
096 protected void doExecuteTask() {
097 validateInstanceId()
098
099 if (isBlank(getResolvedInstanceId().orNull) && isBlank(getResolvedInstanceName().orNull)) {
100 throw new IllegalStateException("Missing value for either 'instanceId' or 'instanceName' in $path")
101 }
102 if (!getResolvedAction()) {
103 throw new IllegalStateException("Missing value for 'action' in $path")
104 }
105
106 ComputeClient client = createComputeClient()
107
108 if (isNotBlank(getResolvedInstanceId().orNull)) {
109 instanceAction(client, getResolvedInstanceId().get(), getResolvedAction().get())
110 } else {
111 validateCompartmentId()
112
113 client.listInstances(ListInstancesRequest.builder()
114 .compartmentId(getResolvedCompartmentId().get())
115 .displayName(getResolvedInstanceName().get())
116 .build())
117 .items.each { instance ->
118 setInstanceId(instance.id)
119 instanceAction(client, instance.id, getResolvedAction().get())
120 }
121 }
122 }
123
124 private Instance instanceAction(ComputeClient client, String instanceId, InstanceAction action) {
125 println("Sending ${getResolvedAction().get().name()} to Instance with id ${console.yellow(instanceId)}")
126 Instance instance = client.instanceAction(InstanceActionRequest.builder()
127 .instanceId(instanceId)
128 .action(action.name())
129 .build())
130 .instance
131
132 if (getResolvedWaitForCompletion().get()) {
133 println("Waiting for Instance to be ${state(action.state().name())}")
134 client.waiters
135 .forInstance(GetInstanceRequest.builder()
136 .instanceId(instance.id).build(),
137 action.state())
138 .execute()
139 }
140
141 instance
142 }
143 }
|