foreman_scc_manager 1.8.6 → 1.8.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a0b1fc3df2a088cefb4344e848995955fb81a5478cf4500268c68f32ccf0bec
4
- data.tar.gz: ae3c19f91491ba06228c59f6314e28d5c8525d8936e89c5a82af092a71dd4e85
3
+ metadata.gz: 843165a6092fcb04bf69d13131ae44acb02478ce347084c160a8f61891770eba
4
+ data.tar.gz: 892025747b9572a4b31d25f4c96ab28ea9af0099ef3302fe8c7aec07935b588b
5
5
  SHA512:
6
- metadata.gz: 57f473572bfc7342b44765343b168e94bb55ba479bb17d7a9236703bcb5cb7f2cad615b16d76934790a739037eb5b724e70ff637c17e7d95aaaa6dc993eb3bd2
7
- data.tar.gz: 6569d327e0ccb6c251a823ae3af6a3bd1a40d44edc9878fd4b538303ec242a8f594dffd0e8fb951ae371c8b22ae13f16a0120ac78a6f9cb4a5bf2dabd33781fb
6
+ metadata.gz: 0cb42eeb656e4a0cca5c93d7c83e0fed14fa73a9b0e7f2ad0ddcb07b007156405f0e91d968e4eb38aafd6376551f334340bda0a4ff9d632d13d4818766e7eb75
7
+ data.tar.gz: 700546d7abfdc1ff7fc12f452c69bb6ca8869c41b63ae4e37fef99541dc229bf2287de3435ecd8c09dee32cb79465b8c896af09c78b4d0d498209e35c8a347cf
@@ -35,7 +35,7 @@ module Api
35
35
  param :base_url, String, :required => false, :desc => N_('URL of SUSE for scc_account')
36
36
  param :interval, ['never', 'daily', 'weekly', 'monthy'], :desc => N_('Interval for syncing scc_account')
37
37
  param :sync_date, String, :desc => N_('Date and time relative to which the sync interval is run')
38
- param :katello_gpg_key_id, :identifier, :required => false, :desc => N_('Associated gpg key of scc_account')
38
+ param :katello_gpg_key_id, :identifier, :required => false, :desc => N_('Associated GPG key of scc_account')
39
39
  end
40
40
  end
41
41
 
@@ -12,24 +12,34 @@ module Actions
12
12
  :product_description => scc_product.pretty_description,
13
13
  :organization_id => scc_product.organization.id,
14
14
  :gpg_key => scc_product.scc_account.katello_gpg_key_id)
15
+ katello_repos = {}
15
16
  scc_product.scc_repositories.each do |repo|
16
17
  arch = scc_product.arch || 'noarch'
17
- plan_action(CreateRepository,
18
- :product_id => product_create_action.output[:product_id],
19
- :uniq_name => repo.uniq_name(scc_product),
20
- :pretty_repo_name => repo.pretty_name,
21
- :url => repo.full_url,
22
- :arch => arch)
18
+ repo_create_action = plan_action(CreateRepository,
19
+ :product_id => product_create_action.output[:product_id],
20
+ :uniq_name => repo.uniq_name(scc_product),
21
+ :pretty_repo_name => repo.pretty_name,
22
+ :url => repo.full_url,
23
+ :arch => arch)
24
+ katello_repos[repo.id] = repo_create_action.output[:katello_root_repository_id]
23
25
  end
26
+ # connect action to resource (=> make parameters accessable in input)
24
27
  action_subject(scc_product, product_id: product_create_action.output[:product_id])
28
+ input.update(katello_repos: katello_repos)
25
29
  plan_self
26
30
  end
27
31
  end
28
32
 
29
33
  def finalize
34
+ # connect Scc products and Katello products
30
35
  scc_product = SccProduct.find(input[:scc_product][:id])
31
36
  product = ::Katello::Product.find(input[:product_id])
32
37
  scc_product.update!(product: product)
38
+ # extract Katello repo ids from input hash and store to database
39
+ input[:katello_repos].each do |scc_repo_id, katello_root_repository_id|
40
+ scc_repo = SccRepository.find(scc_repo_id)
41
+ scc_repo.update!(katello_root_repository_id: katello_root_repository_id)
42
+ end
33
43
  end
34
44
 
35
45
  def humanized_name
@@ -74,7 +84,9 @@ module Actions
74
84
  repository = product.add_repo(repo_param)
75
85
  repository.mirror_on_sync = true
76
86
  repository.verify_ssl_on_sync = true
77
- trigger(::Actions::Katello::Repository::CreateRoot, repository)
87
+ trigger(::Actions::Katello::Repository::CreateRoot, repository).tap do
88
+ output[:katello_root_repository_id] = repository.id
89
+ end
78
90
  end
79
91
  end
80
92
  end
@@ -1,21 +1,21 @@
1
1
  module Actions
2
2
  module SccManager
3
+ # for dynflow documentation see here: https://dynflow.github.io/documentation/
3
4
  class Sync < Actions::EntryAction
