Skip to content
This repository has been archived by the owner on Jun 14, 2024. It is now read-only.

Commit

Permalink
Resolve GCLOUD_CONFIG/APPENGINE_CONFIG late (#321)
Browse files Browse the repository at this point in the history
* Resolve GCLOUD_CONFIG/APPENGINE_CONFIG late

If a user doesn't have the cloud sdk installed yet, but uses
GCLOUD_CONFIG, it results in a cloud sdk not found error.

While this seems like a strange case, it's safest for us
to only even attempt anything after we can guarantee the cloud
sdk is setup.
  • Loading branch information
loosebazooka authored Jan 10, 2019
1 parent 6412e8b commit 8b7ea8e
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,7 @@ private void configureExtensions() {
deploy.setAppEngineDirectory(stageExtension.getAppEngineDirectory());
}

AppYamlDeployTargetResolver resolver =
new AppYamlDeployTargetResolver(cloudSdkOperations.getGcloud());
deploy.setProjectId(resolver.getProject(deploy.getProjectId()));
deploy.setVersion(resolver.getVersion(deploy.getVersion()));
deploy.setDeployTargetResolver(new AppYamlDeployTargetResolver(cloudSdkOperations));

DeployAllTask deployAllTask =
(DeployAllTask)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@
import static com.google.cloud.tools.gradle.appengine.core.ConfigReader.APPENGINE_CONFIG;
import static com.google.cloud.tools.gradle.appengine.core.ConfigReader.GCLOUD_CONFIG;

import com.google.cloud.tools.appengine.operations.Gcloud;
import com.google.cloud.tools.gradle.appengine.core.CloudSdkOperations;
import com.google.cloud.tools.gradle.appengine.core.ConfigReader;
import com.google.cloud.tools.gradle.appengine.core.DeployTargetResolver;
import org.gradle.api.GradleException;

public class AppYamlDeployTargetResolver {
public class AppYamlDeployTargetResolver implements DeployTargetResolver {

static final String PROJECT_ERROR =
"Deployment projectId must be defined or configured to read from system state\n"
Expand All @@ -46,44 +47,46 @@ public class AppYamlDeployTargetResolver {
+ APPENGINE_CONFIG
+ " is not allowed for app.yaml based projects";

private final Gcloud gcloud;
private final CloudSdkOperations cloudSdkOperations;

public AppYamlDeployTargetResolver(Gcloud gcloud) {
this.gcloud = gcloud;
public AppYamlDeployTargetResolver(CloudSdkOperations cloudSdkOperations) {
this.cloudSdkOperations = cloudSdkOperations;
}

/**
* Process user configuration of "projectId". If not configured or set to APPENGINE_CONFIG (not
* allowed for app.yaml based projects), show usage. If set to GCLOUD_CONFIG then read from
* gcloud's global state. If set but not a keyword then just return the set value.
*/
@Override
public String getProject(String configString) {
if (configString == null
|| configString.trim().isEmpty()
|| configString.equals(APPENGINE_CONFIG)) {
throw new GradleException(PROJECT_ERROR);
} else if (configString.equals(GCLOUD_CONFIG)) {
return ConfigReader.getProject(gcloud);
} else {
return configString;
}
if (configString.equals(GCLOUD_CONFIG)) {
return ConfigReader.getProject(cloudSdkOperations.getGcloud());
}
return configString;
}

/**
* Process user configuration of "version". If not configured or set to APPENGINE_CONFIG (not
* allowed for app.yaml based deployments), show usage. If set to GCLOUD_CONFIG then allow gcloud
* to generate a version. If set but not a keyword then just return the set value.
*/
@Override
public String getVersion(String configString) {
if (configString == null
|| configString.trim().isEmpty()
|| configString.equals(APPENGINE_CONFIG)) {
throw new GradleException(VERSION_ERROR);
} else if (configString.equals(GCLOUD_CONFIG)) {
}
if (configString.equals(GCLOUD_CONFIG)) {
// can be null to allow gcloud to generate this
return null;
} else {
return configString;
}
return configString;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
/** Extension element to define Deployable configurations for App Engine. */
public class DeployExtension {

@InternalProperty private DeployTargetResolver deployTargetResolver;

// named gradleProject to disambiguate with deploy parameter "project"
private final Project gradleProject;

Expand All @@ -45,21 +47,28 @@ public DeployExtension(Project gradleProject) {
this.gradleProject = gradleProject;
}

public void setDeployTargetResolver(DeployTargetResolver deployTargetResolver) {
this.deployTargetResolver = deployTargetResolver;
}

DeployConfiguration toDeployConfiguration(List<Path> deployables) {
String processedProjectId = deployTargetResolver.getProject(projectId);
String processedVersion = deployTargetResolver.getVersion(version);
return DeployConfiguration.builder(deployables)
.bucket(bucket)
.imageUrl(imageUrl)
.projectId(projectId)
.projectId(processedProjectId)
.promote(promote)
.server(server)
.stopPreviousVersion(stopPreviousVersion)
.version(version)
.version(processedVersion)
.build();
}

DeployProjectConfigurationConfiguration toDeployProjectConfigurationConfiguration() {
String processedProjectId = deployTargetResolver.getProject(projectId);
return DeployProjectConfigurationConfiguration.builder(appEngineDirectory.toPath())
.projectId(projectId)
.projectId(processedProjectId)
.server(server)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2019 Google LLC. All Rights Reserved.
*
* 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.
*/

package com.google.cloud.tools.gradle.appengine.core;

/** Used for processing user configured project/version when generating config objects. */
public interface DeployTargetResolver {
String getProject(String configString);

String getVersion(String configString);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,12 @@

package com.google.cloud.tools.gradle.appengine.standard;

import static com.google.cloud.tools.gradle.appengine.core.ConfigReader.APPENGINE_CONFIG;
import static com.google.cloud.tools.gradle.appengine.core.ConfigReader.GCLOUD_CONFIG;

import com.google.cloud.tools.appengine.operations.cloudsdk.CloudSdkNotFoundException;
import com.google.cloud.tools.gradle.appengine.core.AppEngineCorePluginConfiguration;
import com.google.cloud.tools.gradle.appengine.core.CloudSdkOperations;
import com.google.cloud.tools.gradle.appengine.core.ConfigReader;
import com.google.cloud.tools.gradle.appengine.core.DeployAllTask;
import com.google.cloud.tools.gradle.appengine.core.DeployExtension;
import com.google.cloud.tools.gradle.appengine.core.DeployTargetResolver;
import com.google.cloud.tools.gradle.appengine.core.DeployTask;
import com.google.cloud.tools.gradle.appengine.core.ToolsExtension;
import com.google.common.base.Strings;
Expand Down Expand Up @@ -123,11 +120,10 @@ private void configureExtensions() {
.resolve("appengine-web.xml")
.toFile();

// configure the deploy extensions's project/version parameters
StandardDeployTargetResolver resolver =
new StandardDeployTargetResolver(appengineWebXml, cloudSdkOperations.getGcloud());
deploy.setProjectId(resolver.getProject(deploy.getProjectId()));
deploy.setVersion(resolver.getVersion(deploy.getVersion()));
// configure the resolver for projectId/version parameters
DeployTargetResolver standardResolver =
new StandardDeployTargetResolver(appengineWebXml, cloudSdkOperations);
deploy.setDeployTargetResolver(standardResolver);

DeployAllTask deployAllTask =
(DeployAllTask)
Expand All @@ -144,15 +140,11 @@ private void configureExtensions() {
deployTask.setAppYaml(stageExtension.getStagingDirectory().toPath().resolve("app.yaml"));

// configure the runExtension's project parameter
// assign the run project to the deploy project if none is specified
// assign the run projectId to the deploy projectId if none is specified
if (Strings.isNullOrEmpty(runExtension.getProjectId())) {
runExtension.setProjectId(deploy.getProjectId());
}
if (runExtension.getProjectId().equals(GCLOUD_CONFIG)) {
runExtension.setProjectId(ConfigReader.getProject(cloudSdkOperations.getGcloud()));
} else if (runExtension.getProjectId().equals(APPENGINE_CONFIG)) {
runExtension.setProjectId(ConfigReader.getProject(appengineWebXml));
}
runExtension.setDeployTargetResolver(standardResolver);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package com.google.cloud.tools.gradle.appengine.standard;

import com.google.cloud.tools.appengine.configuration.RunConfiguration;
import com.google.cloud.tools.gradle.appengine.core.DeployTargetResolver;
import com.google.cloud.tools.gradle.appengine.core.InternalProperty;
import com.google.cloud.tools.gradle.appengine.util.NullSafe;
import com.google.common.collect.ImmutableList;
import java.io.File;
Expand All @@ -32,6 +34,8 @@
/** Extension element to define Run configurations for App Engine Standard Environments. */
public class RunExtension {

@InternalProperty private DeployTargetResolver deployTargetResolver;

private final Project project;
private int startSuccessTimeout;
private String serverVersion;
Expand Down Expand Up @@ -73,6 +77,10 @@ public RunExtension(Project project) {
this.project = project;
}

public void setDeployTargetResolver(DeployTargetResolver deployTargetResolver) {
this.deployTargetResolver = deployTargetResolver;
}

public int getStartSuccessTimeout() {
return startSuccessTimeout;
}
Expand Down Expand Up @@ -339,6 +347,7 @@ public void setProjectId(String projectId) {
}

RunConfiguration toRunConfiguration() {
String processedProjectId = deployTargetResolver.getProject(projectId);
return RunConfiguration.builder(
services.stream().map(File::toPath).collect(Collectors.toList()))
.additionalArguments(additionalArguments)
Expand All @@ -359,7 +368,7 @@ RunConfiguration toRunConfiguration() {
.logLevel(logLevel)
.maxModuleInstances(maxModuleInstances)
.port(port)
.projectId(projectId)
.projectId(processedProjectId)
.pythonStartupArgs(pythonStartupArgs)
.pythonStartupScript(pythonStartupScript)
.runtime(runtime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
import static com.google.cloud.tools.gradle.appengine.core.ConfigReader.APPENGINE_CONFIG;
import static com.google.cloud.tools.gradle.appengine.core.ConfigReader.GCLOUD_CONFIG;

import com.google.cloud.tools.appengine.operations.Gcloud;
import com.google.cloud.tools.gradle.appengine.core.CloudSdkOperations;
import com.google.cloud.tools.gradle.appengine.core.ConfigReader;
import com.google.cloud.tools.gradle.appengine.core.DeployTargetResolver;
import java.io.File;
import org.gradle.api.GradleException;

public class StandardDeployTargetResolver {
public class StandardDeployTargetResolver implements DeployTargetResolver {

static final String PROJECT_ERROR =
"Deployment projectId must be defined or configured to read from system state\n"
Expand All @@ -48,45 +49,49 @@ public class StandardDeployTargetResolver {
+ "' to have gcloud generate a version for you.";

private final File appengineWebXml;
private final Gcloud gcloud;
private final CloudSdkOperations cloudSdkOperations;

public StandardDeployTargetResolver(File appengineWebXml, Gcloud gcloud) {
public StandardDeployTargetResolver(File appengineWebXml, CloudSdkOperations cloudSdkOperations) {
this.appengineWebXml = appengineWebXml;
this.gcloud = gcloud;
this.cloudSdkOperations = cloudSdkOperations;
}

/**
* Process user configuration of "projectId". If not configured, show usage. If set to
* APPENGINE_CONFIG then read from appengine-web.xml. If set to GCLOUD_CONFIG then read from
* gcloud's config state. If set but not a keyword then just return the set value.
*/
@Override
public String getProject(String configString) {
if (configString == null || configString.trim().isEmpty()) {
throw new GradleException(PROJECT_ERROR);
} else if (configString.equals(APPENGINE_CONFIG)) {
}
if (configString.equals(APPENGINE_CONFIG)) {
return ConfigReader.getProject(appengineWebXml);
} else if (configString.equals(GCLOUD_CONFIG)) {
return ConfigReader.getProject(gcloud);
} else {
return configString;
}
if (configString.equals(GCLOUD_CONFIG)) {
return ConfigReader.getProject(cloudSdkOperations.getGcloud());
}
return configString;
}

/**
* Process user configuration of "version". If not configured, show usage. If set to
* APPENGINE_CONFIG then read from appengine-web.xml. If set to GCLOUD_CONFIG then allow gcloud to
* generate a version. If set but not a keyword then just return the set value.
*/
@Override
public String getVersion(String configString) {
if (configString == null || configString.trim().isEmpty()) {
throw new GradleException(VERSION_ERROR);
} else if (configString.equals(APPENGINE_CONFIG)) {
}
if (configString.equals(APPENGINE_CONFIG)) {
return ConfigReader.getVersion(appengineWebXml);
} else if (configString.equals(GCLOUD_CONFIG)) {
}
if (configString.equals(GCLOUD_CONFIG)) {
// can be null to allow gcloud to generate this
return null;
} else {
return configString;
}
return configString;
}
}
Loading

0 comments on commit 8b7ea8e

Please sign in to comment.