katello 3.0.0.rc1 → 3.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of katello might be problematic. Click here for more details.

Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/katello/katello.scss +5 -5
  3. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +3 -3
  4. data/app/controllers/katello/api/v2/activation_keys_controller.rb +12 -12
  5. data/app/controllers/katello/api/v2/api_controller.rb +13 -5
  6. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +30 -27
  7. data/app/controllers/katello/api/v2/content_views_controller.rb +4 -1
  8. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +100 -3
  9. data/app/controllers/katello/api/v2/repositories_controller.rb +2 -2
  10. data/app/controllers/katello/api/v2/repository_sets_controller.rb +1 -1
  11. data/app/controllers/katello/api/v2/subscriptions_controller.rb +0 -1
  12. data/app/controllers/katello/api/v2/systems_controller.rb +1 -88
  13. data/app/controllers/katello/concerns/api/v2/bulk_hosts_extensions.rb +10 -4
  14. data/app/controllers/katello/remote_execution_controller.rb +1 -1
  15. data/app/helpers/katello/concerns/settings_helper_extensions.rb +50 -0
  16. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +17 -4
  17. data/app/helpers/katello/katello_urls_helper.rb +3 -2
  18. data/app/helpers/katello/providers_helper.rb +2 -5
  19. data/app/lib/actions/katello/capsule_content/configure_capsule.rb +1 -1
  20. data/app/lib/actions/katello/capsule_content/{create_or_update.rb → create_repos.rb} +2 -7
  21. data/app/lib/actions/katello/capsule_content/remove_orphans.rb +15 -0
  22. data/app/lib/actions/katello/capsule_content/remove_unneeded_repos.rb +6 -5
  23. data/app/lib/actions/katello/capsule_content/sync.rb +32 -0
  24. data/app/lib/actions/katello/content_view/incremental_updates.rb +4 -3
  25. data/app/lib/actions/katello/content_view/promote.rb +4 -0
  26. data/app/lib/actions/katello/content_view/publish.rb +4 -0
  27. data/app/lib/actions/katello/content_view_puppet_module/destroy.rb +4 -5
  28. data/app/lib/actions/katello/content_view_version/incremental_update.rb +5 -3
  29. data/app/lib/actions/katello/host/erratum/applicable_errata_install.rb +2 -2
  30. data/app/lib/actions/katello/host/generate_applicability.rb +1 -1
  31. data/app/lib/actions/katello/host/hypervisors_update.rb +1 -1
  32. data/app/lib/actions/katello/host/register.rb +10 -4
  33. data/app/lib/actions/katello/repository/destroy.rb +2 -1
  34. data/app/lib/actions/katello/repository/import_applicability.rb +23 -0
  35. data/app/lib/actions/katello/repository/sync.rb +1 -8
  36. data/app/lib/actions/pulp/abstract_async_task.rb +8 -0
  37. data/app/lib/actions/pulp/consumer/content_install.rb +14 -0
  38. data/app/lib/actions/pulp/repository/create.rb +2 -1
  39. data/app/lib/actions/pulp/repository/delete_distributor.rb +18 -0
  40. data/app/lib/actions/pulp/repository/refresh.rb +25 -7
  41. data/app/lib/katello/api/v2/error_handling.rb +2 -2
  42. data/app/lib/katello/capsule_content.rb +11 -0
  43. data/app/lib/katello/errors.rb +1 -1
  44. data/app/mailers/katello/errata_mailer.rb +3 -3
  45. data/app/models/katello/activation_key.rb +6 -6
  46. data/app/models/katello/candlepin/product_content.rb +15 -0
  47. data/app/models/katello/concerns/content_facet_host_extensions.rb +13 -0
  48. data/app/models/katello/concerns/operatingsystem_extensions.rb +17 -1
  49. data/app/models/katello/concerns/pulp_database_unit.rb +3 -1
  50. data/app/models/katello/concerns/setting_extensions.rb +12 -0
  51. data/app/models/katello/content_view.rb +2 -2
  52. data/app/models/katello/erratum.rb +7 -0
  53. data/app/models/katello/glue/candlepin/product.rb +4 -0
  54. data/app/models/katello/glue/candlepin/subscription.rb +1 -1
  55. data/app/models/katello/glue/pulp/repo.rb +31 -3
  56. data/app/models/katello/host/content_facet.rb +43 -16
  57. data/app/models/katello/host/subscription_facet.rb +1 -0
  58. data/app/models/katello/pool.rb +6 -11
  59. data/app/models/katello/repository.rb +20 -15
  60. data/app/models/katello/subscription.rb +14 -0
  61. data/app/models/katello/sync_plan.rb +5 -0
  62. data/app/models/katello/system.rb +0 -10
  63. data/app/models/setting/katello.rb +2 -1
  64. data/app/presenters/katello/product_content_presenter.rb +16 -0
  65. data/app/services/katello/candlepin/consumer.rb +22 -1
  66. data/app/services/katello/repository_type_manager.rb +4 -0
  67. data/app/views/dashboard/_content_views_widget.html.erb +2 -2
  68. data/app/views/dashboard/_errata_widget.html.erb +1 -1
  69. data/app/views/dashboard/_host_collection_widget.html.erb +2 -2
  70. data/app/views/dashboard/_subscription_status_widget.html.erb +5 -5
  71. data/app/views/dashboard/_subscription_widget.html.erb +1 -1
  72. data/app/views/dashboard/_sync_widget.html.erb +2 -2
  73. data/app/views/foreman/unattended/finish-katello.erb +2 -0
  74. data/app/views/foreman/unattended/kickstart-katello-atomic.erb +42 -0
  75. data/app/views/foreman/unattended/kickstart-katello.erb +2 -0
  76. data/app/views/foreman/unattended/snippets/_subscription_manager_registration.erb +15 -9
  77. data/app/views/foreman/unattended/userdata-katello.erb +6 -1
  78. data/app/views/katello/api/v2/activation_keys/show.json.rabl +2 -2
  79. data/app/views/katello/api/v2/common/_metadata.json.rabl +1 -0
  80. data/app/views/katello/api/v2/content_facet/show.json.rabl +4 -0
  81. data/app/views/katello/api/v2/host_subscriptions/content_override.json.rabl +3 -0
  82. data/app/views/katello/api/v2/{systems/_content.json.rabl → host_subscriptions/product_content.json.rabl} +1 -3
  83. data/app/views/katello/api/v2/sync_plans/show.json.rabl +5 -1
  84. data/app/views/katello/errata_mailer/host_errata.html.erb +2 -2
  85. data/app/views/katello/errata_mailer/promote_errata.html.erb +1 -1
  86. data/app/views/katello/errata_mailer/promote_errata.text.erb +1 -1
  87. data/app/views/katello/errata_mailer/sync_errata.html.erb +1 -1
  88. data/app/views/katello/errata_mailer/sync_errata.text.erb +1 -1
  89. data/app/views/overrides/activation_keys/_host_environment_select.html.erb +21 -11
  90. data/config/katello.yaml.example +1 -0
  91. data/config/routes/api/v2.rb +0 -6
  92. data/config/routes/overrides.rb +3 -0
  93. data/db/migrate/20140117160939_refactor_content_views.rb +1 -0
  94. data/db/migrate/20140222022712_remove_provider_discovery.rb +2 -0
  95. data/db/migrate/20140502164009_rename_system_groups_to_host_collections.rb +7 -0
  96. data/db/migrate/20141210173220_create_docker_tables.rb +4 -3
  97. data/db/migrate/20151219203225_rename_index_repository_puppet_module.rb +1 -1
  98. data/db/migrate/20160203195736_remove_docker_image_schema.rb +1 -0
  99. data/db/migrate/20160317171813_change_activation_key_column_names.rb +11 -0
  100. data/db/migrate/20160323065901_increase_cdn_length.rb +11 -0
  101. data/db/migrate/20160404132250_remove_katello_from_notification_name.rb +26 -0
  102. data/db/seeds.d/103-provisioning_templates.rb +3 -1
  103. data/db/seeds.d/106-mail_notifications.rb +3 -3
  104. data/db/seeds.d/109-atomic_os.rb +11 -0
  105. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/activationKeyConsumed.filter.js +1 -1
  106. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-associations.controller.js +21 -9
  107. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-add-subscriptions.html +3 -3
  108. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-associations-content-hosts.html +41 -40
  109. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-details.html +1 -1
  110. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-info.html +7 -7
  111. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-subscriptions-list.html +3 -3
  112. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/new/new-activation-key.controller.js +1 -1
  113. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/new/views/activation-key-new.html +8 -8
  114. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.routes.js +2 -2
  115. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +0 -8
  116. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-errata.controller.js +19 -16
  117. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-errata.html +1 -1
  118. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details-info.controller.js +5 -3
  119. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details.controller.js +27 -3
  120. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-products.controller.js +79 -26
  121. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-add-subscriptions.html +3 -3
  122. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-details.html +32 -10
  123. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +8 -8
  124. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-products.html +11 -11
  125. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-subscriptions-list.html +3 -3
  126. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-promotion.html +1 -1
  127. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-puppet-modules.html +3 -3
  128. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/apply-errata.controller.js +1 -1
  129. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/errata-content-hosts.controller.js +33 -10
  130. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/errata-details-content-hosts.html +5 -5
  131. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/views/apply-errata-confirm.html +2 -2
  132. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/details/views/gpg-key-details.html +1 -1
  133. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/new/new-gpg-key.controller.js +7 -3
  134. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/views/host-collection-details.html +1 -1
  135. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/new/views/host-collection-new-form.html +1 -1
  136. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-subscription.factory.js +3 -1
  137. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/organizations/check-current-organization.run.js +3 -15
  138. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/organizations/fenced-pages.service.js +36 -0
  139. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/organizations/organization.factory.js +1 -1
  140. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/views/bulk-actions.html +14 -3
  141. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/views/product-details.html +1 -1
  142. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/views/product-repositories.html +13 -3
  143. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/repositories/details/views/repository-info.html +1 -1
  144. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/repositories/details/views/repository-manage-docker-manifests.html +3 -1
  145. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/repositories/details/views/repository-manage-packages.html +7 -5
  146. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/repositories/details/views/repository-manage-puppet-modules.html +5 -3
  147. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/manifest/manifest-import.controller.js +16 -6
  148. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-details-info.controller.js +7 -2
  149. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/views/sync-plan-details.html +1 -1
  150. data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +6 -0
  151. data/lib/katello/engine.rb +4 -3
  152. data/lib/katello/permissions/host_permissions.rb +1 -0
  153. data/lib/katello/version.rb +1 -1
  154. metadata +17 -11
  155. data/app/controllers/katello/concerns/api/v2/bulk_systems_extensions.rb +0 -39
  156. data/app/views/katello/api/v2/systems/content_override.json.rabl +0 -3
  157. data/app/views/katello/api/v2/systems/product_content.json.rabl +0 -3
  158. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-product-details.controller.js +0 -97
  159. data/lib/katello/tasks/upgrades/2.1/import_errata.rake +0 -45
  160. data/lib/katello/tasks/upgrades/2.2/update_gpg_key_urls.rake +0 -20
  161. data/lib/katello/tasks/upgrades/2.2/update_metadata_expire.rake +0 -18