4
5
  def plan(scc_account)
5
6
  ::Foreman::Logging.logger('foreman_scc_manager')
6
7
  .info("Initiating 'sync' for SccAccount '#{scc_account.name}'.")
7
8
  action_subject(scc_account)
8
9
  sequence do
9
- sync_repo_action = plan_action(::Actions::SccManager::SyncRepositories, scc_account)
10
- sync_prod_action = plan_action(::Actions::SccManager::SyncProducts, scc_account)
11
- plan_self(repo_status: sync_repo_action.output[:status], prod_status: sync_prod_action.output[:status])
10
+ plan_action(::Actions::SccManager::SyncRepositories, scc_account)
11
+ plan_action(::Actions::SccManager::SyncProducts, scc_account)
12
+ plan_self
12
13
  end
13
14
  end
14
15
 
15
16
  def finalize
17
+ # this is only executed if run actions of SyncRepositories and SyncProducts were successful
16
18
  scc_account = SccAccount.find(input[:scc_account][:id])
17
- raise 'Updating failed' unless input[:repo_status] == 'SUCCESS' && input[:prod_status] == 'SUCCESS'
18
-
19
19
  scc_account.update! synced: Time.current
20
20
  end
21
21
 
@@ -13,22 +13,19 @@ module Actions
13
13
  end
14
14
 
15
15
  def run
16
- output[:status] = 'SUCCESS'
17
- begin
18
- products = ::SccManager.get_scc_data(input.fetch(:base_url),
19
- '/connect/organizations/products',
20
- input.fetch(:login),
21
- decrypt_field(input.fetch(:password)))
22
- output[:data] = ::SccManager.sanitize_products(products).values
23
- rescue StandardError => e
24
- ::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Products: #{e}"
25
- output[:error] = e.to_s
26
- output[:status] = 'FAILURE'
27
- end
16
+ products = ::SccManager.get_scc_data(input.fetch(:base_url),
17
+ '/connect/organizations/products',
18
+ input.fetch(:login),
19
+ decrypt_field(input.fetch(:password)))
20
+ output[:data] = ::SccManager.sanitize_products(products).values
21
+ rescue StandardError => e
22
+ ::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Products: #{e}"
23
+ error! e.to_s
28
24
  end
29
25
 
30
26
  def finalize
31
- SccAccount.find(input.fetch(:id)).update_scc_products(output.fetch(:data)) if output[:status] == 'SUCCESS'
27
+ # this is only executed if 'run' succeeds
28
+ SccAccount.find(input.fetch(:id)).update_scc_products(output.fetch(:data))
32
29
  end
33
30
 
34
31
  def rescue_strategy
@@ -12,22 +12,18 @@ module Actions
12
12
  end
13
13
 
14
14
  def run
15
- output[:status] = 'IN PROGRESS'
16
- begin
17
- output[:data] = ::SccManager.get_scc_data(input[:base_url],
18
- '/connect/organizations/repositories',
19
- input[:login],
20
- decrypt_field(input[:password]))
21
- output[:status] = 'SUCCESS'
22
- rescue StandardError => e
23
- ::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Repositories: #{e}"
24
- output[:error] = e.to_s
25
- output[:status] = 'FAILURE'
26
- end
15
+ output[:data] = ::SccManager.get_scc_data(input[:base_url],
16
+ '/connect/organizations/repositories',
17
+ input[:login],
18
+ decrypt_field(input[:password]))
19
+ rescue StandardError => e
20
+ ::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Repositories: #{e}"
21
+ error! e.to_s
27
22
  end
28
23
 
29
24
  def finalize
30
- SccAccount.find(input[:scc_account][:id]).update_scc_repositories(output[:data]) if output[:status] == 'SUCCESS'
25
+ # this is only executed if 'run' succeeds
26
+ SccAccount.find(input[:scc_account][:id]).update_scc_repositories(output[:data])
31
27
  end
32
28
 
33
29
  def rescue_strategy
@@ -176,6 +176,8 @@ class SccAccount < ApplicationRecord
176
176
 
177
177
  def update_scc_repositories(upstream_repositories)
178
178
  upstream_repo_ids = []
179
+ # initially invalidate all repositories and validate them during update
180
+ invalidated_repos = invalidate_subscription_status(scc_repositories)
179
181
  # import repositories
180
182
  upstream_repositories.each do |ur|
181
183
  cached_repository = scc_repositories.find_or_initialize_by(scc_id: ur['id'])
@@ -187,11 +189,21 @@ class SccAccount < ApplicationRecord
187
189
  cached_repository.installer_updates = ur['installer_updates']
188
190
  # should be called after all attributes are set in case of dependencies (currently: description)
189
191
  cached_repository.name = cached_repository.pretty_name
192
+ cached_repository.subscription_valid = true
190
193
  cached_repository.save!
191
194
  upstream_repo_ids << ur['id']
