1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-28 13:15:12 +01:00

Update Setup project to handle EU region (#3137)

This commit is contained in:
Vince Grassia 2023-07-31 13:14:33 -04:00 committed by GitHub
parent 1a3005b2ed
commit 6aff9b7b05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 139 additions and 34 deletions

View File

@ -403,11 +403,12 @@ jobs:
- name: Restore - name: Restore
run: dotnet tool restore run: dotnet tool restore
- name: Make Docker stub - name: Make Docker stubs
if: github.ref == 'refs/heads/master' || if: github.ref == 'refs/heads/master' ||
github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/rc' ||
github.ref == 'refs/heads/hotfix-rc' github.ref == 'refs/heads/hotfix-rc'
run: | run: |
# Set proper image based on branch
if [[ "${{ github.ref }}" == "rc" ]]; then if [[ "${{ github.ref }}" == "rc" ]]; then
SETUP_IMAGE="bitwarden/setup:rc" SETUP_IMAGE="bitwarden/setup:rc"
elif [[ "${{ github.ref }}" == "hotfix-rc" ]]; then elif [[ "${{ github.ref }}" == "hotfix-rc" ]]; then
@ -417,32 +418,65 @@ jobs:
fi fi
STUB_OUTPUT=$(pwd)/docker-stub STUB_OUTPUT=$(pwd)/docker-stub
docker run -i --rm --name setup -v $STUB_OUTPUT:/bitwarden $SETUP_IMAGE \
dotnet Setup.dll -stub 1 -install 1 -domain bitwarden.example.com -os lin # Run setup
docker run -i --rm --name setup -v $STUB_OUTPUT/US:/bitwarden $SETUP_IMAGE \
dotnet Setup.dll -stub 1 -install 1 -domain bitwarden.example.com -os lin -cloud-region US
docker run -i --rm --name setup -v $STUB_OUTPUT/EU:/bitwarden $SETUP_IMAGE \
dotnet Setup.dll -stub 1 -install 1 -domain bitwarden.example.com -os lin -cloud-region EU
sudo chown -R $(whoami):$(whoami) $STUB_OUTPUT sudo chown -R $(whoami):$(whoami) $STUB_OUTPUT
rm -rf $STUB_OUTPUT/letsencrypt
rm $STUB_OUTPUT/env/uid.env $STUB_OUTPUT/config.yml
touch $STUB_OUTPUT/env/uid.env
cd docker-stub; zip -r ../docker-stub.zip *; cd ..
- name: Make Docker stub checksum Remove extra directories and files
rm -rf $STUB_OUTPUT/US/letsencrypt
rm -rf $STUB_OUTPUT/EU/letsencrypt
rm $STUB_OUTPUT/US/env/uid.env $STUB_OUTPUT/US/config.yml
rm $STUB_OUTPUT/EU/env/uid.env $STUB_OUTPUT/EU/config.yml
# Create uid environment files
touch $STUB_OUTPUT/US/env/uid.env
touch $STUB_OUTPUT/EU/env/uid.env
# Zip up the Docker stub files
cd docker-stub/US; zip -r ../../docker-stub-US.zip *; cd ../..
cd docker-stub/EU; zip -r ../../docker-stub-EU.zip *; cd ../..
- name: Make Docker stub checksums
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc' if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc'
run: sha256sum docker-stub.zip > docker-stub-sha256.txt run: |
sha256sum docker-stub-US.zip > docker-stub-US-sha256.txt
sha256sum docker-stub-EU.zip > docker-stub-EU-sha256.txt
- name: Upload Docker stub artifact - name: Upload Docker stub US artifact
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc' if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc'
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with: with:
name: docker-stub.zip name: docker-stub-US.zip
path: docker-stub.zip path: docker-stub-US.zip
if-no-files-found: error if-no-files-found: error
- name: Upload Docker stub checksum artifact - name: Upload Docker stub EU artifact
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc' if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc'
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with: with:
name: docker-stub-sha256.txt name: docker-stub-EU.zip
path: docker-stub-sha256.txt path: docker-stub-EU.zip
if-no-files-found: error
- name: Upload Docker stub US checksum artifact
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc'
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: docker-stub-US-sha256.txt
path: docker-stub-US-sha256.txt
if-no-files-found: error
- name: Upload Docker stub EU checksum artifact
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc'
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: docker-stub-EU-sha256.txt
path: docker-stub-EU-sha256.txt
if-no-files-found: error if-no-files-found: error
- name: Build Swagger - name: Build Swagger

View File

@ -338,34 +338,40 @@ jobs:
- setup - setup
- deploy - deploy
steps: steps:
- name: Download latest Release docker-stub - name: Download latest Release Docker Stubs
if: ${{ github.event.inputs.release_type != 'Dry Run' }} if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@74f4ac01c9abe0a7331c9a5de822a558fd4a4710 uses: bitwarden/gh-actions/download-artifacts@74f4ac01c9abe0a7331c9a5de822a558fd4a4710
with: with:
workflow: build.yml workflow: build.yml
workflow_conclusion: success workflow_conclusion: success
branch: ${{ needs.setup.outputs.branch-name }} branch: ${{ needs.setup.outputs.branch-name }}
artifacts: "docker-stub.zip, artifacts: "docker-stub-US.zip,
docker-stub-sha256.txt, docker-stub-US-sha256.txt,
docker-stub-EU.zip,
docker-stub-EU-sha256.txt,
swagger.json" swagger.json"
- name: Download latest Release docker-stub - name: Download latest Release Docker Stubs
if: ${{ github.event.inputs.release_type == 'Dry Run' }} if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@74f4ac01c9abe0a7331c9a5de822a558fd4a4710 uses: bitwarden/gh-actions/download-artifacts@74f4ac01c9abe0a7331c9a5de822a558fd4a4710
with: with:
workflow: build.yml workflow: build.yml
workflow_conclusion: success workflow_conclusion: success
branch: master branch: master
artifacts: "docker-stub.zip, artifacts: "docker-stub-US.zip,
docker-stub-sha256.txt, docker-stub-US-sha256.txt,
docker-stub-EU.zip,
docker-stub-EU-sha256.txt,
swagger.json" swagger.json"
- name: Create release - name: Create release
if: ${{ github.event.inputs.release_type != 'Dry Run' }} if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0 uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0
with: with:
artifacts: "docker-stub.zip, artifacts: "docker-stub-US.zip,
docker-stub-sha256.txt, docker-stub-US-sha256.txt,
docker-stub-EU.zip,
docker-stub-EU-sha256.txt,
swagger.json" swagger.json"
commit: ${{ github.sha }} commit: ${{ github.sha }}
tag: "v${{ needs.setup.outputs.release_version }}" tag: "v${{ needs.setup.outputs.release_version }}"

View File

@ -1,4 +1,5 @@
using YamlDotNet.Serialization; using Bit.Setup.Enums;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NamingConventions;
namespace Bit.Setup; namespace Bit.Setup;
@ -183,6 +184,7 @@ public class Context
{ {
public Guid InstallationId { get; set; } public Guid InstallationId { get; set; }
public string InstallationKey { get; set; } public string InstallationKey { get; set; }
public CloudRegion CloudRegion { get; set; }
public bool DiffieHellman { get; set; } public bool DiffieHellman { get; set; }
public bool Trusted { get; set; } public bool Trusted { get; set; }
public bool SelfSignedCert { get; set; } public bool SelfSignedCert { get; set; }

View File

@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Setup.Enums;
public enum CloudRegion
{
[Display(Name = "US")]
US = 0,
[Display(Name = "EU")]
EU = 1,
}

View File

@ -73,7 +73,7 @@ public class EnvironmentFileBuilder
_globalOverrideValues = new Dictionary<string, string> _globalOverrideValues = new Dictionary<string, string>
{ {
["globalSettings__baseServiceUri__vault"] = _context.Config.Url, ["globalSettings__baseServiceUri__vault"] = _context.Config.Url,
["globalSettings__baseServiceUri__cloudVaultRegion"] = "US", ["globalSettings__baseServiceUri__cloudRegion"] = _context.Install?.CloudRegion.ToString(),
["globalSettings__sqlServer__connectionString"] = $"\"{dbConnectionString.Replace("\"", "\\\"")}\"", ["globalSettings__sqlServer__connectionString"] = $"\"{dbConnectionString.Replace("\"", "\\\"")}\"",
["globalSettings__identityServer__certificatePassword"] = _context.Install?.IdentityCertPassword, ["globalSettings__identityServer__certificatePassword"] = _context.Install?.IdentityCertPassword,
["globalSettings__internalIdentityKey"] = _context.Stub ? "RANDOM_IDENTITY_KEY" : ["globalSettings__internalIdentityKey"] = _context.Stub ? "RANDOM_IDENTITY_KEY" :

View File

@ -148,7 +148,7 @@ public static class Helpers
Console.Write(prompt); Console.Write(prompt);
if (prompt.EndsWith("?")) if (prompt.EndsWith("?"))
{ {
Console.Write(" (y/n)"); Console.Write(" (y/N)");
} }
Console.Write(": "); Console.Write(": ");
var input = Console.ReadLine(); var input = Console.ReadLine();
@ -222,4 +222,13 @@ public static class Helpers
Console.WriteLine(); Console.WriteLine();
} }
} }
public static void WriteError(string errorMessage)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("(!) ");
Console.ResetColor();
Console.Write(errorMessage);
Console.WriteLine();
}
} }

