Skip to content

Commit

Permalink
Merge pull request #2855 from alphagov/sengi/secrets-zeroconf
Browse files Browse the repository at this point in the history
Make secrets sync zero-configuration.
  • Loading branch information
sengi authored May 2, 2024
2 parents c2bed7e + e78c54c commit c98d606
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 105 deletions.
24 changes: 4 additions & 20 deletions lib/tasks/sync_kubernetes_secrets.rake
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
namespace :kubernetes do
desc "Synchronise OAuth Token secrets in Kubernetes"
task :sync_token_secrets, %i[config_map_name] => :environment do |_, args|
task sync_token_secrets: :environment do
client = Kubernetes::Client.new
config_map = client.get_config_map(args[:config_map_name])

emails = JSON.parse(config_map.data["api_user_emails"])

api_users = ApiUser.where(email: emails)
missing_users = emails - api_users.map(&:email)
api_users = ApiUser.where(suspended_at: nil)

api_users.each do |api_user|
api_user.authorisations.not_revoked.each do |token|
Expand All @@ -18,21 +14,13 @@ namespace :kubernetes do
client.apply_secret(name, data)
end
end

if missing_users.any?
raise StandardError, "Could not find api users for: #{missing_users.join(', ')}"
end
end

desc "Synchronise OAuth App secrets in Kubernetes"
task :sync_app_secrets, %i[config_map_name] => :environment do |_, args|
task sync_app_secrets: :environment do
client = Kubernetes::Client.new
config_map = client.get_config_map(args[:config_map_name])

app_names = JSON.parse(config_map.data["app_names"])
apps = Doorkeeper::Application.where(name: app_names)

missing_apps = app_names - apps.map(&:name)
apps = Doorkeeper::Application.where(retired: false)

apps.each do |app|
name = "signon-app-#{app.name}".parameterize
Expand All @@ -41,9 +29,5 @@ namespace :kubernetes do
Rails.logger.info(name)
client.apply_secret(name, data)
end

if missing_apps.any?
raise StandardError, "Could not find apps for: #{missing_apps.join(', ')}"
end
end
end
95 changes: 10 additions & 85 deletions test/lib/tasks/sync_kubernetes_secrets_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,93 +15,30 @@ class KubernetesTaskTest < ActiveSupport::TestCase
api_user_with_token("user2", token_count: 1),
]

stub_config_map(@client, [], api_users.map(&:email))
expect_secret_tokens_created_for_only_users(@client, api_users)

Rake::Task["kubernetes:sync_token_secrets"].execute({
config_map_name: "config_map_name",
})
Rake::Task["kubernetes:sync_token_secrets"].execute
end

should "create all token secrets for only users specified" do
api_users = [
api_user_with_token("user1", token_count: 2),
api_user_with_token("user2", token_count: 1),
]

specified_user = api_users[0]

stub_config_map(@client, [], [specified_user.email])
expect_secret_tokens_created_for_only_users(@client, [specified_user])

Rake::Task["kubernetes:sync_token_secrets"].execute({
config_map_name: "config_map_name",
})
end

should "raise an exception about missing user, but not skip other existing users" do
api_users = [
api_user_with_token("user1", token_count: 2),
api_user_with_token("user2", token_count: 1),
]

emails = [api_users[0].email, "[email protected]", api_users[1].email]

stub_config_map(@client, [], emails)
expect_secret_tokens_created_for_only_users(@client, api_users)
should "create token secrets for non-suspended users only" do
suspended_user = api_user_with_token("user1", token_count: 1)
suspended_user.suspend("test")
expected_user = api_user_with_token("user2", token_count: 2)

err = assert_raises StandardError do
Rake::Task["kubernetes:sync_token_secrets"].execute({
config_map_name: "config_map_name",
})
end
expect_secret_tokens_created_for_only_users(@client, [expected_user])

assert_match(/[email protected]/, err.message)
Rake::Task["kubernetes:sync_token_secrets"].execute
end
end

context "#sync_app_secrets" do
should "create all app secrets for only specified apps" do
should "create app secrets for all non-retired apps" do
app = create(:application)
create(:application)
create(:application, retired: true)

stub_config_map(@client, [app.name], [])
expect_secrets_created_for_only_apps(@client, [app])

Rake::Task["kubernetes:sync_app_secrets"].execute({
config_map_name: "config_map_name",
})
end

should "raise an exception about missing app, but not skip other existing apps" do
apps = [create(:application), create(:application)]
names = [apps[0].name, "Do Not Exist", apps[1].name]

stub_config_map(@client, names, [])
expect_secrets_created_for_only_apps(@client, apps)

err = assert_raises StandardError do
Rake::Task["kubernetes:sync_app_secrets"].execute({
config_map_name: "config_map_name",
})
end

assert_match(/Do Not Exist/, err.message)
end

should "raise an exception about retired app" do
app = create(:application, retired: true)

stub_config_map(@client, [app.name], [])
expect_secrets_created_for_only_apps(@client, [])

err = assert_raises StandardError do
Rake::Task["kubernetes:sync_app_secrets"].execute({
config_map_name: "config_map_name",
})
end

assert_match(/#{app.name}/, err.message)
Rake::Task["kubernetes:sync_app_secrets"].execute
end
end

Expand All @@ -124,16 +61,4 @@ def expect_secrets_created_for_only_apps(client, apps)
)
end
end

def stub_config_map(client, app_names, emails)
email_list = emails.map { |e| %("#{e}") }.join(",")
names_list = app_names.map { |n| %("#{n}") }.join(",")

client.stubs(:get_config_map).with("config_map_name").returns(
Kubeclient::Resource.new({
data: { "app_names" => "[#{names_list}]",
"api_user_emails" => "[#{email_list}]" },
}),
)
end
end

0 comments on commit c98d606

Please sign in to comment.