195
+ # set invalidated record to true, if exists
196
+ invalidated_repos = revalidate_subscription_status(invalidated_repos, ur[id])
192
197
  end
193
198
  ::Foreman::Logging.logger('foreman_scc_manager').debug "Found #{upstream_repo_ids.length} repositories"
194
- # delete repositories beeing removed upstream
199
+
200
+ # all scc repos that are kept but not available upstream need to be marked invalid
201
+ # subscription_valid can be set to nil
202
+ to_invalidate = invalidated_repos.select { |ir| ir.katello_root_repository_id.present? && !ir.subscription_valid }
203
+ ::Foreman::Logging.logger('foreman_scc_manager').debug "Invalidating #{to_invalidate.count} expired repositories"
204
+ invalidate_subscription_status(to_invalidate, true)
205
+
206
+ # delete repositories being removed upstream and that are not subscribed to
195
207
  to_delete = scc_repositories.where.not(scc_id: upstream_repo_ids)
196
208
  ::Foreman::Logging.logger('foreman_scc_manager').debug "Deleting #{to_delete.count} old repositories"
197
209
  to_delete.destroy_all
@@ -199,6 +211,8 @@ class SccAccount < ApplicationRecord
199
211
 
200
212
  def update_scc_products(upstream_products)
201
213
  upstream_product_ids = []
214
+ # initially invalidate all products and validate them during update
215
+ invalidated_products = invalidate_subscription_status(scc_products)
202
216
  # import products
203
217
  upstream_products.each do |up|
204
218
  cached_product = scc_products.find_or_initialize_by(scc_id: up['id'])
@@ -212,12 +226,22 @@ class SccAccount < ApplicationRecord
212
226
  # name should be set after friendly_name because it depends on friendly_name
213
227
  cached_product.name = cached_product.pretty_name
214
228
  cached_product.description = cached_product.pretty_description
229
+ cached_product.subscription_valid = true
215
230
  cached_product.save!
216
231
  upstream_product_ids << up['id']
232
+ # set invalidated record to true, if exists
233
+ invalidated_products = revalidate_subscription_status(invalidated_products, up['id'])
217
234
  end
218
235
  ::Foreman::Logging.logger('foreman_scc_manager').debug "Found #{upstream_product_ids.length} products"
219
- # delete products beeing removed upstream
220
- to_delete = scc_products.where.not(scc_id: upstream_product_ids)
236
+
237
+ # all scc products that are kept but not available upstream need to be marked invalid
238
+ # subscription_valid can be set to nil
239
+ to_invalidate = invalidated_products.select { |ip| ip.product_id.present? && !ip.subscription_valid }
240
+ ::Foreman::Logging.logger('foreman_scc_manager').debug "Invalidating #{to_invalidate.count} expired products"
241
+ invalidate_subscription_status(to_invalidate, true)
242
+
243
+ # delete products being removed upstream and that are not subscribed to
244
+ to_delete = scc_products.where.not(scc_id: upstream_product_ids).where(product_id: nil)
221
245
  ::Foreman::Logging.logger('foreman_scc_manager').debug "Deleting #{to_delete.count} old products"
222
246
  to_delete.destroy_all
223
247
  # rewire product to product relationships
@@ -230,4 +254,32 @@ class SccAccount < ApplicationRecord
230
254
  end
231
255
  end
232
256
  end
257
+
258
+ # validate the subscription status of a product/repo
259
+ # no saving to database
260
+ # params: elements: scc repos or products, Array or ActiveRecord_(*)
261
+ # scc_id: scc_id of the element that should be revalidated
262
+ # return: elements where for the element with scc_id subscription_valid is true
263
+ def revalidate_subscription_status(elements, scc_id)
264
+ return nil if elements.nil?
265
+
266
+ revalidate = elements.find { |e| e.scc_id == scc_id }
267
+ revalidate.subscription_valid = true unless revalidate.nil?
268
+ # return modified list
269
+ elements
270
+ end
271
+
272
+ # set all products/repos invalid
273
+ # params: items_to_invalidate: ActiveRecord_(*)
274
+ # save_record: store in database or not (default)
275
+ # return: ActiveRecord elements with invalidated subscription status
276
+ def invalidate_subscription_status(items_to_invalidate, save_record = false)
277
+ if items_to_invalidate.present?
278
+ items_to_invalidate.each do |inv|
279
+ inv.subscription_valid = false
280
+ inv.save! if save_record
281
+ end
282
+ end
283
+ items_to_invalidate
284
+ end
233
285
  end
@@ -4,6 +4,7 @@ class SccRepository < ApplicationRecord
4
4
  self.include_root_in_json = false
5
5
 
6
6
  belongs_to :scc_account
7
+ belongs_to :katello_root_repository, class_name: 'Katello::RootRepository'
7
8
  has_one :organization, through: :scc_account
8
9
  has_and_belongs_to_many :scc_products
9
10
 
@@ -12,7 +13,7 @@ class SccRepository < ApplicationRecord
12
13
  end
