diff --git a/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java b/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java index 1cd41d2ec..aa732d72d 100644 --- a/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java +++ b/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java @@ -17,7 +17,6 @@ package google.registry.batch; import static google.registry.request.Action.Method.POST; import com.google.common.flogger.FluentLogger; -import google.registry.batch.cannedscript.CannedScripts; import google.registry.request.Action; import google.registry.request.auth.Auth; import javax.inject.Inject; @@ -25,15 +24,15 @@ import javax.inject.Inject; /** * Action that executes a canned script specified by the caller. * - *

This class is introduced to help the safe rollout of credential changes. The delegated - * credentials in particular, benefit from this: they require manual configuration of the peer - * system in each environment, and may wait hours or even days after deployment until triggered by - * user activities. + *

This class provides a hook for invoking hard-coded methods. The main use case is to verify in + * Sandbox and Production environments new features that depend on environment-specific + * configurations. For example, the {@code DelegatedCredential}, which requires correct GWorkspace + * configuration, has been tested this way. Since it is a hassle to add or remove endpoints, we keep + * this class all the time. * *

This action can be invoked using the Nomulus CLI command: {@code nomulus -e ${env} curl - * --service BACKEND -X POST -u '/_dr/task/executeCannedScript?script=${script_name}'} + * --service BACKEND -X POST -u '/_dr/task/executeCannedScript}'} */ -// TODO(b/277239043): remove class after credential changes are rolled out. @Action( service = Action.Service.BACKEND, path = "/_dr/task/executeCannedScript", @@ -51,7 +50,7 @@ public class CannedScriptExecutionAction implements Runnable { @Override public void run() { try { - CannedScripts.runAllChecks(); + // Invoke canned scripts here. logger.atInfo().log("Finished running scripts."); } catch (Throwable t) { logger.atWarning().withCause(t).log("Error executing scripts."); diff --git a/core/src/main/java/google/registry/batch/cannedscript/CannedScripts.java b/core/src/main/java/google/registry/batch/cannedscript/CannedScripts.java deleted file mode 100644 index f99d81e2d..000000000 --- a/core/src/main/java/google/registry/batch/cannedscript/CannedScripts.java +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2023 The Nomulus Authors. 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 google.registry.batch.cannedscript; - -import com.google.api.gax.core.FixedCredentialsProvider; -import com.google.api.services.bigquery.Bigquery; -import com.google.api.services.dataflow.Dataflow; -import com.google.api.services.dns.Dns; -import com.google.cloud.storage.Storage; -import com.google.cloud.storage.StorageOptions; -import com.google.cloud.tasks.v2.CloudTasksClient; -import com.google.cloud.tasks.v2.CloudTasksSettings; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import com.google.common.flogger.FluentLogger; -import dagger.Component; -import dagger.Module; -import dagger.Provides; -import google.registry.config.CredentialModule; -import google.registry.config.CredentialModule.ApplicationDefaultCredential; -import google.registry.config.RegistryConfig.Config; -import google.registry.config.RegistryConfig.ConfigModule; -import google.registry.util.GoogleCredentialsBundle; -import google.registry.util.UtilsModule; -import java.io.IOException; -import java.util.Optional; -import javax.inject.Singleton; - -/** Canned actions invoked from {@link google.registry.batch.CannedScriptExecutionAction}. */ -// TODO(b/277239043): remove class after credential changes are rolled out. -public class CannedScripts { - private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - - private static final Supplier COMPONENT_SUPPLIER = - Suppliers.memoize(DaggerCannedScripts_CannedScriptsComponent::create); - - public static void runAllChecks() { - CannedScriptsComponent component = COMPONENT_SUPPLIER.get(); - String projectId = component.projectId(); - Bigquery bigquery = component.bigQuery(); - try { - bigquery.datasets().list(projectId).execute().getDatasets().stream() - .findAny() - .ifPresent( - datasets -> - logger.atInfo().log("Found a BQ dataset [%s]", datasets.getFriendlyName())); - logger.atInfo().log("Finished accessing BQ."); - } catch (IOException ioe) { - logger.atSevere().withCause(ioe).log("Failed to access bigquery."); - } - try { - Dataflow dataflow = component.dataflow(); - dataflow.projects().jobs().list(projectId).execute().getJobs().stream() - .findAny() - .ifPresent(job -> logger.atInfo().log("Found a job [%s]", job.getName())); - logger.atInfo().log("Finished accessing Dataflow."); - } catch (IOException ioe) { - logger.atSevere().withCause(ioe).log("Failed to access dataflow."); - } - try { - Storage gcs = component.gcs(); - gcs.listAcls(projectId + "-beam"); - logger.atInfo().log("Finished accessing gcs."); - } catch (RuntimeException e) { - logger.atSevere().withCause(e).log("Failed to access gcs."); - } - try { - Dns dns = component.dns(); - dns.managedZones().list(projectId).execute().getManagedZones().stream() - .findAny() - .ifPresent(zone -> logger.atInfo().log("Found one zone [%s].", zone.getName())); - logger.atInfo().log("Finished accessing dns."); - } catch (IOException ioe) { - logger.atSevere().withCause(ioe).log("Failed to access dns."); - } - try { - CloudTasksClient client = component.cloudtasksClient(); - com.google.cloud.tasks.v2.Queue queue = - client.getQueue( - String.format( - "projects/%s/locations/%s/queues/async-actions", - projectId, component.locationId())); - logger.atInfo().log("Got async queue state [%s]", queue.getState().name()); - logger.atInfo().log("Finished accessing cloudtasks."); - } catch (RuntimeException e) { - logger.atSevere().withCause(e).log("Failed to access cloudtasks."); - } - } - - @Singleton - @Component( - modules = { - ConfigModule.class, - CredentialModule.class, - CannedScriptsModule.class, - UtilsModule.class - }) - interface CannedScriptsComponent { - Bigquery bigQuery(); - - CloudTasksClient cloudtasksClient(); - - Dataflow dataflow(); - - Dns dns(); - - Storage gcs(); - - @Config("projectId") - String projectId(); - - @Config("locationId") - String locationId(); - } - - @Module - static class CannedScriptsModule { - @Provides - static Bigquery provideBigquery( - @ApplicationDefaultCredential GoogleCredentialsBundle credentialsBundle, - @Config("projectId") String projectId) { - return new Bigquery.Builder( - credentialsBundle.getHttpTransport(), - credentialsBundle.getJsonFactory(), - credentialsBundle.getHttpRequestInitializer()) - .setApplicationName(projectId) - .build(); - } - - @Provides - static Dataflow provideDataflow( - @ApplicationDefaultCredential GoogleCredentialsBundle credentialsBundle, - @Config("projectId") String projectId) { - return new Dataflow.Builder( - credentialsBundle.getHttpTransport(), - credentialsBundle.getJsonFactory(), - credentialsBundle.getHttpRequestInitializer()) - .setApplicationName(String.format("%s billing", projectId)) - .build(); - } - - @Provides - static Storage provideGcs( - @ApplicationDefaultCredential GoogleCredentialsBundle credentialsBundle) { - return StorageOptions.newBuilder() - .setCredentials(credentialsBundle.getGoogleCredentials()) - .build() - .getService(); - } - - @Provides - static Dns provideDns( - @ApplicationDefaultCredential GoogleCredentialsBundle credentialsBundle, - @Config("projectId") String projectId, - @Config("cloudDnsRootUrl") Optional rootUrl, - @Config("cloudDnsServicePath") Optional servicePath) { - Dns.Builder builder = - new Dns.Builder( - credentialsBundle.getHttpTransport(), - credentialsBundle.getJsonFactory(), - credentialsBundle.getHttpRequestInitializer()) - .setApplicationName(projectId); - - rootUrl.ifPresent(builder::setRootUrl); - servicePath.ifPresent(builder::setServicePath); - - return builder.build(); - } - - @Provides - public static CloudTasksClient provideCloudTasksClient( - @ApplicationDefaultCredential GoogleCredentialsBundle credentials) { - CloudTasksClient client; - try { - client = - CloudTasksClient.create( - CloudTasksSettings.newBuilder() - .setCredentialsProvider( - FixedCredentialsProvider.create(credentials.getGoogleCredentials())) - .build()); - } catch (IOException e) { - throw new RuntimeException(e); - } - return client; - } - } -} diff --git a/core/src/main/java/google/registry/bigquery/BigqueryModule.java b/core/src/main/java/google/registry/bigquery/BigqueryModule.java index fd3283d0a..0e949696e 100644 --- a/core/src/main/java/google/registry/bigquery/BigqueryModule.java +++ b/core/src/main/java/google/registry/bigquery/BigqueryModule.java @@ -20,7 +20,7 @@ import com.google.common.collect.ImmutableList; import dagger.Module; import dagger.Provides; import dagger.multibindings.Multibinds; -import google.registry.config.CredentialModule.DefaultCredential; +import google.registry.config.CredentialModule.ApplicationDefaultCredential; import google.registry.config.RegistryConfig.Config; import google.registry.util.GoogleCredentialsBundle; import java.util.Map; @@ -34,7 +34,7 @@ public abstract class BigqueryModule { @Provides static Bigquery provideBigquery( - @DefaultCredential GoogleCredentialsBundle credentialsBundle, + @ApplicationDefaultCredential GoogleCredentialsBundle credentialsBundle, @Config("projectId") String projectId) { return new Bigquery.Builder( credentialsBundle.getHttpTransport(), diff --git a/core/src/main/java/google/registry/config/CloudTasksUtilsModule.java b/core/src/main/java/google/registry/config/CloudTasksUtilsModule.java index 109d3771a..8fd8f8271 100644 --- a/core/src/main/java/google/registry/config/CloudTasksUtilsModule.java +++ b/core/src/main/java/google/registry/config/CloudTasksUtilsModule.java @@ -22,7 +22,7 @@ import dagger.Provides; import google.registry.batch.CloudTasksUtils; import google.registry.batch.CloudTasksUtils.GcpCloudTasksClient; import google.registry.batch.CloudTasksUtils.SerializableCloudTasksClient; -import google.registry.config.CredentialModule.DefaultCredential; +import google.registry.config.CredentialModule.ApplicationDefaultCredential; import google.registry.config.RegistryConfig.Config; import google.registry.util.GoogleCredentialsBundle; import java.io.IOException; @@ -41,7 +41,7 @@ public abstract class CloudTasksUtilsModule { // Provides a supplier instead of using a Dagger @Provider because the latter is not serializable. @Provides public static Supplier provideCloudTasksClientSupplier( - @DefaultCredential GoogleCredentialsBundle credentials) { + @ApplicationDefaultCredential GoogleCredentialsBundle credentials) { return (Supplier & Serializable) () -> { CloudTasksClient client; diff --git a/core/src/main/java/google/registry/config/CredentialModule.java b/core/src/main/java/google/registry/config/CredentialModule.java index 85d3c6250..5d57d25ae 100644 --- a/core/src/main/java/google/registry/config/CredentialModule.java +++ b/core/src/main/java/google/registry/config/CredentialModule.java @@ -66,38 +66,6 @@ public abstract class CredentialModule { return GoogleCredentialsBundle.create(credential); } - /** - * Provides the default {@link GoogleCredentialsBundle} from the Google Cloud runtime. - * - *

