hako 2.16.0 → 2.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +4 -4
- data/.rubocop.yml +3 -1
- data/CHANGELOG.md +13 -0
- data/hako.gemspec +3 -1
- data/lib/hako/container.rb +23 -0
- data/lib/hako/definition_loader.rb +9 -0
- data/lib/hako/schedulers/ecs.rb +142 -25
- data/lib/hako/schedulers/ecs_definition_comparator.rb +17 -1
- data/lib/hako/schedulers/ecs_volume_comparator.rb +18 -0
- data/lib/hako/scripts/nginx_front.rb +1 -1
- data/lib/hako/version.rb +1 -1
- metadata +32 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bf69da97907f68236fdaeca00d74f4933d0c517afd44e072721a77b2d5ba9d0e
|
|
4
|
+
data.tar.gz: 1d3455be0daf4d3c0e61e5384fd82ccbb2a14b4a007d5115cf77b4495f63b115
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6c59d28f95d1be5246c4454924f8dbada59e4ffea9222eb23e684a2996161a89bcb3a33d8af1779637f3248d824118f3b48b6745816c608ae756e8646654ffc1
|
|
7
|
+
data.tar.gz: 2039675e62e6f47b3a9e37b63b843c5ac099079df435cc9f2705758722745044319f135c2b7f35371f4b192ead601d4ec842e362943cd961d2b32308909ecba1
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -13,10 +13,10 @@ jobs:
|
|
|
13
13
|
fail-fast: false
|
|
14
14
|
matrix:
|
|
15
15
|
ruby:
|
|
16
|
-
- '2.6'
|
|
17
|
-
- '2.7'
|
|
18
|
-
- '3.0'
|
|
19
16
|
- '3.1'
|
|
17
|
+
- '3.2'
|
|
18
|
+
- '3.3'
|
|
19
|
+
- '3.4'
|
|
20
20
|
steps:
|
|
21
21
|
- uses: actions/checkout@v2
|
|
22
22
|
- uses: ruby/setup-ruby@v1
|
|
@@ -32,6 +32,6 @@ jobs:
|
|
|
32
32
|
- uses: ruby/setup-ruby@v1
|
|
33
33
|
with:
|
|
34
34
|
# Use the same version with .rubocop.yml
|
|
35
|
-
ruby-version:
|
|
35
|
+
ruby-version: 3.1
|
|
36
36
|
bundler-cache: true
|
|
37
37
|
- run: bundle exec rubocop
|
data/.rubocop.yml
CHANGED
|
@@ -2,7 +2,7 @@ inherit_from: .rubocop_todo.yml
|
|
|
2
2
|
|
|
3
3
|
AllCops:
|
|
4
4
|
DisplayCopNames: true
|
|
5
|
-
TargetRubyVersion:
|
|
5
|
+
TargetRubyVersion: 3.1
|
|
6
6
|
NewCops: disable
|
|
7
7
|
|
|
8
8
|
Layout/FirstArgumentIndentation:
|
|
@@ -36,6 +36,8 @@ Style/PercentLiteralDelimiters:
|
|
|
36
36
|
'%i': '[]'
|
|
37
37
|
Style/RaiseArgs:
|
|
38
38
|
EnforcedStyle: compact
|
|
39
|
+
Style/RedundantCondition:
|
|
40
|
+
Enabled: false
|
|
39
41
|
Style/SignalException:
|
|
40
42
|
Enabled: false
|
|
41
43
|
Style/SoleNestedConditional:
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
# 2.18.0 (2026-01-26)
|
|
2
|
+
## New features
|
|
3
|
+
- Support EFS
|
|
4
|
+
- Support resource_requirements for GPU
|
|
5
|
+
- Support SecretsManager secrets in dry-run
|
|
6
|
+
- Launch dependent containers on `hako oneshot`
|
|
7
|
+
- Support deployment circuit breaker
|
|
8
|
+
- Support FireLens
|
|
9
|
+
|
|
10
|
+
# 2.17.0 (2022-05-31)
|
|
11
|
+
## New features
|
|
12
|
+
- Support runtime_platform option
|
|
13
|
+
|
|
1
14
|
# 2.16.0 (2022-05-02)
|
|
2
15
|
## New features
|
|
3
16
|
- Support ephemeral_storage option in ECS scheduler
|
data/hako.gemspec
CHANGED
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
|
19
19
|
spec.bindir = 'exe'
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
21
21
|
spec.require_paths = ['lib']
|
|
22
|
-
spec.required_ruby_version = '>=
|
|
22
|
+
spec.required_ruby_version = '>= 3.1.0'
|
|
23
23
|
|
|
24
24
|
spec.add_dependency 'aws-sdk-applicationautoscaling'
|
|
25
25
|
spec.add_dependency 'aws-sdk-autoscaling'
|
|
@@ -30,12 +30,14 @@ Gem::Specification.new do |spec|
|
|
|
30
30
|
spec.add_dependency 'aws-sdk-elasticloadbalancing'
|
|
31
31
|
spec.add_dependency 'aws-sdk-elasticloadbalancingv2', '>= 1.54.0'
|
|
32
32
|
spec.add_dependency 'aws-sdk-s3'
|
|
33
|
+
spec.add_dependency 'aws-sdk-secretsmanager'
|
|
33
34
|
spec.add_dependency 'aws-sdk-servicediscovery'
|
|
34
35
|
spec.add_dependency 'aws-sdk-sns'
|
|
35
36
|
spec.add_dependency 'aws-sdk-ssm'
|
|
36
37
|
spec.add_dependency 'jsonnet'
|
|
37
38
|
|
|
38
39
|
spec.add_development_dependency 'bundler'
|
|
40
|
+
spec.add_development_dependency 'oga' # XML library for aws-sdk
|
|
39
41
|
spec.add_development_dependency 'rake'
|
|
40
42
|
spec.add_development_dependency 'rspec'
|
|
41
43
|
spec.add_development_dependency 'rubocop', '>= 0.53.0'
|
data/lib/hako/container.rb
CHANGED
|
@@ -222,6 +222,29 @@ module Hako
|
|
|
222
222
|
end
|
|
223
223
|
end
|
|
224
224
|
|
|
225
|
+
# @return [Array, nil]
|
|
226
|
+
def resource_requirements
|
|
227
|
+
if @definition.key?('resource_requirements')
|
|
228
|
+
@definition['resource_requirements'].map do |rr|
|
|
229
|
+
{
|
|
230
|
+
type: rr.fetch('type'),
|
|
231
|
+
value: rr.fetch('value'),
|
|
232
|
+
}
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# @return [Hash, nil]
|
|
238
|
+
def firelens_configuration
|
|
239
|
+
if @definition.key?('firelens_configuration')
|
|
240
|
+
conf = @definition['firelens_configuration']
|
|
241
|
+
{
|
|
242
|
+
type: conf.fetch('type'),
|
|
243
|
+
options: conf.fetch('options', nil),
|
|
244
|
+
}
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
225
248
|
private
|
|
226
249
|
|
|
227
250
|
PROVIDERS_KEY = '$providers'
|
|
@@ -50,11 +50,20 @@ module Hako
|
|
|
50
50
|
Container.new(@app, sidecars.fetch(name), dry_run: @dry_run)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
# Load linked containers
|
|
53
54
|
containers[name].links.each do |link|
|
|
54
55
|
m = link.match(/\A([^:]+):([^:]+)\z/)
|
|
55
56
|
names << (m ? m[1] : link)
|
|
56
57
|
end
|
|
57
58
|
|
|
59
|
+
# Load dependent containers
|
|
60
|
+
depends_on = containers[name].depends_on
|
|
61
|
+
if depends_on
|
|
62
|
+
depends_on.each do |depend_on|
|
|
63
|
+
names << depend_on.fetch(:container_name)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
58
67
|
containers[name].volumes_from.each do |volumes_from|
|
|
59
68
|
names << volumes_from[:source_container]
|
|
60
69
|
end
|
data/lib/hako/schedulers/ecs.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'aws-sdk-autoscaling'
|
|
|
4
4
|
require 'aws-sdk-ec2'
|
|
5
5
|
require 'aws-sdk-ecs'
|
|
6
6
|
require 'aws-sdk-s3'
|
|
7
|
+
require 'aws-sdk-secretsmanager'
|
|
7
8
|
require 'aws-sdk-sns'
|
|
8
9
|
require 'aws-sdk-ssm'
|
|
9
10
|
require 'hako'
|
|
@@ -59,9 +60,21 @@ module Hako
|
|
|
59
60
|
end
|
|
60
61
|
@oneshot_notification_prefix = options.fetch('oneshot_notification_prefix', nil)
|
|
61
62
|
if options.key?('deployment_configuration')
|
|
63
|
+
deployment_configuration = options.fetch('deployment_configuration')
|
|
64
|
+
|
|
62
65
|
@deployment_configuration = {}
|
|
66
|
+
if deployment_configuration.key?('deployment_circuit_breaker')
|
|
67
|
+
circuit_breaker = deployment_configuration.fetch('deployment_circuit_breaker')
|
|
68
|
+
if circuit_breaker.fetch('rollback', nil)
|
|
69
|
+
validation_error!('rollback option of deployment_circuit_breaker is not supported because Hako handles rollback instead of the circuit breaker')
|
|
70
|
+
end
|
|
71
|
+
@deployment_configuration[:deployment_circuit_breaker] = {
|
|
72
|
+
enable: circuit_breaker.fetch('enable'),
|
|
73
|
+
rollback: false,
|
|
74
|
+
}
|
|
75
|
+
end
|
|
63
76
|
%i[maximum_percent minimum_healthy_percent].each do |key|
|
|
64
|
-
@deployment_configuration[key] =
|
|
77
|
+
@deployment_configuration[key] = deployment_configuration[key.to_s]
|
|
65
78
|
end
|
|
66
79
|
else
|
|
67
80
|
@deployment_configuration = nil
|
|
@@ -81,6 +94,13 @@ module Hako
|
|
|
81
94
|
end
|
|
82
95
|
end
|
|
83
96
|
@requires_compatibilities = options.fetch('requires_compatibilities', nil)
|
|
97
|
+
if options.key?('runtime_platform')
|
|
98
|
+
runtime_platform = options.fetch('runtime_platform')
|
|
99
|
+
@runtime_platform = {
|
|
100
|
+
cpu_architecture: runtime_platform.fetch('cpu_architecture', nil),
|
|
101
|
+
operating_system_family: runtime_platform.fetch('operating_system_family', nil),
|
|
102
|
+
}
|
|
103
|
+
end
|
|
84
104
|
@launch_type = options.fetch('launch_type', nil)
|
|
85
105
|
if options.key?('capacity_provider_strategy')
|
|
86
106
|
@capacity_provider_strategy = options.fetch('capacity_provider_strategy').map do |strategy|
|
|
@@ -393,9 +413,18 @@ module Hako
|
|
|
393
413
|
@ec2_client ||= Aws::EC2::Client.new(region: @region)
|
|
394
414
|
end
|
|
395
415
|
|
|
416
|
+
# @param [String] region
|
|
396
417
|
# @return [Aws::SSM::Client]
|
|
397
|
-
def ssm_client
|
|
398
|
-
@
|
|
418
|
+
def ssm_client(region)
|
|
419
|
+
@ssm_clients ||= {}
|
|
420
|
+
@ssm_clients[region] ||= Aws::SSM::Client.new(region: region)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
# @param [String] region
|
|
424
|
+
# @return [Aws::SecretsManager::Client]
|
|
425
|
+
def secretsmanager_client(region)
|
|
426
|
+
@secretsmanager_clients ||= {}
|
|
427
|
+
@secretsmanager_clients[region] ||= Aws::SecretsManager::Client.new(region: region)
|
|
399
428
|
end
|
|
400
429
|
|
|
401
430
|
# @return [EcsElb, EcsElbV2]
|
|
@@ -523,6 +552,9 @@ module Hako
|
|
|
523
552
|
if actual_definition.requires_compatibilities != @requires_compatibilities
|
|
524
553
|
return true
|
|
525
554
|
end
|
|
555
|
+
if actual_definition.runtime_platform != @runtime_platform
|
|
556
|
+
return true
|
|
557
|
+
end
|
|
526
558
|
if actual_definition.ephemeral_storage != @ephemeral_storage
|
|
527
559
|
return true
|
|
528
560
|
end
|
|
@@ -566,6 +598,7 @@ module Hako
|
|
|
566
598
|
container_definitions: definitions,
|
|
567
599
|
volumes: volumes_definition,
|
|
568
600
|
requires_compatibilities: @requires_compatibilities,
|
|
601
|
+
runtime_platform: @runtime_platform,
|
|
569
602
|
cpu: @cpu,
|
|
570
603
|
memory: @memory,
|
|
571
604
|
ephemeral_storage: @ephemeral_storage,
|
|
@@ -603,6 +636,7 @@ module Hako
|
|
|
603
636
|
container_definitions: definitions,
|
|
604
637
|
volumes: volumes_definition,
|
|
605
638
|
requires_compatibilities: @requires_compatibilities,
|
|
639
|
+
runtime_platform: @runtime_platform,
|
|
606
640
|
cpu: @cpu,
|
|
607
641
|
memory: @memory,
|
|
608
642
|
ephemeral_storage: @ephemeral_storage,
|
|
@@ -640,6 +674,23 @@ module Hako
|
|
|
640
674
|
labels: configuration['labels'],
|
|
641
675
|
scope: configuration['scope'],
|
|
642
676
|
}
|
|
677
|
+
elsif volume.key?('efs_volume_configuration')
|
|
678
|
+
configuration = volume['efs_volume_configuration']
|
|
679
|
+
authorization_config =
|
|
680
|
+
if configuration.key?('authorization_config')
|
|
681
|
+
ac = configuration['authorization_config']
|
|
682
|
+
{
|
|
683
|
+
access_point_id: ac['access_point_id'],
|
|
684
|
+
iam: ac['iam'],
|
|
685
|
+
}
|
|
686
|
+
end
|
|
687
|
+
definition[:efs_volume_configuration] = {
|
|
688
|
+
file_system_id: configuration.fetch('file_system_id'),
|
|
689
|
+
root_directory: configuration['root_directory'],
|
|
690
|
+
transit_encryption: configuration['transit_encryption'],
|
|
691
|
+
transit_encryption_port: configuration['transit_encryption_port'],
|
|
692
|
+
authorization_config: authorization_config,
|
|
693
|
+
}
|
|
643
694
|
else
|
|
644
695
|
# When neither 'host' nor 'docker_volume_configuration' is
|
|
645
696
|
# specified, ECS API treats it as if 'host' is specified without
|
|
@@ -690,6 +741,8 @@ module Hako
|
|
|
690
741
|
docker_security_options: container.docker_security_options,
|
|
691
742
|
system_controls: container.system_controls,
|
|
692
743
|
repository_credentials: container.repository_credentials,
|
|
744
|
+
resource_requirements: container.resource_requirements,
|
|
745
|
+
firelens_configuration: container.firelens_configuration,
|
|
693
746
|
}
|
|
694
747
|
end
|
|
695
748
|
|
|
@@ -1016,13 +1069,14 @@ module Hako
|
|
|
1016
1069
|
Hako.logger.debug " latest_event_id=#{latest_event_id}, deployments=#{s.deployments}"
|
|
1017
1070
|
no_active = s.deployments.all? { |d| d.status != 'ACTIVE' }
|
|
1018
1071
|
primary = s.deployments.find { |d| d.status == 'PRIMARY' }
|
|
1019
|
-
if primary.
|
|
1072
|
+
if primary.rollout_state == 'FAILED'
|
|
1073
|
+
Hako.logger.error("New deployment is failing: #{primary.rollout_state_reason}")
|
|
1074
|
+
report_task_diagnostics(service.cluster_arn, @started_task_ids)
|
|
1075
|
+
return false
|
|
1076
|
+
end
|
|
1077
|
+
if primary.desired_count * 2 < @started_task_ids.size && !ecs_circuit_breaker_enabled?
|
|
1020
1078
|
Hako.logger.error('Some started tasks are stopped. It seems new deployment is failing to start')
|
|
1021
|
-
@started_task_ids
|
|
1022
|
-
ecs_client.describe_tasks(cluster: service.cluster_arn, tasks: task_ids).tasks.each do |task|
|
|
1023
|
-
report_task_diagnostics(task)
|
|
1024
|
-
end
|
|
1025
|
-
end
|
|
1079
|
+
report_task_diagnostics(service.cluster_arn, @started_task_ids)
|
|
1026
1080
|
return false
|
|
1027
1081
|
end
|
|
1028
1082
|
primary_ready = primary && primary.running_count == primary.desired_count
|
|
@@ -1034,6 +1088,11 @@ module Hako
|
|
|
1034
1088
|
end
|
|
1035
1089
|
end
|
|
1036
1090
|
|
|
1091
|
+
# @return [Boolean]
|
|
1092
|
+
def ecs_circuit_breaker_enabled?
|
|
1093
|
+
@deployment_configuration&.dig(:deployment_circuit_breaker, :enable)
|
|
1094
|
+
end
|
|
1095
|
+
|
|
1037
1096
|
# @param [Array<Aws::ECS::Types::ServiceEvent>] events
|
|
1038
1097
|
# @return [String, nil]
|
|
1039
1098
|
def find_latest_event_id(events)
|
|
@@ -1044,20 +1103,24 @@ module Hako
|
|
|
1044
1103
|
end
|
|
1045
1104
|
end
|
|
1046
1105
|
|
|
1047
|
-
TASK_ID_RE = /\(task ([\h-]+)\)\.\z
|
|
1106
|
+
TASK_ID_RE = /\(task ([\h-]+)\)\.\z/
|
|
1048
1107
|
# @param [String] message
|
|
1049
1108
|
# @return [String, nil]
|
|
1050
1109
|
def extract_task_id(message)
|
|
1051
1110
|
message.slice(TASK_ID_RE, 1)
|
|
1052
1111
|
end
|
|
1053
1112
|
|
|
1054
|
-
# @param [
|
|
1113
|
+
# @param [Array<String>] task_ids
|
|
1055
1114
|
# @return [nil]
|
|
1056
|
-
def report_task_diagnostics(
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1115
|
+
def report_task_diagnostics(cluster, task_ids)
|
|
1116
|
+
task_ids.each_slice(100) do |batch|
|
|
1117
|
+
ecs_client.describe_tasks(cluster: cluster, tasks: batch).tasks.each do |task|
|
|
1118
|
+
Hako.logger.error("task_definition_arn=#{task.task_definition_arn} last_status=#{task.last_status}")
|
|
1119
|
+
Hako.logger.error(" stopped_reason: #{task.stopped_reason}")
|
|
1120
|
+
task.containers.sort_by(&:name).each do |container|
|
|
1121
|
+
Hako.logger.error(" Container #{container.name}: last_status=#{container.last_status} exit_code=#{container.exit_code.inspect} reason=#{container.reason.inspect}")
|
|
1122
|
+
end
|
|
1123
|
+
end
|
|
1061
1124
|
end
|
|
1062
1125
|
end
|
|
1063
1126
|
|
|
@@ -1199,6 +1262,7 @@ module Hako
|
|
|
1199
1262
|
# @return [nil]
|
|
1200
1263
|
def print_volume_definition_in_cli_format(definition)
|
|
1201
1264
|
return if definition.dig(:docker_volume_configuration, :autoprovision)
|
|
1265
|
+
return if definition[:efs_volume_configuration]
|
|
1202
1266
|
# From version 1.20.0 of ECS agent, a local volume is provisioned when
|
|
1203
1267
|
# 'host' is specified without 'source_path'.
|
|
1204
1268
|
return if definition.dig(:host, :source_path)
|
|
@@ -1290,6 +1354,7 @@ module Hako
|
|
|
1290
1354
|
opts = dev[:host_path]
|
|
1291
1355
|
opts += ":#{dev[:container_path]}" if dev[:container_path]
|
|
1292
1356
|
if dev[:permissions]
|
|
1357
|
+
opts += ':'
|
|
1293
1358
|
dev[:permissions].each do |permission|
|
|
1294
1359
|
opts += permission[0] if %w[read write mknod].include?(permission)
|
|
1295
1360
|
end
|
|
@@ -1383,22 +1448,74 @@ module Hako
|
|
|
1383
1448
|
nil
|
|
1384
1449
|
end
|
|
1385
1450
|
|
|
1451
|
+
SecretValueFrom = Struct.new(:arn, :secret_name, :json_key, :version_stage, :version_id)
|
|
1452
|
+
|
|
1386
1453
|
# @param [Hash] container_definition
|
|
1387
1454
|
# @return [nil]
|
|
1388
1455
|
def check_secrets(container_definition)
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1456
|
+
parameter_arns = []
|
|
1457
|
+
secret_value_arns = []
|
|
1458
|
+
invalid_arns = []
|
|
1459
|
+
|
|
1460
|
+
(container_definition[:secrets] || []).each do |secret|
|
|
1461
|
+
arn = Aws::ARNParser.parse(secret.fetch(:value_from))
|
|
1462
|
+
case arn.service
|
|
1463
|
+
when 'ssm'
|
|
1464
|
+
parameter_arns << arn
|
|
1465
|
+
when 'secretsmanager'
|
|
1466
|
+
secret_value_arns << arn
|
|
1467
|
+
else
|
|
1468
|
+
invalid_arns << arn.to_s
|
|
1469
|
+
end
|
|
1470
|
+
end
|
|
1471
|
+
|
|
1472
|
+
parameter_arns.group_by(&:region).each do |region, region_arns|
|
|
1473
|
+
region_arns.each_slice(10) do |arns|
|
|
1474
|
+
invalid_arns += ssm_client(region).get_parameters(names: arns.map(&:to_s)).invalid_parameters
|
|
1475
|
+
end
|
|
1476
|
+
end
|
|
1477
|
+
|
|
1478
|
+
secret_value_arns.group_by(&:region).each do |region, region_arns|
|
|
1479
|
+
secret_value_froms = region_arns.filter_map do |arn|
|
|
1480
|
+
m = arn.resource.match(/\Asecret:(?<secret_name>[^:]+):(?<json_key>[^:]*):(?<version_stage>[^:]*):(?<version_id>[^:]*)\z/)
|
|
1481
|
+
if m
|
|
1482
|
+
f = SecretValueFrom.new(arn, m[:secret_name])
|
|
1483
|
+
unless m[:json_key].empty?
|
|
1484
|
+
f.json_key = m[:json_key]
|
|
1485
|
+
end
|
|
1486
|
+
unless m[:version_stage].empty?
|
|
1487
|
+
f.version_stage = m[:version_stage]
|
|
1488
|
+
end
|
|
1489
|
+
unless m[:version_id].empty?
|
|
1490
|
+
f.version_id = m[:version_id]
|
|
1491
|
+
end
|
|
1492
|
+
f
|
|
1394
1493
|
else
|
|
1395
|
-
|
|
1494
|
+
invalid_arns << arn.to_s
|
|
1495
|
+
nil
|
|
1496
|
+
end
|
|
1497
|
+
end
|
|
1498
|
+
secret_value_froms.group_by { |f| [f.secret_name, f.version_stage, f.version_id] }.each do |(secret_name, version_stage, version_id), fs|
|
|
1499
|
+
secret_arn = Aws::ARN.new(**fs[0].arn.to_h.merge(resource: "secret:#{secret_name}")).to_s
|
|
1500
|
+
begin
|
|
1501
|
+
secret_string = secretsmanager_client(region).get_secret_value(secret_id: secret_arn, version_stage: version_stage, version_id: version_id).secret_string
|
|
1502
|
+
secret_json = nil
|
|
1503
|
+
fs.each do |f|
|
|
1504
|
+
if f.json_key
|
|
1505
|
+
secret_json ||= JSON.parse(secret_string)
|
|
1506
|
+
unless secret_json.key?(f.json_key)
|
|
1507
|
+
invalid_arns << f.arn.to_s
|
|
1508
|
+
end
|
|
1509
|
+
end
|
|
1510
|
+
end
|
|
1511
|
+
rescue Aws::SecretsManager::Errors::ResourceNotFoundException
|
|
1512
|
+
invalid_arns += fs.map { |f| f.arn.to_s }
|
|
1396
1513
|
end
|
|
1397
1514
|
end
|
|
1398
|
-
ssm_client.get_parameters(names: names).invalid_parameters
|
|
1399
1515
|
end
|
|
1400
|
-
|
|
1401
|
-
|
|
1516
|
+
|
|
1517
|
+
unless invalid_arns.empty?
|
|
1518
|
+
raise Error.new("Invalid ARNs for secrets: #{invalid_arns}")
|
|
1402
1519
|
end
|
|
1403
1520
|
|
|
1404
1521
|
nil
|
|
@@ -45,8 +45,10 @@ module Hako
|
|
|
45
45
|
struct.member(:linux_parameters, Schema::Nullable.new(linux_parameters_schema))
|
|
46
46
|
struct.member(:readonly_root_filesystem, Schema::Nullable.new(Schema::Boolean.new))
|
|
47
47
|
struct.member(:docker_security_options, Schema::Nullable.new(Schema::UnorderedArray.new(Schema::String.new)))
|
|
48
|
-
struct.member(:system_controls, Schema::
|
|
48
|
+
struct.member(:system_controls, Schema::WithDefault.new(system_controls_schema, []))
|
|
49
49
|
struct.member(:repository_credentials, Schema::Nullable.new(repository_credentials_schema))
|
|
50
|
+
struct.member(:resource_requirements, Schema::Nullable.new(Schema::UnorderedArray.new(resource_requirement_schema)))
|
|
51
|
+
struct.member(:firelens_configuration, Schema::Nullable.new(firelens_configuration_schema))
|
|
50
52
|
end
|
|
51
53
|
end
|
|
52
54
|
|
|
@@ -189,6 +191,20 @@ module Hako
|
|
|
189
191
|
struct.member(:credentials_parameter, Schema::String.new)
|
|
190
192
|
end
|
|
191
193
|
end
|
|
194
|
+
|
|
195
|
+
def resource_requirement_schema
|
|
196
|
+
Schema::Structure.new.tap do |struct|
|
|
197
|
+
struct.member(:type, Schema::String.new)
|
|
198
|
+
struct.member(:value, Schema::String.new)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def firelens_configuration_schema
|
|
203
|
+
Schema::Structure.new.tap do |struct|
|
|
204
|
+
struct.member(:type, Schema::String.new)
|
|
205
|
+
struct.member(:options, Schema::Nullable.new(Schema::Table.new(Schema::String.new, Schema::String.new)))
|
|
206
|
+
end
|
|
207
|
+
end
|
|
192
208
|
end
|
|
193
209
|
end
|
|
194
210
|
end
|
|
@@ -22,6 +22,7 @@ module Hako
|
|
|
22
22
|
def volume_schema
|
|
23
23
|
Schema::Structure.new.tap do |struct|
|
|
24
24
|
struct.member(:docker_volume_configuration, Schema::Nullable.new(docker_volume_configuration_schema))
|
|
25
|
+
struct.member(:efs_volume_configuration, Schema::Nullable.new(efs_volume_configuration_schema))
|
|
25
26
|
struct.member(:host, Schema::Nullable.new(host_schema))
|
|
26
27
|
struct.member(:name, Schema::String.new)
|
|
27
28
|
end
|
|
@@ -37,6 +38,23 @@ module Hako
|
|
|
37
38
|
end
|
|
38
39
|
end
|
|
39
40
|
|
|
41
|
+
def efs_volume_configuration_schema
|
|
42
|
+
Schema::Structure.new.tap do |struct|
|
|
43
|
+
struct.member(:file_system_id, Schema::String.new)
|
|
44
|
+
struct.member(:root_directory, Schema::WithDefault.new(Schema::String.new, '/'))
|
|
45
|
+
struct.member(:transit_encryption, Schema::Nullable.new(Schema::String.new))
|
|
46
|
+
struct.member(:transit_encryption_port, Schema::Nullable.new(Schema::Integer.new))
|
|
47
|
+
struct.member(:authorization_config, Schema::Nullable.new(efs_authorization_config_schema))
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def efs_authorization_config_schema
|
|
52
|
+
Schema::Structure.new.tap do |struct|
|
|
53
|
+
struct.member(:access_point_id, Schema::Nullable.new(Schema::String.new))
|
|
54
|
+
struct.member(:iam, Schema::Nullable.new(Schema::String.new))
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
40
58
|
def host_schema
|
|
41
59
|
Schema::Structure.new.tap do |struct|
|
|
42
60
|
struct.member(:source_path, Schema::Nullable.new(Schema::String.new))
|
|
@@ -10,7 +10,7 @@ module Hako
|
|
|
10
10
|
class NginxFront < Script
|
|
11
11
|
S3Config = Struct.new(:region, :bucket, :prefix) do
|
|
12
12
|
# @param [Hash] options
|
|
13
|
-
def initialize(options)
|
|
13
|
+
def initialize(options)
|
|
14
14
|
self.region = options.fetch('region')
|
|
15
15
|
self.bucket = options.fetch('bucket')
|
|
16
16
|
self.prefix = options.fetch('prefix', nil)
|
data/lib/hako/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hako
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kohei Suzuki
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: aws-sdk-applicationautoscaling
|
|
@@ -136,6 +135,20 @@ dependencies:
|
|
|
136
135
|
- - ">="
|
|
137
136
|
- !ruby/object:Gem::Version
|
|
138
137
|
version: '0'
|
|
138
|
+
- !ruby/object:Gem::Dependency
|
|
139
|
+
name: aws-sdk-secretsmanager
|
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - ">="
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '0'
|
|
145
|
+
type: :runtime
|
|
146
|
+
prerelease: false
|
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - ">="
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '0'
|
|
139
152
|
- !ruby/object:Gem::Dependency
|
|
140
153
|
name: aws-sdk-servicediscovery
|
|
141
154
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -206,6 +219,20 @@ dependencies:
|
|
|
206
219
|
- - ">="
|
|
207
220
|
- !ruby/object:Gem::Version
|
|
208
221
|
version: '0'
|
|
222
|
+
- !ruby/object:Gem::Dependency
|
|
223
|
+
name: oga
|
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
|
225
|
+
requirements:
|
|
226
|
+
- - ">="
|
|
227
|
+
- !ruby/object:Gem::Version
|
|
228
|
+
version: '0'
|
|
229
|
+
type: :development
|
|
230
|
+
prerelease: false
|
|
231
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
232
|
+
requirements:
|
|
233
|
+
- - ">="
|
|
234
|
+
- !ruby/object:Gem::Version
|
|
235
|
+
version: '0'
|
|
209
236
|
- !ruby/object:Gem::Dependency
|
|
210
237
|
name: rake
|
|
211
238
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -369,7 +396,6 @@ homepage: https://github.com/eagletmt/hako
|
|
|
369
396
|
licenses:
|
|
370
397
|
- MIT
|
|
371
398
|
metadata: {}
|
|
372
|
-
post_install_message:
|
|
373
399
|
rdoc_options: []
|
|
374
400
|
require_paths:
|
|
375
401
|
- lib
|
|
@@ -377,15 +403,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
377
403
|
requirements:
|
|
378
404
|
- - ">="
|
|
379
405
|
- !ruby/object:Gem::Version
|
|
380
|
-
version:
|
|
406
|
+
version: 3.1.0
|
|
381
407
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
382
408
|
requirements:
|
|
383
409
|
- - ">="
|
|
384
410
|
- !ruby/object:Gem::Version
|
|
385
411
|
version: '0'
|
|
386
412
|
requirements: []
|
|
387
|
-
rubygems_version: 3.
|
|
388
|
-
signing_key:
|
|
413
|
+
rubygems_version: 3.6.9
|
|
389
414
|
specification_version: 4
|
|
390
415
|
summary: Deploy Docker container
|
|
391
416
|
test_files: []
|