13
14
 
14
15
  def uniq_name(scc_product)
15
- scc_product.uniq_name + ' ' + description
16
+ scc_product.scc_id.to_s + ' ' + description
16
17
  end
17
18
 
18
19
  def pretty_name
@@ -21,13 +22,10 @@ class SccRepository < ApplicationRecord
21
22
 
22
23
  def token_changed_callback
23
24
  User.current ||= User.anonymous_admin
24
- scc_products.where.not(product: nil).find_each do |sp|
25
- reponame = uniq_name(sp)
26
- repository = sp.product.root_repositories.find_by(name: reponame)
27
- unless repository.nil? || repository.url == full_url
28
- ::Foreman::Logging.logger('foreman_scc_manager').info "Update URL-token for repository '#{reponame}'."
29
- ForemanTasks.async_task(::Actions::Katello::Repository::Update, repository, url: full_url)
30
- end
31
- end
25
+ repo = self.katello_root_repository
26
+ return if repo.nil? || repo.url == full_url
27
+
28
+ ::Foreman::Logging.logger('foreman_scc_manager').info "Update URL-token for repository '#{repo.name}'."
29
+ ForemanTasks.async_task(::Actions::Katello::Repository::Update, repo, url: full_url)
32
30
  end
33
31
  end
@@ -12,6 +12,11 @@
12
12
  <%= check_box_tag("scc_account[scc_subscribe_product_ids][]", scc_product.id, false) %>
13
13
  <%= scc_product.pretty_name %>
14
14
  <% end %>
15
+ <% unless scc_product.subscription_valid? %>
16
+ <span style="color:red">
17
+ <%= _('(WARNING: Please check your SUSE subscription)') %>
18
+ </span>
19
+ <% end %>
15
20
  </span>
16
21
  <% if scc_product.scc_extensions.any? %>
17
22
  <ul style='padding-left: 20px;'>
@@ -0,0 +1,6 @@
1
+ class AddSubscriptionValidToSccProductsAndRepos < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :scc_products, :subscription_valid, :boolean, null: true
4
+ add_column :scc_repositories, :subscription_valid, :boolean, null: true
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ class AddRootRepositoryIdToSccRepository < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :scc_repositories, :katello_root_repository_id, :integer, index: true, null: true
4
+ add_foreign_key :scc_repositories, :katello_root_repositories, column: :katello_root_repository_id, on_delete: :nullify
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ class ConnectKatelloRootRepositoryToSccRepository < ActiveRecord::Migration[5.2]
2
+ def up
3
+ SccProduct.where.not(product_id: nil).each do |scc_p|
4
+ # extract all katello root repository ids from subscribed products
5
+ katello_root_repositories = scc_p.product.root_repositories.map { |r| [r.label, r.id] }.to_h
6
+ # match scc repository and katello repository names
7
+ # katello repository name can be
8
+ # 1) equal to scc repo name
9
+ # 2) equal to scc product id + scc product name + scc repo name
10
+ scc_p.scc_repositories.each do |scc_r|
11
+ katello_root_repositories.each do |katello_label, katello_id|
12
+ scc_r.update!(katello_root_repository_id: katello_id) if katello_label.end_with?(::Katello::Util::Model.labelize(scc_r.name))
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module ForemanSccManager
2
- VERSION = '1.8.6'.freeze
2
+ VERSION = '1.8.7'.freeze
3
3
  end
