diff --git a/config_app/config_endpoints/api/suconfig.py b/config_app/config_endpoints/api/suconfig.py
index 9ec395a05..fa8233a0b 100644
--- a/config_app/config_endpoints/api/suconfig.py
+++ b/config_app/config_endpoints/api/suconfig.py
@@ -65,44 +65,40 @@ class SuperUserConfig(ApiResource):
""" Updates the config override file. """
# Note: This method is called to set the database configuration before super users exists,
# so we also allow it to be called if there is no valid registry configuration setup.
- if not config_provider.config_exists():
- config_object = request.get_json()['config']
- hostname = request.get_json()['hostname']
+ config_object = request.get_json()['config']
+ hostname = request.get_json()['hostname']
- # Add any enterprise defaults missing from the config.
- add_enterprise_config_defaults(config_object, app.config['SECRET_KEY'], hostname)
+ # Add any enterprise defaults missing from the config.
+ add_enterprise_config_defaults(config_object, app.config['SECRET_KEY'], hostname)
- # Write the configuration changes to the config override file.
- config_provider.save_config(config_object)
+ # Write the configuration changes to the config override file.
+ config_provider.save_config(config_object)
+
+ # If the authentication system is federated, link the superuser account to the
+ # the authentication system chosen.
+ service_name = get_federated_service_name(config_object['AUTHENTICATION_TYPE'])
+ if service_name is not None:
+ current_user = get_authenticated_user()
+ if current_user is None:
+ abort(401)
- # If the authentication system is federated, link the superuser account to the
- # the authentication system chosen.
service_name = get_federated_service_name(config_object['AUTHENTICATION_TYPE'])
- if service_name is not None:
- current_user = get_authenticated_user()
- if current_user is None:
- abort(401)
+ if not model.has_federated_login(current_user.username, service_name):
+ # Verify the user's credentials and retrieve the user's external username+email.
+ handler = get_users_handler(config_object, config_provider, OVERRIDE_CONFIG_DIRECTORY)
+ (result, err_msg) = handler.verify_credentials(current_user.username,
+ request.get_json().get('password', ''))
+ if not result:
+ logger.error('Could not save configuration due to external auth failure: %s', err_msg)
+ abort(400)
- service_name = get_federated_service_name(config_object['AUTHENTICATION_TYPE'])
- if not model.has_federated_login(current_user.username, service_name):
- # Verify the user's credentials and retrieve the user's external username+email.
- handler = get_users_handler(config_object, config_provider, OVERRIDE_CONFIG_DIRECTORY)
- (result, err_msg) = handler.verify_credentials(current_user.username,
- request.get_json().get('password', ''))
- if not result:
- logger.error('Could not save configuration due to external auth failure: %s', err_msg)
- abort(400)
-
- # Link the existing user to the external user.
- model.attach_federated_login(current_user.username, service_name, result.username)
-
- return {
- 'exists': True,
- 'config': config_object
- }
-
- abort(403)
+ # Link the existing user to the external user.
+ model.attach_federated_login(current_user.username, service_name, result.username)
+ return {
+ 'exists': True,
+ 'config': config_object
+ }
@resource('/v1/superuser/registrystatus')
diff --git a/config_app/config_endpoints/api/tar_config_loader.py b/config_app/config_endpoints/api/tar_config_loader.py
index f9b61e740..033a7a5f2 100644
--- a/config_app/config_endpoints/api/tar_config_loader.py
+++ b/config_app/config_endpoints/api/tar_config_loader.py
@@ -37,15 +37,14 @@ class TarConfigLoader(ApiResource):
if os.path.isfile('quay-config.tar.gz'):
os.remove('quay-config.tar.gz')
- tar = tarfile.open('quay-config.tar.gz', mode="w:gz")
+ tar = tarfile.open('quay-config.tar.gz', mode="w|gz")
for name in os.listdir(config_path):
tar.add(os.path.join(config_path, name), filter=tarinfo_filter)
tar.close()
- return send_file('quay-config.tar.gz', mimetype='application/gzip',
- as_attachment=True, attachment_filename='quay-config.tar.gz')
+ return send_file('quay-config.tar.gz', mimetype='application/gzip')
@nickname('scUploadTarballConfig')
def put(self):
diff --git a/config_app/js/components/config-setup-app/config-setup-app.component.html b/config_app/js/components/config-setup-app/config-setup-app.component.html
index d1ea58f31..1cd0dd93c 100644
--- a/config_app/js/components/config-setup-app/config-setup-app.component.html
+++ b/config_app/js/components/config-setup-app/config-setup-app.component.html
@@ -22,5 +22,6 @@
-
+
+
diff --git a/config_app/js/components/config-setup-app/config-setup-app.component.ts b/config_app/js/components/config-setup-app/config-setup-app.component.ts
index e22ca57c0..b453d7ef4 100644
--- a/config_app/js/components/config-setup-app/config-setup-app.component.ts
+++ b/config_app/js/components/config-setup-app/config-setup-app.component.ts
@@ -1,4 +1,4 @@
-import { Input, Component, Inject } from 'ng-metadata/core';
+import { Component } from 'ng-metadata/core';
const templateUrl = require('./config-setup-app.component.html');
/**
@@ -9,7 +9,13 @@ const templateUrl = require('./config-setup-app.component.html');
templateUrl: templateUrl,
})
export class ConfigSetupAppComponent {
- private state: 'choice' | 'setup' | 'load';
+ private state
+ : 'choice'
+ | 'setup'
+ | 'load'
+ | 'download';
+
+ private loadedConfig = false;
constructor() {
this.state = 'choice';
@@ -21,9 +27,14 @@ export class ConfigSetupAppComponent {
private chooseLoad(): void {
this.state = 'load';
+ this.loadedConfig = true;
}
private configLoaded(): void {
this.state = 'setup';
}
+
+ private setupCompleted(): void {
+ this.state = 'download';
+ }
}
diff --git a/config_app/js/components/download-tarball-modal/download-tarball-modal.component.html b/config_app/js/components/download-tarball-modal/download-tarball-modal.component.html
new file mode 100644
index 000000000..89898455f
--- /dev/null
+++ b/config_app/js/components/download-tarball-modal/download-tarball-modal.component.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+ Please download your updated configuration. To deploy these changes to your Quay Enterprise instances, please
+
+ see the docs.
+
+
+ Warning:
+ Your configuration and certificates are kept unencrypted. Please keep this file secure.
+
+
+
+ Please download your new configuration. For more information, and next steps, please
+
+ see the docs.
+
+
+ Warning:
+ Your configuration and certificates are kept unencrypted. Please keep this file secure.
+
+
+
+
+
+
+
+
diff --git a/config_app/js/components/download-tarball-modal/download-tarball-modal.component.ts b/config_app/js/components/download-tarball-modal/download-tarball-modal.component.ts
new file mode 100644
index 000000000..0d586a92f
--- /dev/null
+++ b/config_app/js/components/download-tarball-modal/download-tarball-modal.component.ts
@@ -0,0 +1,34 @@
+import { Input, Component, Inject } from 'ng-metadata/core';
+const templateUrl = require('./download-tarball-modal.component.html');
+const styleUrl = require('./download-tarball-modal.css');
+
+declare const FileSaver: any;
+
+/**
+ * Initial Screen and Choice in the Config App
+ */
+@Component({
+ selector: 'download-tarball-modal',
+ templateUrl: templateUrl,
+ styleUrls: [ styleUrl ],
+})
+export class DownloadTarballModalComponent {
+ @Input('<') public loadedConfig;
+
+ constructor(@Inject('ApiService') private ApiService) {
+
+ }
+
+ private downloadTarball() {
+ const errorDisplay: Function = this.ApiService.errorDisplay(
+ 'Could not save configuration. Please report this error.'
+ );
+
+ // We need to set the response type to 'blob', to ensure it's never encoded as a string
+ // (string encoded binary data can be difficult to transform with js)
+ // and to make it easier to save (FileSaver expects a blob)
+ this.ApiService.scGetConfigTarball(null, null, null, null, true).then(function(resp) {
+ FileSaver.saveAs(resp, 'quay-config.tar.gz');
+ }, errorDisplay);
+ }
+}
diff --git a/config_app/js/components/download-tarball-modal/download-tarball-modal.css b/config_app/js/components/download-tarball-modal/download-tarball-modal.css
new file mode 100644
index 000000000..3f68a1a7a
--- /dev/null
+++ b/config_app/js/components/download-tarball-modal/download-tarball-modal.css
@@ -0,0 +1,6 @@
+.modal__warning-box {
+ background-color: #ddd;
+ padding: 15px;
+ border-radius: 5px;
+ margin-top: 15px;
+}
diff --git a/config_app/js/config-app.module.ts b/config_app/js/config-app.module.ts
index ca90cd045..f5aa0c532 100644
--- a/config_app/js/config-app.module.ts
+++ b/config_app/js/config-app.module.ts
@@ -2,6 +2,7 @@ import { NgModule } from 'ng-metadata/core';
import * as restangular from 'restangular';
import { ConfigSetupAppComponent } from './components/config-setup-app/config-setup-app.component';
+import { DownloadTarballModalComponent } from './components/download-tarball-modal/download-tarball-modal.component';
import { LoadConfigComponent } from './components/load-config/load-config.component';
const quayDependencies: string[] = [
@@ -42,6 +43,7 @@ function provideConfig($provide: ng.auto.IProvideService,
imports: [ DependencyConfig ],
declarations: [
ConfigSetupAppComponent,
+ DownloadTarballModalComponent,
LoadConfigComponent,
],
providers: []
diff --git a/config_app/js/core-config-setup/config-setup-tool.html b/config_app/js/core-config-setup/config-setup-tool.html
index a246e46e8..a1fb25e75 100644
--- a/config_app/js/core-config-setup/config-setup-tool.html
+++ b/config_app/js/core-config-setup/config-setup-tool.html
@@ -1,7 +1,6 @@
+ configuration-saved="configurationSaved(config)"
+ setup-completed="setupCompleted()"
+ >