View File

@ -1,6 +1,7 @@
using System.Globalization; using System.Globalization;
using System.Net.Http.Json; using System.Net.Http.Json;
using Bit.Migrator; using Bit.Migrator;
using Bit.Setup.Enums;
namespace Bit.Setup; namespace Bit.Setup;
@ -196,6 +197,7 @@ public class Program
{ {
var installationId = string.Empty; var installationId = string.Empty;
var installationKey = string.Empty; var installationKey = string.Empty;
CloudRegion cloudRegion;
if (_context.Parameters.ContainsKey("install-id")) if (_context.Parameters.ContainsKey("install-id"))
{ {
@ -203,7 +205,13 @@ public class Program
} }
else else
{ {
installationId = Helpers.ReadInput("Enter your installation id (get at https://bitwarden.com/host)"); var prompt = "Enter your installation id (get at https://bitwarden.com/host)";
installationId = Helpers.ReadInput(prompt);
while (string.IsNullOrEmpty(installationId))
{
Helpers.WriteError("Invalid input for installation id. Please try again.");
installationId = Helpers.ReadInput(prompt);
}
} }
if (!Guid.TryParse(installationId.Trim(), out var installationidGuid)) if (!Guid.TryParse(installationId.Trim(), out var installationidGuid))
@ -218,26 +226,61 @@ public class Program
} }
else else
{ {
installationKey = Helpers.ReadInput("Enter your installation key"); var prompt = "Enter your installation key";
installationKey = Helpers.ReadInput(prompt);
while (string.IsNullOrEmpty(installationKey))
{
Helpers.WriteError("Invalid input for installation key. Please try again.");
installationKey = Helpers.ReadInput(prompt);
}
}
if (_context.Parameters.ContainsKey("cloud-region"))
{
Enum.TryParse(_context.Parameters["cloud-region"], out cloudRegion);
}
else
{
var prompt = "Enter your region (US/EU) [US]";
var region = Helpers.ReadInput(prompt);
if (string.IsNullOrEmpty(region)) region = "US";
while (!Enum.TryParse(region, out cloudRegion))
{
Helpers.WriteError("Invalid input for region. Please try again.");
region = Helpers.ReadInput(prompt);
if (string.IsNullOrEmpty(region)) region = "US";
}
} }
_context.Install.InstallationId = installationidGuid; _context.Install.InstallationId = installationidGuid;
_context.Install.InstallationKey = installationKey; _context.Install.InstallationKey = installationKey;
_context.Install.CloudRegion = cloudRegion;
try try
{ {
var response = new HttpClient().GetAsync("https://api.bitwarden.com/installations/" + string url;
_context.Install.InstallationId).GetAwaiter().GetResult(); switch (cloudRegion)
{
case CloudRegion.EU:
url = "https://api.bitwarden.eu/installations/";
break;
case CloudRegion.US:
default:
url = "https://api.bitwarden.com/installations/";
break;
}
var response = new HttpClient().GetAsync(url + _context.Install.InstallationId).GetAwaiter().GetResult();
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
if (response.StatusCode == System.Net.HttpStatusCode.NotFound) if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
{ {
Console.WriteLine("Invalid installation id."); Console.WriteLine($"Invalid installation id for {cloudRegion.ToString()} region.");
} }
else else
{ {
Console.WriteLine("Unable to validate installation id."); Console.WriteLine($"Unable to validate installation id for {cloudRegion.ToString()} region.");
} }
return false; return false;
@ -246,7 +289,7 @@ public class Program
var result = response.Content.ReadFromJsonAsync<InstallationValidationResponseModel>().GetAwaiter().GetResult(); var result = response.Content.ReadFromJsonAsync<InstallationValidationResponseModel>().GetAwaiter().GetResult();
if (!result.Enabled) if (!result.Enabled)
{ {
Console.WriteLine("Installation id has been disabled."); Console.WriteLine($"Installation id has been disabled in the {cloudRegion.ToString()} region.");
return false; return false;
} }
@ -254,7 +297,7 @@ public class Program
} }
catch catch
{ {
Console.WriteLine("Unable to validate installation id. Problem contacting Bitwarden server."); Console.WriteLine($"Unable to validate installation id. Problem contacting Bitwarden {cloudRegion.ToString()} server.");
return false; return false;
} }
} }