The credential returned depends on the runtime environment: - * - *

- */ - @DefaultCredential - @Provides - @Singleton - public static GoogleCredentialsBundle provideDefaultCredential( - @Config("defaultCredentialOauthScopes") ImmutableList requiredScopes) { - GoogleCredentials credential; - try { - credential = GoogleCredentials.getApplicationDefault(); - } catch (IOException e) { - throw new RuntimeException(e); - } - if (credential.createScopedRequired()) { - credential = credential.createScoped(requiredScopes); - } - return GoogleCredentialsBundle.create(credential); - } - /** * Provides a {@link GoogleCredentialsBundle} for accessing Google Workspace APIs, such as Drive * and Sheets. @@ -162,13 +130,6 @@ public abstract class CredentialModule { @Retention(RetentionPolicy.RUNTIME) public @interface ApplicationDefaultCredential {} - /** Dagger qualifier for the Application Default Credential. */ - @Qualifier - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Deprecated // Switching to @ApplicationDefaultCredential - public @interface DefaultCredential {} - /** Dagger qualifier for the credential for Google Workspace APIs. */ @Qualifier @Documented diff --git a/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java b/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java index 32ee16c7d..b88eaf527 100644 --- a/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java +++ b/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java @@ -22,7 +22,7 @@ import dagger.Provides; import dagger.multibindings.IntoMap; import dagger.multibindings.IntoSet; import dagger.multibindings.StringKey; -import google.registry.config.CredentialModule.DefaultCredential; +import google.registry.config.CredentialModule.ApplicationDefaultCredential; import google.registry.config.RegistryConfig.Config; import google.registry.dns.writer.DnsWriter; import google.registry.util.GoogleCredentialsBundle; @@ -35,7 +35,7 @@ public abstract class CloudDnsWriterModule { @Provides static Dns provideDns( - @DefaultCredential GoogleCredentialsBundle credentialsBundle, + @ApplicationDefaultCredential GoogleCredentialsBundle credentialsBundle, @Config("projectId") String projectId, @Config("cloudDnsRootUrl") Optional rootUrl, @Config("cloudDnsServicePath") Optional servicePath) { diff --git a/core/src/main/java/google/registry/gcs/GcsUtils.java b/core/src/main/java/google/registry/gcs/GcsUtils.java index 7fe0d95b2..c3b6d1f27 100644 --- a/core/src/main/java/google/registry/gcs/GcsUtils.java +++ b/core/src/main/java/google/registry/gcs/GcsUtils.java @@ -31,7 +31,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Streams; import com.google.common.flogger.FluentLogger; import com.google.common.net.MediaType; -import google.registry.config.CredentialModule.DefaultCredential; +import google.registry.config.CredentialModule.ApplicationDefaultCredential; import google.registry.util.GoogleCredentialsBundle; import java.io.IOException; import java.io.InputStream; @@ -64,7 +64,7 @@ public class GcsUtils implements Serializable { } @Inject - public GcsUtils(@DefaultCredential GoogleCredentialsBundle credentialsBundle) { + public GcsUtils(@ApplicationDefaultCredential GoogleCredentialsBundle credentialsBundle) { this( StorageOptions.newBuilder() .setCredentials(credentialsBundle.getGoogleCredentials()) diff --git a/core/src/main/java/google/registry/reporting/ReportingModule.java b/core/src/main/java/google/registry/reporting/ReportingModule.java index 937de75ab..23583fb97 100644 --- a/core/src/main/java/google/registry/reporting/ReportingModule.java +++ b/core/src/main/java/google/registry/reporting/ReportingModule.java @@ -21,7 +21,7 @@ import static google.registry.request.RequestParameters.extractRequiredParameter import com.google.api.services.dataflow.Dataflow; import dagger.Module; import dagger.Provides; -import google.registry.config.CredentialModule.DefaultCredential; +import google.registry.config.CredentialModule.ApplicationDefaultCredential; import google.registry.config.RegistryConfig.Config; import google.registry.request.HttpException.BadRequestException; import google.registry.request.Parameter; @@ -134,7 +134,7 @@ public class ReportingModule { /** Constructs a {@link Dataflow} API client with default settings. */ @Provides static Dataflow provideDataflow( - @DefaultCredential GoogleCredentialsBundle credentialsBundle, + @ApplicationDefaultCredential GoogleCredentialsBundle credentialsBundle, @Config("projectId") String projectId) { return new Dataflow.Builder( credentialsBundle.getHttpTransport(), diff --git a/core/src/main/java/google/registry/tools/AuthModule.java b/core/src/main/java/google/registry/tools/AuthModule.java index 3c6b27bed..9fbc750fe 100644 --- a/core/src/main/java/google/registry/tools/AuthModule.java +++ b/core/src/main/java/google/registry/tools/AuthModule.java @@ -35,7 +35,6 @@ import dagger.Lazy; import dagger.Module; import dagger.Provides; import google.registry.config.CredentialModule.ApplicationDefaultCredential; -import google.registry.config.CredentialModule.DefaultCredential; import google.registry.config.CredentialModule.LocalCredential; import google.registry.config.CredentialModule.LocalCredentialJson; import google.registry.config.RegistryConfig.Config; @@ -222,10 +221,6 @@ public class AuthModule { @Module abstract static class LocalCredentialModule { - @Binds - @DefaultCredential - abstract GoogleCredentialsBundle provideLocalCredentialAsDefaultCredential( - @LocalCredential GoogleCredentialsBundle credential); @Binds @ApplicationDefaultCredential