@@ -50,7 +50,7 @@
50
50
 
51
51
  <span data-block="actions" bst-feature-flag="remote_actions">
52
52
 
53
- <div bst-modal="applySelected()">
53
+ <div bst-modal="applySelected()" model="host">
54
54
  <div data-block="modal-header" translate>Apply Errata to Content Host "{{host.name}}"?</div>
55
55
  <div data-block="modal-body" translate>Are you sure you want to apply Errata to content host "{{ host.name }}"?</div>
56
56
  <div data-block="modal-confirm-button" translate>Apply</div>
@@ -36,7 +36,9 @@ angular.module('Bastion.content-hosts').controller('ContentHostDetailsInfoContro
36
36
 
37
37
  $scope.host.$promise.then(function (host) {
38
38
  $scope.hostFactsAsObject = doubleColonNotationToObject(host.facts);
39
- $scope.originalEnvironment = host.content.lifecycle_environment;
39
+ if (host.hasContent()) {
40
+ $scope.originalEnvironment = host.content.lifecycle_environment;
41
+ }
40
42
  });
41
43
 
42
44
  $scope.successMessages = [];
@@ -122,10 +124,10 @@ angular.module('Bastion.content-hosts').controller('ContentHostDetailsInfoContro
122
124
  $scope.virtualGuestIds = function (host) {
123
125
  var ids = [];
124
126
  angular.forEach(host.subscription['virtual_guests'], function (guest) {
125
- ids.push('id:%s'.replace('%s', guest.id));
127
+ ids.push('name = %s'.replace('%s', guest.name));
126
128
  });
127
129
 
128
- return ids.join(" ");
130
+ return ids.join(" or ");
129
131
  };
130
132
  }]