@@ -0,0 +1,574 @@
1
+ # SOME DESCRIPTIVE TITLE.
2
+ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3
+ # This file is distributed under the same license as the foreman_scc_manager package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5
+ #
6
+ # Translators:
7
+ # Wiederoder <stefanwiederoder@googlemail.com>, 2019
8
+ # Bryan Kearney <bryan.kearney@gmail.com>, 2019
9
+ # simon11 <simon.stieger.98@live.de>, 2019
10
+ # Crited <Alexander.Stoll@netways.de>, 2019
11
+ # Michael Moll, 2019
12
+ # Lukas K. <kallies@puzzle.ch>, 2019
13
+ # Markus Bucher <bucher@atix.de>, 2019
14
+ #
15
+ msgid ""
16
+ msgstr ""
17
+ "Project-Id-Version: foreman_scc_manager 1.7.0\n"
18
+ "Report-Msgid-Bugs-To: \n"
19
+ "PO-Revision-Date: 2019-10-17 13:28+0000\n"
20
+ "Last-Translator: Markus Bucher <bucher@atix.de>, 2019\n"
21
+ "Language-Team: German (https://www.transifex.com/foreman/teams/114/de/)\n"
22
+ "MIME-Version: 1.0\n"
23
+ "Content-Type: text/plain; charset=UTF-8\n"
24
+ "Content-Transfer-Encoding: 8bit\n"
25
+ "Language: de\n"
26
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
27
+
28
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:15
29
+ msgid "List all scc_accounts"
30
+ msgstr ""
31
+
32
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:24
33
+ msgid "Show scc_account"
34
+ msgstr ""
35
+
36
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:32
37
+ msgid "Name of the scc_account"
38
+ msgstr ""
39
+
40
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:33 ../app/controllers/api/v2/scc_accounts_controller.rb:65
41
+ msgid "Login id of scc_account"
42
+ msgstr ""
43
+
44
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:34 ../app/controllers/api/v2/scc_accounts_controller.rb:66
45
+ msgid "Password of scc_account"
46
+ msgstr ""
47
+
48
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:35 ../app/controllers/api/v2/scc_accounts_controller.rb:67
49
+ msgid "URL of SUSE for scc_account"
50
+ msgstr ""
51
+
52
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:36
53
+ msgid "Interval for syncing scc_account"
54
+ msgstr ""
55
+
56
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:37
57
+ msgid "Date and time relative to which the sync interval is run"
58
+ msgstr ""
59
+
60
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:38
61
+ msgid "Associated gpg key of scc_account"
62
+ msgstr ""
63
+
64
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:42
65
+ msgid "Create an scc_account"
66
+ msgstr ""
67
+
68
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:49
69
+ msgid "Update scc_account"
70
+ msgstr ""
71
+
72
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:56
73
+ msgid "Delete scc_account"
74
+ msgstr ""
75
+
76
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:62 ../app/controllers/api/v2/scc_accounts_controller.rb:63
77
+ msgid "Test connection for scc_account"
78
+ msgstr ""
79
+
80
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:90
81
+ msgid "Sync scc_account"
82
+ msgstr ""
83
+
84
+ #: ../app/controllers/api/v2/scc_accounts_controller.rb:104
85
+ msgid "Bulk subscription of scc_products for scc_account"
86
+ msgstr ""
87
+
88
+ #: ../app/controllers/api/v2/scc_products_controller.rb:15
89
+ msgid "List all products for scc_account"
90
+ msgstr ""
91
+
92
+ #: ../app/controllers/api/v2/scc_products_controller.rb:24
93
+ msgid "Show an scc_account product"
94
+ msgstr ""
95
+
96
+ #: ../app/controllers/api/v2/scc_products_controller.rb:29
97
+ msgid "Subscribe product"
98
+ msgstr ""
99
+
100
+ #: ../app/controllers/scc_accounts_controller.rb:71
101
+ msgid "Sync task started."
102
+ msgstr "Sync Job gestartet."
103
+
104
+ #: ../app/controllers/scc_accounts_controller.rb:73 ../app/controllers/scc_accounts_controller.rb:93
105
+ msgid "Failed to add task to queue: %s"
106
+ msgstr "Aufgabe konnte nicht in die Warteschlange gestellt werden: %s"
107
+
108
+ #: ../app/controllers/scc_accounts_controller.rb:75 ../app/controllers/scc_accounts_controller.rb:95
109
+ msgid "Lock on SCC account already taken: %s"
110
+ msgstr "Lock für SCC Zugang bereits vergeben: %s"
111
+
112
+ #: ../app/controllers/scc_accounts_controller.rb:88
113
+ msgid "Task to subscribe products started."
114
+ msgstr "Job zum abonnieren von Produkten gestartet."
115
+
116
+ #: ../app/controllers/scc_accounts_controller.rb:90
117
+ msgid "No products selected."
118
+ msgstr "Keine Produkte ausgewählt."
119
+
120
+ #: ../app/lib/actions/scc_manager/subscribe_product.rb:5
121
+ msgid "Product already subscribed!"
122
+ msgstr "Produkt wurde bereits abonniert!"
123
+
124
+ #: ../app/lib/actions/scc_manager/subscribe_product.rb:46 action_names.rb:5
125
+ msgid "Subscribe SCC Product"
126
+ msgstr "SCC Produkt abonnieren"
127
+
128
+ #: ../app/lib/actions/scc_manager/sync.rb:27 action_names.rb:4
129
+ msgid "Sync SUSE subscriptions"
130
+ msgstr "SUSE Abonnements synchronisieren"
131
+
132
+ #: ../app/lib/actions/scc_manager/sync_plan_account_repositories.rb:31
133
+ msgid "Update SUSE repositories %s"
134
+ msgstr "SUSE Repositorien %s aktualisieren"
135
+
136
+ #: ../app/lib/actions/scc_manager/sync_plan_account_repositories.rb:31
137
+ msgid "Unknown"
138
+ msgstr "Unbekannt"
139
+
140
+ #: ../app/lib/actions/scc_manager/sync_plan_account_repositories.rb:33 action_names.rb:9
141
+ msgid "Update SUSE repositories"
142
+ msgstr "SUSE Repositorien aktualisieren"
143
+
144
+ #: ../app/lib/actions/scc_manager/sync_products.rb:36 action_names.rb:3
145
+ msgid "Sync SUSE subscriptions (Products)"
146
+ msgstr "SUSE Abonnements (Produkte) synchronisieren"
147
+
148
+ #: ../app/lib/actions/scc_manager/sync_repositories.rb:34 action_names.rb:2
149
+ msgid "Sync SUSE subscriptions (Repositories)"
150
+ msgstr "SUSE Abonnements (Repositorien) synchronisieren"
151
+
152
+ #: ../app/models/scc_account.rb:62
153
+ msgid "never synced"
154
+ msgstr "Nie synchronisiert"
155
+
156
+ #: ../app/models/scc_account.rb:109
157
+ msgid "Interval cannot be nil"
158
+ msgstr "Intervall darf nicht Null sein"
159
+
160
+ #: ../app/models/scc_account.rb:116
161
+ msgid "Interval not set correctly"
162
+ msgstr "Intervall nicht richtig gesetzt"
163
+
164
+ #: ../app/models/scc_account.rb:121
165
+ msgid "Cron expression is not valid!"
166
+ msgstr "Cron-Ausdruck ungültig!"
167
+
168
+ #: ../app/models/scc_account_sync_plan_task_group.rb:5
169
+ msgid "SUSE Subscription"
170
+ msgstr "SUSE Abonnement"
171
+
172
+ #: ../app/views/scc_account_sync_plan_task_groups/_scc_account_sync_plan_task_groups.html.erb:1
173
+ msgid "SUSE Subscription: "
174
+ msgstr "SUSE Abonnement:"
175
+
176
+ #: ../app/views/scc_accounts/_form.html.erb:7
177
+ msgid "SUSE Customer Center account"
178
+ msgstr "SUSE Customer Center Konto"
179
+
180
+ #: ../app/views/scc_accounts/_form.html.erb:14
181
+ msgid "Use your 'Organization credentials' obtained from the SUSE Customer Center."
182
+ msgstr "Verwenden Sie die \"Organisationszugangsdaten\" aus dem SUSE Customer Center."
183
+
184
+ #: ../app/views/scc_accounts/_form.html.erb:16
185
+ msgid "Base URL"
186
+ msgstr "Basis URL"
187
+
188
+ #: ../app/views/scc_accounts/_form.html.erb:18
189
+ msgid "Sync interval"
190
+ msgstr ""
191
+
192
+ #: ../app/views/scc_accounts/_form.html.erb:18
193
+ msgid "The sync interval is used to periodically update the SCC authentication tokens of any imported products."
194
+ msgstr ""
195
+
196
+ #: ../app/views/scc_accounts/_form.html.erb:19
197
+ msgid "Sync Date"
198
+ msgstr "Synchronisationsdatum"
199
+
200
+ #: ../app/views/scc_accounts/_form.html.erb:23
201
+ msgid "None"
202
+ msgstr ""
203
+
204
+ #: ../app/views/scc_accounts/_form.html.erb:24
205
+ msgid "Use GPG key for SUSE products"
206
+ msgstr ""
207
+
208
+ #: ../app/views/scc_accounts/_form.html.erb:26
209
+ msgid "Use this setting if you want to automatically add a GPG key to your SUSE products upon subscription. You can change this setting in the 'Content' > 'Products' menu, later."
210
+ msgstr ""
211
+
212
+ #: ../app/views/scc_accounts/_form.html.erb:31
213
+ msgid "Test Connection"
214
+ msgstr "Verbindung testen"
215
+
216
+ #: ../app/views/scc_accounts/edit.html.erb:1
217
+ msgid "Edit %s"
218
+ msgstr "%s bearbeiten"
219
+
220
+ #: ../app/views/scc_accounts/index.html.erb:2
221
+ msgid "SUSE subscriptions"
222
+ msgstr "SUSE Abonnements"
223
+
224
+ #: ../app/views/scc_accounts/index.html.erb:3
225
+ msgid "Add SCC account"
226
+ msgstr "SCC Konto hinzufügen"
227
+
228
+ #: ../app/views/scc_accounts/index.html.erb:9
229
+ msgid "Products"
230
+ msgstr "Produkte"
231
+
232
+ #: ../app/views/scc_accounts/index.html.erb:10
233
+ msgid "Last synced"
234
+ msgstr "Letzte Synchronisation"
235
+
236
+ #: ../app/views/scc_accounts/index.html.erb:11
237
+ msgid "Actions"
238
+ msgstr "Aktionen"
239
+
240
+ #: ../app/views/scc_accounts/index.html.erb:24
241
+ msgid "Select products"
242
+ msgstr "Produkte auswählen"
243
+
244
+ #: ../app/views/scc_accounts/index.html.erb:25
245
+ msgid "Sync"
246
+ msgstr "Synchronisation"
247
+
248
+ #: ../app/views/scc_accounts/index.html.erb:28
249
+ msgid "Delete %s?"
250
+ msgstr "%s löschen?"
251
+
252
+ #: ../app/views/scc_accounts/new.html.erb:1
253
+ msgid "Add SUSE Customer Center Account"
254
+ msgstr "SUSE Customer Center Konto hinzufügen"
255
+
256
+ #: ../app/views/scc_accounts/show.html.erb:1
257
+ msgid "Product Selection for Account %s"
258
+ msgstr ""
259
+
260
+ #: ../app/views/scc_accounts/show.html.erb:17
261
+ msgid "(WARNING: Please check your SUSE subscription)"
262
+ msgstr ""
263
+
264
+ #: ../app/views/scc_accounts/show.html.erb:33
265
+ msgid "SUSE Customer Center"
266
+ msgstr "SUSE Customer Center"
267
+
268
+ #: ../app/views/scc_accounts/show.html.erb:44
269
+ msgid "Please sync your SUSE subscriptions first."
270
+ msgstr "Bitte synchronisieren Sie zuerst Ihre SUSE Abonnements."
271
+
272
+ #: ../lib/foreman_scc_manager/engine.rb:77
273
+ msgid "SUSE Subscriptions"
274
+ msgstr "SUSE Abonnements"
275
+
276
+ #: action_names.rb:6
277
+ msgid "Action with sub plans"
278
+ msgstr ""
279
+
280
+ #: action_names.rb:7
281
+ msgid "Import facts"
282
+ msgstr ""
283
+
284
+ #: action_names.rb:8
285
+ msgid "Import Puppet classes"
286
+ msgstr ""
287
+
288
+ #: action_names.rb:10
289
+ msgid "Abstract async task"
290
+ msgstr ""
291
+
292
+ #: action_names.rb:11
293
+ msgid "Export"
294
+ msgstr ""
295
+
296
+ #: action_names.rb:12
297
+ msgid "Import"
298
+ msgstr ""
299
+
300
+ #: action_names.rb:13
301
+ msgid "Copy version units to library"
302
+ msgstr ""
303
+
304
+ #: action_names.rb:14
305
+ msgid "Create"
306
+ msgstr ""
307
+
308
+ #: action_names.rb:15
309
+ msgid "Delete Activation Key"
310
+ msgstr ""
311
+
312
+ #: action_names.rb:16
313
+ msgid "Update"
314
+ msgstr ""
315
+
316
+ #: action_names.rb:17
317
+ msgid "Generate host applicability"
318
+ msgstr ""
319
+
320
+ #: action_names.rb:18
321
+ msgid "Bulk generate applicability for hosts"
322
+ msgstr ""
323
+
324
+ #: action_names.rb:19
325
+ msgid "Generate repository applicability"
326
+ msgstr ""
327
+
328
+ #: action_names.rb:20
329
+ msgid "Synchronize smart proxy"
330
+ msgstr ""
331
+
332
+ #: action_names.rb:21
333
+ msgid "Sync capsule"
334
+ msgstr ""
335
+
336
+ #: action_names.rb:22
337
+ msgid "Delete"
338
+ msgstr ""
339
+
340
+ #: action_names.rb:23
341
+ msgid "Errata mail"
342
+ msgstr ""
343
+
344
+ #: action_names.rb:24
345
+ msgid "Incremental Update of Content View Version(s) "
346
+ msgstr ""
347
+
348
+ #: action_names.rb:25
349
+ msgid "Promote"
350
+ msgstr ""
351
+
352
+ #: action_names.rb:26
353
+ msgid "Promotion to Environment"
354
+ msgstr ""
355
+
356
+ #: action_names.rb:27
357
+ msgid "Publish"
358
+ msgstr ""
359
+
360
+ #: action_names.rb:28
361
+ msgid "Remove Versions and Associations"
362
+ msgstr ""
363
+
364
+ #: action_names.rb:29
365
+ msgid "Remove from Environment"
366
+ msgstr ""
367
+
368
+ #: action_names.rb:30
369
+ msgid "Remove Version"
370
+ msgstr ""
371
+
372
+ #: action_names.rb:31
373
+ msgid "Auto attach subscriptions"
374
+ msgstr ""
375
+
376
+ #: action_names.rb:32
377
+ msgid "Destroy Content Host"
378
+ msgstr ""
379
+
380
+ #: action_names.rb:33
381
+ msgid "Install Applicable Errata"
382
+ msgstr ""
383
+
384
+ #: action_names.rb:34
385
+ msgid "Install erratum"
386
+ msgstr ""
387
+
388
+ #: action_names.rb:35
389
+ msgid "Hypervisors"
390
+ msgstr ""
391
+
392
+ #: action_names.rb:36
393
+ msgid "Import Content View Version"
394
+ msgstr ""
395
+
396
+ #: action_names.rb:37
397
+ msgid "Incremental Update"
398
+ msgstr ""
399
+
400
+ #: action_names.rb:38
401
+ msgid "Republish Version Repositories"
402
+ msgstr ""
403
+
404
+ #: action_names.rb:39
405
+ msgid "Delete Lifecycle Environment"
406
+ msgstr ""
407
+
408
+ #: action_names.rb:40
409
+ msgid "Publish Lifecycle Environment Repositories"
410
+ msgstr ""
411
+
412
+ #: action_names.rb:41
413
+ msgid "Attach subscriptions"
414
+ msgstr ""
415
+
416
+ #: action_names.rb:42
417
+ msgid "Remove subscriptions"
418
+ msgstr ""
419
+
420
+ #: action_names.rb:43
421
+ msgid "Update Content Overrides"
422
+ msgstr ""
423
+
424
+ #: action_names.rb:44
425
+ msgid "Hypervisors update"
426
+ msgstr ""
427
+
428
+ #: action_names.rb:45
429
+ msgid "Install package"
430
+ msgstr ""
431
+
432
+ #: action_names.rb:46
433
+ msgid "Remove package"
434
+ msgstr ""
435
+
436
+ #: action_names.rb:47
437
+ msgid "Update package"
438
+ msgstr ""
439
+
440
+ #: action_names.rb:48
441
+ msgid "Install package group"
442
+ msgstr ""
443
+
444
+ #: action_names.rb:49
445
+ msgid "Remove package group"
446
+ msgstr ""
447
+
448
+ #: action_names.rb:50
449
+ msgid "Updating System Purpose for host"
450
+ msgstr ""
451
+
452
+ #: action_names.rb:51
453
+ msgid "Package Profile Update"
454
+ msgstr ""
455
+
456
+ #: action_names.rb:52
457
+ msgid "Update for host"
458
+ msgstr ""
459
+
460
+ #: action_names.rb:53
461
+ msgid "Update release version for host"
462
+ msgstr ""
463
+
464
+ #: action_names.rb:54
465
+ msgid "Combined Profile Update"
466
+ msgstr ""
467
+
468
+ #: action_names.rb:55
469
+ msgid "Destroy"
470
+ msgstr ""
471
+
472
+ #: action_names.rb:56
473
+ msgid "Run Sync Plan:"
474
+ msgstr ""
475
+
476
+ #: action_names.rb:57
477
+ msgid "Product Create"
478
+ msgstr ""
479
+
480
+ #: action_names.rb:58
481
+ msgid "Disable"
482
+ msgstr ""
483
+
484
+ #: action_names.rb:59
485
+ msgid "Delete Product"
486
+ msgstr ""
487
+
488
+ #: action_names.rb:60
489
+ msgid "Enable"
490
+ msgstr ""
491
+
492
+ #: action_names.rb:61
493
+ msgid "Create Package Group"
494
+ msgstr ""
495
+
496
+ #: action_names.rb:62
497
+ msgid "Reindex subscriptions"
498
+ msgstr ""
499
+
500
+ #: action_names.rb:63
501
+ msgid "Verify checksum"
502
+ msgstr ""
503
+
504
+ #: action_names.rb:64
505
+ msgid "Upload into"
506
+ msgstr ""
507
+
508
+ #: action_names.rb:65
509
+ msgid "Upload errata into"
510
+ msgstr ""
511
+
512
+ #: action_names.rb:66
513
+ msgid "Update http proxy"
514
+ msgstr ""
515
+
516
+ #: action_names.rb:67
517
+ msgid "Update redhat repository"
518
+ msgstr ""
519
+
520
+ #: action_names.rb:68
521
+ msgid "Update http proxy details"
522
+ msgstr ""
523
+
524
+ #: action_names.rb:69
525
+ msgid "Update content urls"
526
+ msgstr ""
527
+
528
+ #: action_names.rb:70
529
+ msgid "Synchronize"
530
+ msgstr ""
531
+
532
+ #: action_names.rb:71
533
+ msgid "Remove Content"
534
+ msgstr ""
535
+
536
+ #: action_names.rb:72
537
+ msgid "Delete Package Group"
538
+ msgstr ""
539
+
540
+ #: action_names.rb:73
541
+ msgid "Discover"
542
+ msgstr ""
543
+
544
+ #: action_names.rb:74
545
+ msgid "Instance update"
546
+ msgstr ""
547
+
548
+ #: action_names.rb:75
549
+ msgid "Fetch pxe files"
550
+ msgstr ""
551
+
552
+ #: action_names.rb:76
553
+ msgid "Index module streams"
554
+ msgstr ""
555
+
556
+ #: action_names.rb:77
557
+ msgid "Index package groups"
558
+ msgstr ""
559
+
560
+ #: action_names.rb:78
561
+ msgid "Filtered index content"
562
+ msgstr ""
563
+
564
+ #: action_names.rb:79
565
+ msgid "Index errata"
566
+ msgstr ""
567
+
568
+ #: action_names.rb:80
569
+ msgid "Index content"
570
+ msgstr ""
571
+
572
+ #: gemspec.rb:2
573
+ msgid "Foreman plugin to sync SUSE Customer Center products and repositories into Katello."
574
+ msgstr "Foreman Plugin um SUSE Customer Center Produkte und Repositorien in Katello zu importieren."