1
0
mirror of https://github.com/google/nomulus synced 2026-07-06 00:04:50 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Pavlo Tkach ed95d19b93 Provide prompt for user deletion UI (#2684) 2025-02-21 20:30:03 +00:00
Lai Jiang 97fc2c0b66 Add an annotation to the deployment (#2683)
This allows us to easily tell which tag was deployed.

Also set the gateway to use named address so they are stable, and so
that we can attach an IPv6 record to it. Auto-provisioned addresses are
IPv4 only.
2025-02-21 16:30:32 +00:00
Weimin Yu 00728c40ba Abort schema verifier when pg_dump fails (#2681)
Failed pg_dump may not leave a file, failing the subsequent diffing and
causing the verifier to return success.

The verifier should abort in this case.
2025-02-20 17:35:47 +00:00
Lai Jiang 3f2a42ab8d Expose EPP via saidcar proxy (#2680) 2025-02-19 18:57:25 +00:00
Lai Jiang b73e342820 Update PostgreSQL version in builder image and tests (#2667) 2025-02-18 17:34:41 +00:00
Lai Jiang df7fec7a3e Update RDAP TOS link (#2678) 2025-02-18 17:00:26 +00:00
Lai Jiang 6f7ae1eabc Redirect HTTP to HTTPS (#2679)
This opens up port 80 on the load balancer IP and upgrades all HTTP
request to HTTPS.

TESTED=tested on alpha.
2025-02-18 16:57:18 +00:00
30 changed files with 418 additions and 79 deletions
@@ -76,7 +76,7 @@ enum Operation {
selector: 'app-reason-dialog',
template: `
<h2 mat-dialog-title>
Please provide a reason for {{ data.operation }} the domain(s):
Please provide the (EPP) reason for {{ data.operation }} the domain(s):
</h2>
<mat-dialog-content>
<mat-form-field appearance="outline" style="width:100%">
@@ -67,17 +67,24 @@ export class UserDetailsComponent {
}
deleteUser() {
this.isLoading = true;
this.usersService.deleteUser(this.userDetails()).subscribe({
error: (err) => {
this._snackBar.open(err.error || err.message);
this.isLoading = false;
},
complete: () => {
this.isLoading = false;
this.goBack();
},
});
if (
confirm(
'This will permanently delete the user ' +
this.userDetails().emailAddress
)
) {
this.isLoading = true;
this.usersService.deleteUser(this.userDetails()).subscribe({
error: (err) => {
this._snackBar.open(err.error || err.message);
this.isLoading = false;
},
complete: () => {
this.isLoading = false;
this.goBack();
},
});
}
}
goBack() {
@@ -70,7 +70,7 @@ import google.registry.rdap.RdapObjectClasses.RdapRegistrarEntity;
import google.registry.rdap.RdapObjectClasses.SecureDns;
import google.registry.rdap.RdapObjectClasses.Vcard;
import google.registry.rdap.RdapObjectClasses.VcardArray;
import google.registry.request.FullServletPath;
import google.registry.request.RequestServerName;
import google.registry.util.Clock;
import jakarta.persistence.Entity;
import java.net.Inet4Address;
@@ -114,7 +114,7 @@ public class RdapJsonFormatter {
@Nullable
String rdapTosStaticUrl;
@Inject @FullServletPath String fullServletPath;
@Inject @RequestServerName String serverName;
@Inject RdapAuthorization rdapAuthorization;
@Inject Clock clock;
@@ -267,7 +267,7 @@ public class RdapJsonFormatter {
.setDescription(rdapTos)
.addLink(selfLink);
if (rdapTosStaticUrl != null) {
URI htmlBaseURI = URI.create(fullServletPath);
URI htmlBaseURI = URI.create("https//:" + serverName + "/rdap/");
URI htmlUri = htmlBaseURI.resolve(rdapTosStaticUrl);
noticeBuilder.addLink(
Link.builder()
@@ -1071,7 +1071,7 @@ public class RdapJsonFormatter {
/** Create a link relative to the RDAP server endpoint. */
String makeRdapServletRelativeUrl(String part, String... moreParts) {
return makeServerRelativeUrl(fullServletPath, part, moreParts);
return makeServerRelativeUrl("https://" + serverName + "/rdap/", part, moreParts);
}
/** Create a link relative to some base server */
@@ -151,17 +151,9 @@ public final class RequestModule {
* query string.
*/
@Provides
@FullServletPath
static String provideFullServletPath(HttpServletRequest req) {
// Include the port only if it differs from the default for the scheme.
if (("http".equals(req.getScheme()) && (req.getServerPort() == 80))
|| ("https".equals(req.getScheme()) && (req.getServerPort() == 443))) {
return String.format("%s://%s%s", req.getScheme(), req.getServerName(), req.getServletPath());
} else {
return String.format(
"%s://%s:%d%s",
req.getScheme(), req.getServerName(), req.getServerPort(), req.getServletPath());
}
@RequestServerName
static String provideServerName(HttpServletRequest req) {
return req.getServerName();
}
@Provides
@@ -20,11 +20,11 @@ import java.lang.annotation.RetentionPolicy;
import javax.inject.Qualifier;
/**
* Dagger qualifier for the HTTP servlet path, prepended with scheme, host and port.
* Dagger qualifier for the server name of the HTTP request.
*
* <p>See {@link jakarta.servlet.http.HttpServletRequest#getServletPath}
* <p>See {@link jakarta.servlet.http.HttpServletRequest#getServerName()}
*/
@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface FullServletPath {}
public @interface RequestServerName {}
@@ -406,26 +406,6 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_registrant_logged_out.json"));
}
@Test
void testRegistrant_baseHasNoTrailingSlash() {
// First, make sure we have a trailing slash at the end by default!
// This test tries to change the default state, if the default doesn't have a /, then this test
// doesn't help.
assertThat(rdapJsonFormatter.fullServletPath).endsWith("/");
rdapJsonFormatter.fullServletPath =
rdapJsonFormatter.fullServletPath.substring(
0, rdapJsonFormatter.fullServletPath.length() - 1);
assertAboutJson()
.that(
rdapJsonFormatter
.createRdapContactEntity(
contactRegistrant,
ImmutableSet.of(RdapEntity.Role.REGISTRANT),
OutputDataType.FULL)
.toJson())
.isEqualTo(loadJson("rdapjson_registrant.json"));
}
@Test
void testAdmin() {
assertAboutJson()
@@ -150,7 +150,7 @@ class RdapTestHelper {
static RdapJsonFormatter getTestRdapJsonFormatter(Clock clock) {
RdapJsonFormatter rdapJsonFormatter = new RdapJsonFormatter();
rdapJsonFormatter.rdapAuthorization = RdapAuthorization.PUBLIC_AUTHORIZATION;
rdapJsonFormatter.fullServletPath = "https://example.tld/rdap/";
rdapJsonFormatter.serverName = "example.tld";
rdapJsonFormatter.clock = clock;
rdapJsonFormatter.rdapTos =
ImmutableList.of(
Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 132 KiB

@@ -23,7 +23,7 @@ public class NomulusPostgreSql {
/** The current PostgreSql version in Cloud SQL. */
// TODO(weiminyu): setup periodic checks to detect version changes in Cloud SQL.
private static final String TARGET_VERSION = "11.21-alpine";
private static final String TARGET_VERSION = "17-alpine";
/**
* Returns the docker image of the targeted Postgresql server version.
@@ -257,11 +257,11 @@ td.section {
<tbody>
<tr>
<td class="property_name">generated by</td>
<td class="property_value">SchemaCrawler 16.23.2</td>
<td class="property_value">SchemaCrawler 16.25.2</td>
</tr>
<tr>
<td class="property_name">generated on</td>
<td class="property_value">2024-12-09 22:31:09</td>
<td class="property_value">2025-02-16 20:10:13</td>
</tr>
<tr>
<td class="property_name">last flyway file</td>
@@ -278,9 +278,9 @@ td.section {
</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-3577.64 4860,-3577.64 4860,4 -4,4" />
<text text-anchor="start" x="4616" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text>
<text text-anchor="start" x="4699" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.23.2</text>
<text text-anchor="start" x="4699" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.25.2</text>
<text text-anchor="start" x="4615" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text>
<text text-anchor="start" x="4699" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2024-12-09 22:31:09</text>
<text text-anchor="start" x="4699" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2025-02-16 20:10:13</text>
<polygon fill="none" stroke="#888888" points="4612,-4 4612,-44 4848,-44 4848,-4 4612,-4" /> <!-- allocationtoken_a08ccbef -->
<g id="node1" class="node">
<title>
@@ -2716,6 +2716,11 @@ td.section {
<td class="minwidth">recurrence_last_expansion</td>
<td class="minwidth">timestamptz not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default '2021-05-31 20:00:00-04'::timestamp with time zone</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
@@ -2825,6 +2830,11 @@ td.section {
<td class="minwidth"><b><i>job_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"BsaDomainRefresh_job_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -2861,6 +2871,11 @@ td.section {
<td class="minwidth"><b><i>job_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"BsaDownload_job_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -3069,6 +3084,11 @@ td.section {
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"ClaimsList_revision_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -3639,6 +3659,11 @@ td.section {
<td class="minwidth"><b><i>id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"DnsRefreshRequest_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -3785,6 +3810,11 @@ td.section {
<td class="minwidth">lordn_phase</td>
<td class="minwidth">text not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default 'NONE'::text</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
@@ -4334,6 +4364,11 @@ td.section {
<td class="minwidth"><b><i>id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"DomainTransactionRecord_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -4895,6 +4930,11 @@ td.section {
<td class="minwidth"><b><i>package_promotion_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"Package_promotion_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -5188,6 +5228,11 @@ td.section {
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"PremiumList_revision_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -5873,6 +5918,11 @@ td.section {
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"RegistryLock_revision_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -6006,6 +6056,11 @@ td.section {
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"ReservedList_revision_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -6065,6 +6120,11 @@ td.section {
<td class="minwidth"><b><i>id</i></b></td>
<td class="minwidth">int8 not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default 1</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
@@ -6155,6 +6215,11 @@ td.section {
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"SignedMarkRevocationList_revision_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -6209,6 +6274,11 @@ td.section {
<td class="minwidth"><b><i>id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"SafeBrowsingThreat_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -6321,6 +6391,11 @@ td.section {
<td class="minwidth"><b><i>id</i></b></td>
<td class="minwidth">int8 not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default 1</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
@@ -257,11 +257,11 @@ td.section {
<tbody>
<tr>
<td class="property_name">generated by</td>
<td class="property_value">SchemaCrawler 16.23.2</td>
<td class="property_value">SchemaCrawler 16.25.2</td>
</tr>
<tr>
<td class="property_name">generated on</td>
<td class="property_value">2024-12-09 22:31:07</td>
<td class="property_value">2025-02-16 20:10:10</td>
</tr>
<tr>
<td class="property_name">last flyway file</td>
@@ -278,9 +278,9 @@ td.section {
</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-7933.5 5565,-7933.5 5565,4 -4,4" />
<text text-anchor="start" x="5321" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text>
<text text-anchor="start" x="5404" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.23.2</text>
<text text-anchor="start" x="5404" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.25.2</text>
<text text-anchor="start" x="5320" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text>
<text text-anchor="start" x="5404" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2024-12-09 22:31:07</text>
<text text-anchor="start" x="5404" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2025-02-16 20:10:10</text>
<polygon fill="none" stroke="#888888" points="5317,-4 5317,-44 5553,-44 5553,-4 5317,-4" /> <!-- allocationtoken_a08ccbef -->
<g id="node1" class="node">
<title>
@@ -3986,11 +3986,21 @@ td.section {
<td class="minwidth">renewal_price_behavior</td>
<td class="minwidth">text not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default 'DEFAULT'::text</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">registration_behavior</td>
<td class="minwidth">text not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default 'DEFAULT'::text</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">allowed_epp_actions</td>
@@ -4755,6 +4765,11 @@ td.section {
<td class="minwidth">renewal_price_behavior</td>
<td class="minwidth">text not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default 'DEFAULT'::text</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">renewal_price_currency</td>
@@ -4770,6 +4785,11 @@ td.section {
<td class="minwidth">recurrence_last_expansion</td>
<td class="minwidth">timestamptz not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default '2021-05-31 20:00:00-04'::timestamp with time zone</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
@@ -4986,6 +5006,11 @@ td.section {
<td class="minwidth"><b><i>job_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"BsaDomainRefresh_job_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -5055,6 +5080,11 @@ td.section {
<td class="minwidth"><b><i>job_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"BsaDownload_job_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -5392,6 +5422,11 @@ td.section {
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"ClaimsList_revision_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -6866,6 +6901,11 @@ td.section {
<td class="minwidth"><b><i>id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"DnsRefreshRequest_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -7224,6 +7264,11 @@ td.section {
<td class="minwidth">lordn_phase</td>
<td class="minwidth">text not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default 'NONE'::text</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">last_update_time_via_epp</td>
@@ -8154,6 +8199,11 @@ td.section {
<td class="minwidth">lordn_phase</td>
<td class="minwidth">text not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default 'NONE'::text</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">last_update_time_via_epp</td>
@@ -8494,6 +8544,11 @@ td.section {
<td class="minwidth"><b><i>id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"DomainTransactionRecord_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -9622,6 +9677,11 @@ td.section {
<td class="minwidth"><b><i>package_promotion_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"Package_promotion_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -10154,6 +10214,11 @@ td.section {
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"PremiumList_revision_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -11688,6 +11753,11 @@ td.section {
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"RegistryLock_revision_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -11958,6 +12028,11 @@ td.section {
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"ReservedList_revision_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -12057,6 +12132,11 @@ td.section {
<td class="minwidth"><b><i>id</i></b></td>
<td class="minwidth">int8 not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default 1</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
@@ -12193,6 +12273,11 @@ td.section {
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"SignedMarkRevocationList_revision_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -12270,6 +12355,11 @@ td.section {
<td class="minwidth"><b><i>id</i></b></td>
<td class="minwidth">bigserial not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default nextval('"SafeBrowsingThreat_id_seq"'::regclass)</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
@@ -12595,6 +12685,11 @@ td.section {
<td class="minwidth">breakglass_mode</td>
<td class="minwidth">bool not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default false</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">bsa_enroll_start_time</td>
@@ -12699,6 +12794,11 @@ td.section {
<td class="minwidth"><b><i>id</i></b></td>
<td class="minwidth">int8 not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth"></td>
<td class="minwidth">default 1</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
@@ -2,12 +2,13 @@
-- PostgreSQL database dump
--
-- Dumped from database version 11.21
-- Dumped by pg_dump version 11.21
-- Dumped from database version 17.3
-- Dumped by pg_dump version 17.3
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET transaction_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
@@ -32,7 +33,7 @@ COMMENT ON EXTENSION hstore IS 'data type for storing sets of (key, value) pairs
SET default_tablespace = '';
SET default_with_oids = false;
SET default_table_access_method = heap;
--
-- Name: AllocationToken; Type: TABLE; Schema: public; Owner: -
+18 -2
View File
@@ -37,15 +37,19 @@ for service in frontend backend pubapi console
do
sed s/GCP_PROJECT/"${project}"/g "./kubernetes/nomulus-${service}.yaml" | \
sed s/ENVIRONMENT/"${environment}"/g | \
sed s/PROXY_ENV/"${environment}"/g | \
sed s/EPP/"epp"/g | \
kubectl apply -f -
kubectl rollout restart deployment/${service}
# canary
sed s/GCP_PROJECT/"${project}"/g "./kubernetes/nomulus-${service}.yaml" | \
sed s/ENVIRONMENT/"${environment}"/g | \
sed s/PROXY_ENV/"${environment}_canary"/g | \
sed s/EPP/"epp-canary"/g | \
sed s/"${service}"/"${service}-canary"/g | \
kubectl apply -f -
kubectl rollout restart deployment/${service}-canary
done
# Kills all running pods, new pods created will be pulling the new image.
kubectl delete pods --all
kubectl apply -f "./kubernetes/gateway/nomulus-gateway.yaml"
kubectl apply -f "./kubernetes/gateway/nomulus-iap-${environment}.yaml"
for service in frontend backend console pubapi
@@ -57,4 +61,16 @@ do
sed s/SERVICE/"${service}-canary"/g "./kubernetes/gateway/nomulus-backend-policy-${environment}.yaml" | \
kubectl apply -f -
done
# Restart proxies
while read line
do
parts=(${line})
echo "Updating cluster ${parts[0]} in location ${parts[1]}..."
gcloud container clusters get-credentials ${parts[0]} \
--project ${project} --location ${parts[1]}
kubectl rollout restart deployment/proxy-deployment
kubectl rollout restart deployment/proxy-deployment-canary
done < <(gcloud container clusters list --project ${project} | grep proxy-cluster)
kubectl config use-context "$current_context"
@@ -4,7 +4,18 @@ metadata:
name: nomulus
spec:
gatewayClassName: gke-l7-global-external-managed-mc
addresses:
- type: NamedAddress
value: nomulus-ipv4-address
- type: NamedAddress
value: nomulus-ipv6-address
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
kinds:
- kind: HTTPRoute
- name: https
protocol: HTTPS
port: 443
@@ -15,3 +26,19 @@ spec:
allowedRoutes:
kinds:
- kind: HTTPRoute
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: redirect
spec:
parentRefs:
- kind: Gateway
name: nomulus
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
@@ -6,6 +6,7 @@ spec:
parentRefs:
- kind: Gateway
name: nomulus
sectionName: https
hostnames:
- "backend.BASE_DOMAIN"
rules:
@@ -6,6 +6,7 @@ spec:
parentRefs:
- kind: Gateway
name: nomulus
sectionName: https
hostnames:
- "console.BASE_DOMAIN"
rules:
@@ -6,6 +6,7 @@ spec:
parentRefs:
- kind: Gateway
name: nomulus
sectionName: https
hostnames:
- "frontend.BASE_DOMAIN"
rules:
@@ -6,6 +6,7 @@ spec:
parentRefs:
- kind: Gateway
name: nomulus
sectionName: https
hostnames:
- "pubapi.BASE_DOMAIN"
rules:
+6 -1
View File
@@ -2,6 +2,8 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
annotations:
tag: "latest"
spec:
selector:
matchLabels:
@@ -12,6 +14,8 @@ spec:
service: backend
spec:
serviceAccountName: nomulus
nodeSelector:
cloud.google.com/compute-class: "Performance"
containers:
- name: backend
image: gcr.io/GCP_PROJECT/nomulus
@@ -20,7 +24,8 @@ spec:
name: http
resources:
requests:
cpu: "500m"
cpu: "100m"
memory: "512Mi"
args: [ENVIRONMENT]
env:
- name: POD_ID
+6 -1
View File
@@ -2,6 +2,8 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: console
annotations:
tag: "latest"
spec:
selector:
matchLabels:
@@ -12,6 +14,8 @@ spec:
service: console
spec:
serviceAccountName: nomulus
nodeSelector:
cloud.google.com/compute-class: "Performance"
containers:
- name: console
image: gcr.io/GCP_PROJECT/nomulus
@@ -20,7 +24,8 @@ spec:
name: http
resources:
requests:
cpu: "500m"
cpu: "100m"
memory: "512Mi"
args: [ENVIRONMENT]
env:
- name: POD_ID
+48 -2
View File
@@ -2,6 +2,8 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
annotations:
tag: "latest"
spec:
selector:
matchLabels:
@@ -12,6 +14,8 @@ spec:
service: frontend
spec:
serviceAccountName: nomulus
nodeSelector:
cloud.google.com/compute-class: "Performance"
containers:
- name: frontend
image: gcr.io/GCP_PROJECT/nomulus
@@ -20,7 +24,8 @@ spec:
name: http
resources:
requests:
cpu: "500m"
cpu: "100m"
memory: "512Mi"
args: [ENVIRONMENT]
env:
- name: POD_ID
@@ -37,6 +42,27 @@ spec:
fieldPath: metadata.namespace
- name: CONTAINER_NAME
value: frontend
- name: EPP
image: gcr.io/GCP_PROJECT/proxy
ports:
- containerPort: 30002
name: epp
resources:
requests:
cpu: "100m"
memory: "512Mi"
args: [--env, PROXY_ENV, --log, --local]
env:
- name: POD_ID
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE_ID
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: CONTAINER_NAME
value: EPP
---
# Only need to define the service account once per cluster.
apiVersion: v1
@@ -55,7 +81,7 @@ spec:
apiVersion: apps/v1
kind: Deployment
name: frontend
minReplicas: 5
minReplicas: 15
maxReplicas: 15
metrics:
- type: Resource
@@ -77,6 +103,26 @@ spec:
targetPort: http
name: http
---
apiVersion: v1
kind: Service
metadata:
name: EPP
annotations:
cloud.google.com/l4-rbs: enabled
networking.gke.io/weighted-load-balancing: pods-per-node
spec:
type: LoadBalancer
# Traffic is directly delivered to a node, preserving the original source IP.
externalTrafficPolicy: Local
ipFamilies: [IPv4, IPv6]
ipFamilyPolicy: RequireDualStack
selector:
service: frontend
ports:
- port: 700
targetPort: epp
name: epp
---
apiVersion: net.gke.io/v1
kind: ServiceExport
metadata:
+6 -1
View File
@@ -2,6 +2,8 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: pubapi
annotations:
tag: "latest"
spec:
selector:
matchLabels:
@@ -12,6 +14,8 @@ spec:
service: pubapi
spec:
serviceAccountName: nomulus
nodeSelector:
cloud.google.com/compute-class: "Performance"
containers:
- name: pubapi
image: gcr.io/GCP_PROJECT/nomulus
@@ -20,7 +24,8 @@ spec:
name: http
resources:
requests:
cpu: "500m"
cpu: "100m"
memory: "512Mi"
args: [ENVIRONMENT]
env:
- name: POD_ID
+1 -1
View File
@@ -28,7 +28,7 @@ COPY go.sum ./
COPY go.mod ./
RUN go build -o /deployCloudSchedulerAndQueue
FROM marketplace.gcr.io/google/ubuntu2204
FROM marketplace.gcr.io/google/ubuntu2404
ENV DEBIAN_FRONTEND=noninteractive LANG=en_US.UTF-8
# Add script for cloud scheduler and cloud tasks deployment
COPY --from=deployCloudSchedulerAndQueueBuilder /deployCloudSchedulerAndQueue /usr/local/bin/deployCloudSchedulerAndQueue
+3 -5
View File
@@ -43,10 +43,6 @@ apt-get install openjdk-21-jdk-headless -y
# Install Python
apt-get install python3 -y
# As of March 2021 python3 is at v3.6. Get pip then install dataclasses
# (introduced in 3.7) for nom_build
apt-get install python3-pip -y
python3 -m pip install dataclasses
# Install Node
apt-get install npm -y
@@ -57,11 +53,13 @@ npm install -g n
for i in {1..5}; do n 22.7.0 && break || sleep 15; done
# Install gp_dump
apt-get install postgresql-client-11 procps -y
apt-get install postgresql-client-17 procps -y
# Install gcloud
apt-get install google-cloud-cli -y
apt-get install google-cloud-sdk-app-engine-java -y
apt-get install kubectl -y
apt-get install google-cloud-cli-gke-gcloud-auth-plugin -y
# Install git
apt-get install git -y
+1
View File
@@ -198,6 +198,7 @@ artifacts:
- 'release/cloudbuild-delete-*.yaml'
- 'release/cloudbuild-schema-deploy-*.yaml'
- 'release/cloudbuild-schema-verify-*.yaml'
- 'release/cloudbuild-restart-proxies-*.yaml'
- 'jetty/kubernetes/*.yaml'
- 'jetty/kubernetes/gateway/*.yaml'
# The images are already uploaded, but we still need to include them there so that
+15 -3
View File
@@ -88,6 +88,7 @@ steps:
sed -i s/builder:latest/builder@$builder_digest/g release/cloudbuild-schema-deploy.yaml
sed -i s/builder:latest/builder@$builder_digest/g release/cloudbuild-schema-verify.yaml
sed -i s/builder:latest/builder@$builder_digest/g release/cloudbuild-delete.yaml
sed -i s/builder:latest/builder@$builder_digest/g release/cloudbuild-restart-proxies.yaml
sed -i s/GCP_PROJECT/${PROJECT_ID}/ proxy/kubernetes/proxy-*.yaml
sed -i s/'$${TAG_NAME}'/${TAG_NAME}/g release/cloudbuild-sync-and-tag.yaml
sed -i s/'$${TAG_NAME}'/${TAG_NAME}/g release/cloudbuild-deploy.yaml
@@ -99,6 +100,11 @@ steps:
> release/cloudbuild-deploy-gke-${environment}.yaml
sed s/'$${_ENV}'/${environment}/g release/cloudbuild-delete.yaml \
> release/cloudbuild-delete-${environment}.yaml
sed s/'$${_ENV}'/${environment}/g release/cloudbuild-restart-proxies.yaml \
> release/cloudbuild-restart-proxies-${environment}.yaml
sed s/'$${_ENV}'/${environment}/g release/cloudbuild-restart-proxies.yaml | \
sed s/proxy-deployment/proxy-deployment-canary/g \
> release/cloudbuild-restart-proxies-${environment}-canary.yaml
done
# Build and upload the schema_deployer image.
- name: 'gcr.io/cloud-builders/docker'
@@ -178,11 +184,14 @@ steps:
base_domain=$(grep baseDomain \
./core/src/main/java/google/registry/config/files/nomulus-config-${env}.yaml | \
awk '{print $2}')
for service in frontend backend pubapi console
for service in frontend backend pubapi console
do
# non-canary
sed s/GCP_PROJECT/${PROJECT_ID}/g ./jetty/kubernetes/nomulus-${service}.yaml | \
sed s/ENVIRONMENT/${env}/g > ./jetty/kubernetes/nomulus-${env}-${service}.yaml
sed s/latest/${TAG_NAME}/g | \
sed s/ENVIRONMENT/${env}/g | \
sed s/PROXY_ENV/"${env}"/g | \
sed s/EPP/"epp"/g > ./jetty/kubernetes/nomulus-${env}-${service}.yaml
# Proxy '--log' flag does not work on production.
if [ ${env} == production ]
then
@@ -195,7 +204,10 @@ steps:
fi
# canary
sed s/GCP_PROJECT/${PROJECT_ID}/g ./jetty/kubernetes/nomulus-${service}.yaml | \
sed s/latest/${TAG_NAME}/g | \
sed s/ENVIRONMENT/${env}/g | \
sed s/PROXY_ENV/"${env}_canary"/g | \
sed s/EPP/"epp-canary"/g | \
sed s/${service}/${service}-canary/g \
> ./jetty/kubernetes/nomulus-${env}-${service}-canary.yaml
# Proxy '--log' flag does not work on production.
@@ -264,7 +276,7 @@ steps:
$(gcloud auth list --format='get(account)' --filter=active)
git add .
git commit -m "Release commit for tag ${TAG_NAME}"
git push -o nokeycheck origin master
git push -o nokeycheck origin master
git tag ${TAG_NAME}
git push -o nokeycheck origin ${TAG_NAME}
timeout: 3600s
+54
View File
@@ -0,0 +1,54 @@
# This will do rolling restarts of all proxies. This forces the client to reconnect
# and resets the sessions.
#
# To manually trigger a build on GCB, run:
# gcloud builds submit --config=cloudbuild-restart-proxies.yaml \
# --substitutions=_ENV=[ENV] ..
#
# To trigger a build automatically, follow the instructions below and add a trigger:
# https://cloud.google.com/cloud-build/docs/running-builds/automate-builds
#
# Note: to work around the issue in Spinnaker's 'Deployment Manifest' stage,
# variable references must avoid the ${var} format. Valid formats include
# $var or ${"${var}"}. This file uses the former. Since TAG_NAME and _ENV are
# expanded in the copies sent to Spinnaker, we preserve the brackets around
# them for safe pattern matching during release.
# See https://github.com/spinnaker/spinnaker/issues/3028 for more information.
steps:
# Pull the credential for nomulus tool.
- name: 'gcr.io/$PROJECT_ID/builder:latest'
entrypoint: /bin/bash
args:
- -c
- |
set -e
gcloud secrets versions access latest \
--secret nomulus-tool-cloudbuild-credential > tool-credential.json
# Do rolling restarts of all proxies in all environments.
- name: 'gcr.io/$PROJECT_ID/builder:latest'
entrypoint: /bin/bash
args:
- -c
- |
if [ ${_ENV} == production ]
then
project_id="domain-registry"
else
project_id="domain-registry-${_ENV}"
fi
gcloud auth activate-service-account --key-file=tool-credential.json
while read line
do
name=$(echo $line | awk '{print $1}')
location=$(echo $line | awk '{print $2}')
echo $name $region
echo "Updating cluster $name in location $location..."
gcloud container clusters get-credentials $name \
--project $project_id --location $location
kubectl rollout restart deployment/proxy-deployment
done < <(gcloud container clusters list --project $project_id | grep proxy-cluster)
timeout: 3600s
options:
machineType: 'N1_HIGHCPU_8'
@@ -3,3 +3,6 @@ COMMENT ON EXTENSION pgaudit IS 'provides auditing functionality';
SET default_with_oids = false;
CREATE EXTENSION IF NOT EXISTS pg_stat_statements WITH SCHEMA public;
COMMENT ON EXTENSION pg_stat_statements IS 'track execution statistics of all SQL statements executed';
SET transaction_timeout = 0;
SET default_table_access_method = heap;
SET default_with_oids = false;
@@ -69,6 +69,14 @@ PGPASSWORD=${db_password} pg_dump -h localhost -U "${db_user}" \
--exclude-table flyway_schema_history \
postgres
if [ $? -ne 0 ]; then
echo "Failed to dump schema."
exit 1
else
echo "Schema dumped."
fi
raw_diff=$(diff /schema/nomulus.golden.sql /schema/nomulus.actual.sql)
# Clean up the raw_diff:
# - Remove diff locations (e.g. "5,6c5,6): grep "^[<>]"