131
133
  );
@@ -15,8 +15,8 @@
15
15
  * Provides the functionality for the content host details action pane.
16
16
  */
17
17
  angular.module('Bastion.content-hosts').controller('ContentHostDetailsController',
18
- ['$scope', '$state', '$q', 'translate', 'Host', 'Organization', 'CurrentOrganization', 'MenuExpander', 'ApiErrorHandler',
19
- function ($scope, $state, $q, translate, Host, Organization, CurrentOrganization, MenuExpander, ApiErrorHandler) {
18
+ ['$scope', '$state', '$q', 'translate', 'Host', 'HostSubscription', 'Organization', 'CurrentOrganization', 'GlobalNotification', 'MenuExpander', 'ApiErrorHandler',
19
+ function ($scope, $state, $q, translate, Host, HostSubscription, Organization, CurrentOrganization, GlobalNotification, MenuExpander, ApiErrorHandler) {
20
20
  $scope.menuExpander = MenuExpander;
21
21
  $scope.successMessages = [];
22
22
  $scope.errorMessages = [];
@@ -25,7 +25,8 @@ angular.module('Bastion.content-hosts').controller('ContentHostDetailsController
25
25
  loading: true
26
26
  };
27
27
 
28
- $scope.host = Host.get({id: $scope.$stateParams.hostId}, function () {
28
+ $scope.host = Host.get({id: $scope.$stateParams.hostId}, function (host) {
29
+ host.unregisterDelete = !host.hasSubscription(); //default to delete if no subscription
29
30
  $scope.panel.loading = false;
30
31
  }, function (response) {
31
32
  $scope.panel.loading = false;
@@ -116,5 +117,28 @@ angular.module('Bastion.content-hosts').controller('ContentHostDetailsController
116
117
 
117
118
  return deferred.promise;
118
119
  };
120
+
121
+ $scope.unregisterContentHost = function (host) {
122
+ var errorHandler = function (response) {
123
+ host.deleting = false;
124
+ GlobalNotification.setErrorMessage(translate('An error occured: %s').replace('%s', response.data.displayMessage));
125
+ };
126
+ host.deleting = true;
127
+
128
+ if (host.unregisterDelete) {
129
+ host.$delete(function () {
130
+ host.deleting = false;
131
+ GlobalNotification.setSuccessMessage(translate('Host %s has been deleted.').replace('%s', host.name));
132
+ $scope.removeRow(host.id);
133
+ $scope.transitionTo('content-hosts.index');
134
+ }, errorHandler);
135
+ } else {
136
+ HostSubscription.delete({id: host.id}, function () {
137
+ host.deleting = false;
138
+ GlobalNotification.setSuccessMessage(translate('Host %s has been unregistered.').replace('%s', host.name));
139
+ $scope.transitionTo('content-hosts.index');
140
+ }, errorHandler);
141
+ }
142
+ };
119
143
  }]
120
144
  );
@@ -4,43 +4,96 @@
4
4
  *
5
5
  * @requires $scope
6
6
  * @requires translate
7
- * @requires ContentHost
8
- * @requires Product
9
- * @requires CurrentOrganization
7
+ * @requires HostSubscription
10
8
  *
11
9
  * @description
12
10
  * Provides the functionality for the content-host products action pane.
13
11
  */
14
12
  angular.module('Bastion.content-hosts').controller('ContentHostProductsController',
15
- ['$scope', 'translate', 'ContentHost', 'Product', 'CurrentOrganization',
16
- function ($scope, translate, ContentHost, Product, CurrentOrganization) {
13
+ ['$scope', 'translate', 'HostSubscription',
14
+ function ($scope, translate, HostSubscription) {
15
+ var defaultOverride = "default",
16
+ enabledOverride = "1",
17
+ disabledOverride = "0";
17
18
 
18
- $scope.successMessages = [];
19
- $scope.errorMessages = [];
20
- $scope.displayArea = { working: true, isAvailableContent: false };
19
+ function processOverrides(overrides) {
20
+ var products = {};
21
21
 
22
- $scope.isAnyAvailableContent = function (products) {
23
- var isAvailableContent = false;
24
- angular.forEach(products, function (product) {
25
- if (product['available_content'].length > 0) {
26
- isAvailableContent = true;
22
+ angular.forEach(overrides, function (override) {
23
+ if (angular.isUndefined(products[override.product.name])) {
24
+ products[override.product.name] = [];
27
25
  }
26
+
27
+ override.enabledText = $scope.getEnabledText(override.enabled, override.enabled_override);
28
+ products[override.product.name].push(override);
28
29
  });
29
- return isAvailableContent;
30
+
31
+ $scope.products = products;
32
+ $scope.displayArea.isAvailableContent = Object.keys(products).length !== 0;
33
+ $scope.displayArea.working = false;
34
+ }
35
+
36
+ $scope.getEnabledText = function (enabled, overrideEnabled) {
37
+ var enabledText;
38
+ overrideEnabled = overrideEnabled + "";
39
+
40
+ if (overrideEnabled === defaultOverride) {
41
+ enabledText = enabled ? translate("Yes (Default)") : translate("No (Default)");
42
+ } else if (overrideEnabled === enabledOverride) {
43
+ enabledText = translate("Override to Yes");
44
+ } else {
45
+ enabledText = translate("Override to No");
46
+ }
47
+
48
+ return enabledText;
30
49
  };
31
50
 
32
- $scope.contentHost.$promise.then(function () {
33
- ContentHost.products({id: $scope.contentHost.uuid,
34
- 'organization_id': CurrentOrganization,
35
- enabled: true,
36
- 'full_result': true,
37
- 'include_available_content': true
38
- }, function (response) {
39
- $scope.products = response.results;
40
- $scope.displayArea.isAvailableContent = $scope.isAnyAvailableContent($scope.products);
41
- $scope.displayArea.working = false;
42
- });
43
- });
51
+ $scope.overrideEnableChoices = function (override) {
52
+ var choices;
53
+ if (override.enabled === true) {
54
+ choices = [
55
+ {name: $scope.getEnabledText(true, defaultOverride), id: "default"},
56
+ {name: $scope.getEnabledText(null, 0), id: disabledOverride}
57
+ ];
58
+ } else {
59
+ choices = [
60
+ {name: $scope.getEnabledText(false, defaultOverride), id: "default"},
61
+ {name: $scope.getEnabledText(null, 1), id: enabledOverride}
62
+ ];
63
+ }
64
+ return choices;
65
+ };
44
66
 
67
+ $scope.success = function (content) {
68
+ content.enabledText = $scope.getEnabledText(content.enabled, content.enabled_override);
69
+ $scope.successMessages.push(translate('Updated override for %y to "%x".')
70
+ .replace('%x', content.enabledText).replace("%y", content.content.name));
71
+ };
72
+
73
+ $scope.error = function (error) {
74
+ $scope.errorMessages.push(error.data.errors);
75
+ };
76
+
77
+ $scope.saveContentOverride = function (content) {
78
+ var params = {'content_label': content.content.label,
79
+ name: "enabled",
80
+ value: content.enabled_override
81
+ };
82
+
83
+ HostSubscription.contentOverride({id: $scope.host.id}, params,
84
+ function () {
85
+ $scope.success(content);
86
+ },
87
+ $scope.error);
88
+ };
89
+
90
+ $scope.successMessages = [];
91
+ $scope.errorMessages = [];
92
+ $scope.displayArea = { working: true, isAvailableContent: false };
93
+
94
+ HostSubscription.productContent({id: $scope.$stateParams.hostId, 'full_result': true,
95
+ 'include_available_content': true }, function (response) {
96
+ processOverrides(response.results);
97
+ });
45
98
  }]
46
99
  );
@@ -34,12 +34,12 @@
34
34
 
35
35
  <tbody>
36
36
  <tr bst-table-row ng-repeat-start="(name, subscriptions) in groupedSubscriptions">
37
- <td class="row-select"></td>
38
- <td bst-table-cell colspan="8">
39
- <a href='/subscriptions/{{ subscription.id }}/info'>
37
+ <td class="row-select">
38
+ <a href='/subscriptions/{{ subscription.id }}/info' class="confined-text">
40
39
  {{ name }}
41
40
  </a>
42
41
  </td>
42
+ <td bst-table-cell colspan="8"></td>
43
43
  </tr>
44
44
  <tr bst-table-row ng-repeat-end ng-repeat="subscription in subscriptions" row-select="subscription">
45
45
  <td bst-table-cell>
@@ -10,22 +10,44 @@
10
10
 
11
11
  <div ng-hide="panel.error">
12
12
  <header class="details-header">
13
- <h2 class="fl" translate>Content Host {{ contentHost.name }}</h2>
13
+ <h2 class="fl" translate>Content Host {{ host.name }}</h2>
14
14
 
15
15
  <div class="fr">
16
-
17
- <div bst-modal="unregisterContentHost(contentHost)">
16
+ <div bst-modal="unregisterContentHost(host)" model="host">
18
17
  <div data-block="modal-header" translate>
19
- Unregister Content Host "{{contentHost.name}}"?
18
+ Unregister Host "{{host.name}}"?
20
19
  </div>
21
- <div data-block="modal-body" translate>
22
- Are you sure you want to unregister content host "{{ contentHost.name }}"?
20
+ <div data-block="modal-body">
21
+ <p translate>
22
+ Unregister Options:
23
+ </p>
24
+
25
+ <p ng-show="host.hasSubscription()">
26
+ <label>
27
+ <input name="delete"
28
+ ng-model="host.unregisterDelete"
29
+ ng-value="false"
30
+ type="radio" />
31
+ Unregister the host as a subscription consumer. Provisioning and configuration information is preserved.
32
+ </label>
33
+ </p>
34
+ <p>
35
+ <label>
36
+ <input name="delete"
37
+ ng-model="host.unregisterDelete"
38
+ ng-value="true"
39
+ type="radio" />
40
+ Completely deletes the host record and removes all reporting, provisioning, and configuration information.
41
+ </label>
42
+ </p>
23
43
  </div>
24
- </div>
44
+ </div>
25
45
 
26
46
  <button class="btn btn-default"
27
- ng-hide="denied('destroy_hosts', contentHost)"
28
- ng-click="openModal()" translate>Unregister Content Host</button>
47
+ ng-disabled="host.deleting"
48
+ ng-hide="denied('destroy_hosts', host)"
49
+ ng-click="openModal()" translate>Unregister Host</button>
50
+
29
51
  <button class="btn btn-default" ui-sref="content-hosts.index">
30
52
  <i class="fa fa-remove"></i>
31
53
  {{ "Close" | translate }}
@@ -97,7 +119,7 @@
97
119
  Product Content
98
120
  </a>
99
121
  </li>
100
- <li ng-repeat="menuItem in menuExpander.getMenu('contentHost')">
122
+ <li ng-repeat="menuItem in menuExpander.getMenu('host')">
101
123
  <a href="{{ menuItem.url }}">
102
124
  {{ menuItem.label }}
103
125
  </a>
@@ -1,11 +1,11 @@
1
1
  <span page-title ng-model="host">{{ 'Content Host' | translate }} {{ host.name }}</span>
2
2
 
3
3
  <section>
4
- <div class="details fl" ng-hide="host.hasContent()">
4
+ <div class="details fl" ng-hide="host.hasContent() || host.hasSubscription()">
5
5
  <div data-extend-template="common/views/registration.html"></div>
6
6
  </div>
7
7
 
8
- <div class="details fl" ng-show="host.hasContent()">
8
+ <div class="details fl" ng-show="host.hasContent() || host.hasSubscription()">
9
9
  <section>
10
10
  <h4 translate>Basic Information</h4>
11
11
 
@@ -50,21 +50,21 @@
50
50
  </span>
51
51
  </div>
52
52
 
53
- <div ng-show="host.virtual_guests" class="detail">
53
+ <div ng-show="host.subscription.virtual_guests" class="detail">
54
54
  <span class="info-label" translate>Virtual Guests</span>
55
55
  <div class="info-value">
56
56
  <a ng-click="reloadSearch(virtualGuestIds(host))"
57
- translate translate-n="host.virtual_guests.length"
58
- translate-plural="{{ host.virtual_guests.length }} Content Hosts">
57
+ translate translate-n="host.subscription.virtual_guests.length"
58
+ translate-plural="{{ host.subscription.virtual_guests.length }} Content Hosts">
59
59
  1 Content Host
60
60
  </a>
61
61
  </div>
62
62
  </div>
63
63
 
64
- <div ng-show="host.virtual_host" class="detail">
64
+ <div ng-show="host.subscription.virtual_host" class="detail">
65
65
  <span class="info-label" translate>Virtual Host</span>
66
66
  <div class="info-value">
67
- <a ui-sref="content-hosts.details.info({contentHostId: host.subscription.virtual_host.uuid })">{{ host.virtual_host.name }}</a>
67
+ <a ui-sref="content-hosts.details.info({hostId: host.subscription.virtual_host.id })">{{ host.subscription.virtual_host.name }}</a>
68
68
  </div>
69
69
  </div>
70
70
 
@@ -143,7 +143,7 @@
143
143
  <div class="divider"></div>
144
144
  </section>
145
145
 
146
- <section>
146
+ <section ng-show="host.hasContent()">
147
147
  <h4 translate>Installed Products</h4>
148
148
 
149
149
  <p translate ng-show="!host.subscription.installed_products || host.subscription.installed_products.length == 0">
@@ -22,30 +22,30 @@
22
22
  This Content Host is not attached to any subscriptions that provide content
23
23
  </div>
24
24
 
25
- <div ng-repeat="product in products" ng-hide="product.available_content.length < 1"
26
- ng-controller="ContentHostProductDetailsController" ng-init="productDetails(product)">
25
+ <div ng-repeat="(product_name, overrides) in products">
26
+
27
27
  <i ng-class="{'fa fa-plus': !expanded, 'fa fa-minus': expanded}" class="expand-icon"
28
28
  ng-click="expanded = !expanded">
29
- <b>{{ product.name }}</b>
29
+ <b>{{ product_name }}</b>
30
30
  </i>
31
31
 
32
32
  <div class="row" ng-show="expanded">
33
- <div class="col-md-11 col-md-offset-1" ng-show="details.available_content.length < 1"
33
+ <div class="col-md-11 col-md-offset-1" ng-show="contents.length < 1"
34
34
  translate>
35
35
  No repository content.
36
36
  </div>
37
37
 
38
- <div class="col-md-11 col-md-offset-1" ng-repeat="content in product.available_content">
39
- <h4><u>{{ content.content.name }}</u></h4>
38
+ <div class="col-md-11 col-md-offset-1" ng-repeat="override in overrides">
39
+ <h4><u>{{ override.content.name }}</u></h4>
40
40
 
41
41
  <div class="detail row">
42
42
  <span class="col-sm-4" translate>Enabled?</span>
43
43
  <span class="col-sm-3"
44
- bst-edit-select="content.enabledText"
45
- readonly="denied('edit_hosts', contentHost)"
46
- selector="content.overrideEnabled"
47
- options="overrideEnableChoices(content)"
48
- on-save="saveContentOverride(content)">
44
+ bst-edit-select="override.enabledText"
45
+ readonly="denied('edit_hosts', host)"
46
+ selector="override.enabled_override"
47
+ options="overrideEnableChoices(override)"
48
+ on-save="saveContentOverride(override)">
49
49
  </span>
50
50
  </div>
51
51
  </div>
@@ -45,12 +45,12 @@
45
45
 
46
46
  <tbody>
47
47
  <tr bst-table-row ng-repeat-start="(name, subscriptions) in groupedSubscriptions | groupedFilter: subscriptionSearch">
48
- <td class="row-select"></td>
49
- <td bst-table-cell colspan="8">
50
- <a href='/subscriptions/{{ subscription.id }}/info'>
48
+ <td class="row-select">
49
+ <a href='/subscriptions/{{ subscription.id }}/info' class="confined-text">
51
50
  {{ name }}
52
51
  </a>
53
52
  </td>
53
+ <td bst-table-cell colspan="8"></td>
54
54
  </tr>
55
55
  <tr bst-table-row ng-repeat-end ng-repeat="subscription in subscriptions" row-select="subscription">
56
56
  <td bst-table-cell>{{ subscription | subscriptionAttachAmountFilter}}</td>
@@ -40,7 +40,7 @@
40
40
  Cancel
41
41
  </a>
42
42
 
43
- <div bst-modal="promote()">
43
+ <div bst-modal="promote()" model="selectedEnvironment" model="selectedEnvironment">
44
44
  <div data-block="modal-header" translate>Force Promote?</div>
45
45
  <div data-block="modal-body" translate>Promote version to {{ selectedEnvironment.name }}?<br /><br />{{ suggestedEnvironmentMessage() }}</div>
46
46
  <div data-block="modal-confirm-button" translate>Promote</div>
@@ -8,15 +8,15 @@
8
8
  <tr bst-table-head>
9
9
  <th bst-table-column translate>Name</th>
10
10
  <th bst-table-column translate>Author</th>
11
- <th bst-table-column translate>Version</th>
12
11
  </tr>
13
12
  </thead>
14
13
 
15
14
  <tbody>
16
15
  <tr bst-table-row ng-repeat="puppetModule in detailsTable.rows">
17
- <td bst-table-cell>{{ puppetModule.name }}</td>
16
+ <td bst-table-cell>
17
+ <a ui-sref="puppet-modules.details.info({puppetModuleId: puppetModule.id})">{{ puppetModule.name }}-{{ puppetModule.version }}</a>
18
+ </td>
18
19
  <td bst-table-cell>{{ puppetModule.author }}</td>
19
- <td bst-table-cell>{{ puppetModule.version }}</td>
20
20
  </tr>
21
21
  </tbody>
22
22
  </table>
@@ -81,7 +81,7 @@ angular.module('Bastion.errata').controller('ApplyErrataController',
81
81
  });
82
82
 
83
83
  if ($scope.applyErrata) {
84
- params['update_systems'] = $scope.selectedContentHosts;
84
+ params['update_hosts'] = $scope.selectedContentHosts;
85
85
  }
86
86
 
87
87
  error = function (response) {
@@ -12,41 +12,64 @@
12
12
  * Provides the functionality for the available host collection details action pane.
13
13
  */
14
14
  angular.module('Bastion.errata').controller('ErrataContentHostsController',
15
- ['$scope', 'Nutupane', 'ContentHost', 'Environment', 'CurrentOrganization',
16
- function ($scope, Nutupane, ContentHost, Environment, CurrentOrganization) {
15
+ ['$scope', 'Nutupane', 'Host', 'Environment', 'CurrentOrganization',
16
+ function ($scope, Nutupane, Host, Environment, CurrentOrganization) {
17
17
  var nutupane, params;
18
18
 
19
19
  $scope.successMessages = [];
20
20
  $scope.errorMessages = [];
21
21
 
22
+ $scope.restrictInstallable = false;
23
+
22
24
  params = {
23
25
  'erratum_id': $scope.$stateParams.errataId,
24
26
  'organization_id': CurrentOrganization
25
27
  };
26
28
 
27
- if (!params['erratum_id']) {
28
- params['errata_ids'] = _.pluck($scope.table.getSelected(), 'id');
29
- }
30
-
31
- nutupane = new Nutupane(ContentHost, params, 'getPost');
29
+ nutupane = new Nutupane(Host, params);
32
30
  nutupane.table.closeItem = function () {};
33
31
  nutupane.enableSelectAllResults();
34
32
 
35
33
  $scope.nutupane = nutupane;
36
34
  $scope.detailsTable = nutupane.table;
35
+ $scope.nutupane.searchTransform = function(term) {
36
+ var addition = '( ' + $scope.errataSearchString($scope.restrictInstallable) + ' )';
37
+ if (angular.isDefined($scope.environment_id)) {
38
+ addition = addition + ' and lifecycle_environment_id = ' + $scope.environmentId;
39
+ }
40
+
41
+ if (term === "" || angular.isUndefined(term)) {
42
+ return addition;
43
+ }
44
+ return term + ' and ' + addition;
45
+ };
37
46
 
38
47
  Environment.queryUnpaged(function (response) {
39
48
  $scope.environments = response.results;
40
49
  });
41
50
 
42
51
  $scope.toggleInstallable = function () {
43
- nutupane.table.params['erratum_restrict_installable'] = $scope.errata.showInstallable;
44
52
  nutupane.refresh();
45
53
  };
46
54
 
55
+ $scope.errataSearchString = function(installable) {
56
+ var searchTerm = installable ? 'installable_errata' : 'applicable_errata',
57
+ searchStatements, errataIds;
58
+
59
+ if ($scope.errata) {
60
+ errataIds = [$scope.errata['errata_id']];
61
+ } else {
62
+ errataIds = _.pluck($scope.table.getSelected(), 'errata_id');
63
+ }
64
+
65
+ searchStatements = _.map(errataIds, function(errataId) {
66
+ return searchTerm + ' = "' + errataId + '"';
67
+ });
68
+ return searchStatements.join(" or ");
69
+ };
70
+
47
71
  $scope.selectEnvironment = function (environmentId) {
48
- params['environment_id'] = environmentId;
49
- nutupane.setParams(params);
72
+ $scope.environmentId = environmentId;
50
73
  nutupane.refresh();
51
74
  };
52
75