diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 0fc510a4c39..11e3ceed7b5 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -58,6 +58,7 @@ //= require bootstrap-switch //= require angular-ui-bootstrap //= require angular-bootstrap-switch +//= require angular-ui-codemirror //= require patternfly-bootstrap-treeview //= require jquery.observe_field //= require miq_ujs_bindings diff --git a/app/assets/javascripts/controllers/ops/pglogical_replication_form_controller.js b/app/assets/javascripts/controllers/ops/pglogical_replication_form_controller.js index c4b8acf72e0..1aa10300572 100644 --- a/app/assets/javascripts/controllers/ops/pglogical_replication_form_controller.js +++ b/app/assets/javascripts/controllers/ops/pglogical_replication_form_controller.js @@ -5,6 +5,7 @@ ManageIQ.angular.app.controller('pglogicalReplicationFormController', ['$http', subscriptions: [], addEnabled: false, updateEnabled: false, + exclusion_list: null, }; $scope.formId = pglogicalReplicationFormId; $scope.afterGet = false; @@ -18,6 +19,7 @@ ManageIQ.angular.app.controller('pglogicalReplicationFormController', ['$http', $http.get('/ops/pglogical_subscriptions_form_fields/' + pglogicalReplicationFormId).success(function(data) { $scope.pglogicalReplicationModel.replication_type = data.replication_type; $scope.pglogicalReplicationModel.subscriptions = angular.copy(data.subscriptions); + $scope.pglogicalReplicationModel.exclusion_list = angular.copy(data.exclusion_list); if ($scope.pglogicalReplicationModel.replication_type == "none") miqService.miqFlash("warn", __("No replication role has been set")); @@ -48,9 +50,14 @@ ManageIQ.angular.app.controller('pglogicalReplicationFormController', ['$http', object.splice(index, 1); } }); + var updated_exclusion_list = ""; + if ($scope.pglogicalReplicationModel.replication_type == "remote" && !angular.equals($scope.pglogicalReplicationModel.exclusion_list, $scope.modelCopy.exclusion_list) ) { + updated_exclusion_list = angular.copy($scope.pglogicalReplicationModel.exclusion_list); + } pglogicalManageSubscriptionsButtonClicked('save', { 'replication_type': $scope.pglogicalReplicationModel.replication_type, - 'subscriptions' : $scope.pglogicalReplicationModel.subscriptions + 'subscriptions' : $scope.pglogicalReplicationModel.subscriptions, + 'exclusion_list' : updated_exclusion_list }); $scope.angularForm.$setPristine(true); }; @@ -81,11 +88,17 @@ ManageIQ.angular.app.controller('pglogicalReplicationFormController', ['$http', else if (original_value == "global" && new_value == 'remote') miqService.miqFlash("warn", __("Changing to remote replication role will remove all current subscriptions")); - if (new_value != "global") + if (new_value != "global") { $scope.pglogicalReplicationModel.subscriptions = []; + }; + + if (new_value != "remote") { + $scope.pglogicalReplicationModel.exclusion_list = angular.copy($scope.modelCopy.exclusion_list); + }; - if (new_value == "global" && original_value == "global") + if (new_value == "global" && original_value == "global") { $scope.pglogicalReplicationModel.subscriptions = angular.copy($scope.modelCopy.subscriptions); + }; }; // add new subscription button pressed @@ -188,20 +201,34 @@ ManageIQ.angular.app.controller('pglogicalReplicationFormController', ['$http', } $scope.saveEnabled = function(form) { - var saveable = form.$dirty && form.$valid && !$scope.pglogicalReplicationModel.addEnabled && !$scope.pglogicalReplicationModel.updateEnabled - // also need to enable save button when an existing subscriptions was deleted - var subscriptions_changed = angular.equals($scope.pglogicalReplicationModel.subscriptions, $scope.modelCopy.subscriptions); + var saveable = false; + if ($scope.pglogicalReplicationModel.replication_type != "remote") { + saveable = form.$dirty && form.$valid && !$scope.pglogicalReplicationModel.addEnabled && !$scope.pglogicalReplicationModel.updateEnabled; + // also need to enable save button when an existing subscriptions was deleted + var subscriptions_changed = angular.equals($scope.pglogicalReplicationModel.subscriptions, $scope.modelCopy.subscriptions); - if ((saveable || !subscriptions_changed) && + if ((saveable || !subscriptions_changed) && $scope.pglogicalReplicationModel.replication_type === "global" && - $scope.pglogicalReplicationModel.subscriptions.length >= 1) - return true; - else if (saveable && - $scope.pglogicalReplicationModel.replication_type !== "global" && - $scope.pglogicalReplicationModel.subscriptions.length == 0) - return true; - else - return false; + $scope.pglogicalReplicationModel.subscriptions.length >= 1) { + return true; + } + else if (saveable && + $scope.pglogicalReplicationModel.replication_type !== "global" && + $scope.pglogicalReplicationModel.subscriptions.length == 0) { + return true; + } + else { + return false; + } + } else { + saveable = form.$dirty && form.$valid; + if (saveable && (($scope.modelCopy.replication_type !== "remote") || !angular.equals($scope.pglogicalReplicationModel.exclusion_list, $scope.modelCopy.exclusion_list))) { + return true; + } + else { + return false + } + } } // method to set flag to disable certain buttons when add of subscription in progress diff --git a/app/assets/javascripts/miq_angular_application.js b/app/assets/javascripts/miq_angular_application.js index d860f01ac82..994014811ca 100644 --- a/app/assets/javascripts/miq_angular_application.js +++ b/app/assets/javascripts/miq_angular_application.js @@ -1,5 +1,6 @@ ManageIQ.angular.app = angular.module('ManageIQ', [ 'ui.bootstrap', + 'ui.codemirror', 'patternfly', 'frapontillo.bootstrap-switch', 'angular.validators', diff --git a/app/controllers/ops_controller/settings/common.rb b/app/controllers/ops_controller/settings/common.rb index 8af77ed5ddd..612d0da5b77 100644 --- a/app/controllers/ops_controller/settings/common.rb +++ b/app/controllers/ops_controller/settings/common.rb @@ -183,9 +183,12 @@ def pglogical_subscriptions_form_fields end end + exclusion_list = replication_type == :remote ? MiqPglogical.new.active_excludes : MiqPglogical.default_excludes + render :json => { :replication_type => replication_type, - :subscriptions => subscriptions + :subscriptions => subscriptions, + :exclusion_list => exclusion_list.to_yaml } end @@ -205,7 +208,7 @@ def pglogical_save_subscriptions end begin PglogicalSubscription.save_all!(subscriptions_to_save) - rescue StandardError => bang + rescue StandardError => bang add_flash(_("Error during replication configuration save: %{message}") % {:message => bang}, :error) else @@ -218,7 +221,18 @@ def pglogical_save_subscriptions add_flash(_("Error during replication configuration save: %{message}") % {:message => bang.message}, :error) else - add_flash(_("Replication configuration save was successful")) + if replication_type == :remote && !params[:exclusion_list].empty? + begin + MiqPglogical.refresh_excludes_queue(YAML.safe_load(params[:exclusion_list])) + rescue => bang + add_flash(_("Error saving the excluded tables list: %{message}") % + {:message => bang}, :error) + else + add_flash(_("Replication configuration save was successful")) + end + else + add_flash(_("Replication configuration save was successful")) + end end end javascript_flash(:spinner_off => true) diff --git a/app/views/ops/_settings_replication_tab.html.haml b/app/views/ops/_settings_replication_tab.html.haml index 7b801a57ecf..4363d451ed6 100644 --- a/app/views/ops/_settings_replication_tab.html.haml +++ b/app/views/ops/_settings_replication_tab.html.haml @@ -234,6 +234,14 @@ %li %a{"ng-click" => "discardSubscription($index)"} = _('Discard') + .exclusion_list_div{"ng-if" => "pglogicalReplicationModel.replication_type == 'remote'"} + %h3 + = _('Excluded Tables') + %br + %textarea{"ui-codemirror" => "", + :name => "exclusion_list", + 'ng-model' => 'pglogicalReplicationModel.exclusion_list', + 'checkchange' => ''} .button-group{:align => "right"} = button_tag(_("Save"), diff --git a/bower.json b/bower.json index 688dcfb7b00..c6d963fd730 100644 --- a/bower.json +++ b/bower.json @@ -23,6 +23,7 @@ "angular-mocks": "~1.5.8", "angular-patternfly-sass": "~3.13.0", "angular-sanitize": "~1.5.8", + "angular-ui-codemirror": "~0.3.0", "angular.validators": "~4.4.2", "array-includes": "~1.0.0", "bootstrap-filestyle": "~1.2.1", diff --git a/spec/controllers/ops_controller/settings/common_spec.rb b/spec/controllers/ops_controller/settings/common_spec.rb index 231dbc86f85..a715c65dabc 100644 --- a/spec/controllers/ops_controller/settings/common_spec.rb +++ b/spec/controllers/ops_controller/settings/common_spec.rb @@ -262,5 +262,23 @@ expect(assigns(:flash_array).first[:message]).to include("Central Admin has been disabled") end end + + context "#update_exclude_tables_for_remote_region" do + render_views + + before do + EvmSpecHelper.local_miq_server(:zone => Zone.seed) + FactoryGirl.create(:miq_region, :region => 10, :description => "The 10th region") + end + + it "updates the exclude tables for the remote region" do + allow(MiqRegion).to receive(:replication_type).and_return(:remote) + allow(controller).to receive(:javascript_flash) + params = {:replication_type => "remote", :exclusion_list => "table1", :button => "save", :id => "new"} + controller.instance_variable_set(:@_params, params) + controller.send(:pglogical_save_subscriptions) + expect(assigns(:flash_array).first[:message]).to include("Replication configuration save was successful") + end + end end end diff --git a/spec/javascripts/controllers/ops/pglogical_replication_form_controller_spec.js b/spec/javascripts/controllers/ops/pglogical_replication_form_controller_spec.js index 2fcb6c15684..a158bffcb85 100644 --- a/spec/javascripts/controllers/ops/pglogical_replication_form_controller_spec.js +++ b/spec/javascripts/controllers/ops/pglogical_replication_form_controller_spec.js @@ -12,7 +12,9 @@ describe('pglogicalReplicationFormController', function() { $scope = $rootScope.$new(); $scope.pglogicalReplicationModel = { replication_type: 'none', - subscriptions : []}; + subscriptions : [], + exclusion_list : "" + }; $httpBackend = _$httpBackend_; $controller = _$controller_('pglogicalReplicationFormController', { $scope: $scope, @@ -24,7 +26,9 @@ describe('pglogicalReplicationFormController', function() { beforeEach(inject(function(_$controller_) { var pglogicalReplicationFormResponse = { replication_type: 'none', - subscriptions : []}; + subscriptions : [], + exclusion_list : "" + }; $httpBackend.whenGET('/ops/pglogical_subscriptions_form_fields/new').respond(pglogicalReplicationFormResponse); $httpBackend.flush(); })); @@ -42,6 +46,10 @@ describe('pglogicalReplicationFormController', function() { it('sets the subscriptions value returned with http request', function() { expect($scope.pglogicalReplicationModel.subscriptions).toEqual([]); }); + + it('sets the exclusion list to the value returned by the http request', function() { + expect($scope.pglogicalReplicationModel.exclusion_list).toEqual(""); + }); }); describe('#resetClicked', function() { @@ -73,7 +81,8 @@ describe('pglogicalReplicationFormController', function() { it('delegates to miqService.miqAjaxButton', function() { var submitContent = { replication_type: $scope.pglogicalReplicationModel.replication_type, - subscriptions: $scope.pglogicalReplicationModel.subscriptions}; + subscriptions: $scope.pglogicalReplicationModel.subscriptions, + exclusion_list: $scope.pglogicalReplicationModel.exclusion_list}; expect(miqService.miqAjaxButton).toHaveBeenCalledWith('/ops/pglogical_save_subscriptions/new?button=save', submitContent); });