cloud-mu 3.1.3 → 3.3.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/Dockerfile +15 -3
- data/ansible/roles/mu-windows/README.md +33 -0
- data/ansible/roles/mu-windows/defaults/main.yml +2 -0
- data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
- data/ansible/roles/mu-windows/files/config.xml +76 -0
- data/ansible/roles/mu-windows/handlers/main.yml +2 -0
- data/ansible/roles/mu-windows/meta/main.yml +53 -0
- data/ansible/roles/mu-windows/tasks/main.yml +36 -0
- data/ansible/roles/mu-windows/tests/inventory +2 -0
- data/ansible/roles/mu-windows/tests/test.yml +5 -0
- data/ansible/roles/mu-windows/vars/main.yml +2 -0
- data/bin/mu-adopt +21 -13
- data/bin/mu-azure-tests +57 -0
- data/bin/mu-cleanup +2 -4
- data/bin/mu-configure +52 -0
- data/bin/mu-deploy +3 -3
- data/bin/mu-findstray-tests +25 -0
- data/bin/mu-gen-docs +2 -4
- data/bin/mu-load-config.rb +4 -4
- data/bin/mu-node-manage +15 -16
- data/bin/mu-run-tests +147 -37
- data/cloud-mu.gemspec +22 -20
- data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
- data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
- data/cookbooks/mu-tools/libraries/helper.rb +3 -2
- data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
- data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
- data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
- data/cookbooks/mu-tools/recipes/eks.rb +2 -2
- data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
- data/cookbooks/mu-tools/recipes/selinux.rb +2 -1
- data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
- data/cookbooks/mu-tools/resources/disk.rb +1 -1
- data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
- data/extras/clean-stock-amis +25 -19
- data/extras/generate-stock-images +1 -0
- data/extras/image-generators/AWS/win2k12.yaml +18 -13
- data/extras/image-generators/AWS/win2k16.yaml +18 -13
- data/extras/image-generators/AWS/win2k19.yaml +21 -0
- data/extras/image-generators/Google/centos6.yaml +1 -0
- data/extras/image-generators/Google/centos7.yaml +1 -1
- data/modules/mommacat.ru +6 -16
- data/modules/mu.rb +158 -111
- data/modules/mu/adoption.rb +404 -71
- data/modules/mu/cleanup.rb +221 -306
- data/modules/mu/cloud.rb +129 -1633
- data/modules/mu/cloud/database.rb +49 -0
- data/modules/mu/cloud/dnszone.rb +44 -0
- data/modules/mu/cloud/machine_images.rb +212 -0
- data/modules/mu/cloud/providers.rb +81 -0
- data/modules/mu/cloud/resource_base.rb +926 -0
- data/modules/mu/cloud/server.rb +40 -0
- data/modules/mu/cloud/server_pool.rb +1 -0
- data/modules/mu/cloud/ssh_sessions.rb +228 -0
- data/modules/mu/cloud/winrm_sessions.rb +237 -0
- data/modules/mu/cloud/wrappers.rb +169 -0
- data/modules/mu/config.rb +171 -1767
- data/modules/mu/config/alarm.rb +2 -6
- data/modules/mu/config/bucket.rb +32 -3
- data/modules/mu/config/cache_cluster.rb +2 -2
- data/modules/mu/config/cdn.rb +100 -0
- data/modules/mu/config/collection.rb +4 -4
- data/modules/mu/config/container_cluster.rb +9 -4
- data/modules/mu/config/database.rb +84 -105
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +10 -9
- data/modules/mu/config/doc_helpers.rb +516 -0
- data/modules/mu/config/endpoint.rb +5 -4
- data/modules/mu/config/firewall_rule.rb +103 -4
- data/modules/mu/config/folder.rb +4 -4
- data/modules/mu/config/function.rb +19 -10
- data/modules/mu/config/group.rb +4 -4
- data/modules/mu/config/habitat.rb +4 -4
- data/modules/mu/config/job.rb +89 -0
- data/modules/mu/config/loadbalancer.rb +60 -14
- data/modules/mu/config/log.rb +4 -4
- data/modules/mu/config/msg_queue.rb +4 -4
- data/modules/mu/config/nosqldb.rb +4 -4
- data/modules/mu/config/notifier.rb +10 -21
- data/modules/mu/config/ref.rb +411 -0
- data/modules/mu/config/role.rb +4 -4
- data/modules/mu/config/schema_helpers.rb +509 -0
- data/modules/mu/config/search_domain.rb +4 -4
- data/modules/mu/config/server.rb +98 -71
- data/modules/mu/config/server.yml +1 -0
- data/modules/mu/config/server_pool.rb +5 -9
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +200 -0
- data/modules/mu/config/user.rb +4 -4
- data/modules/mu/config/vpc.rb +71 -27
- data/modules/mu/config/vpc.yml +0 -1
- data/modules/mu/defaults/AWS.yaml +91 -68
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +3 -2
- data/modules/mu/deploy.rb +43 -26
- data/modules/mu/groomer.rb +17 -2
- data/modules/mu/groomers/ansible.rb +188 -41
- data/modules/mu/groomers/chef.rb +116 -55
- data/modules/mu/logger.rb +127 -148
- data/modules/mu/master.rb +410 -2
- data/modules/mu/master/chef.rb +3 -4
- data/modules/mu/master/ldap.rb +3 -3
- data/modules/mu/master/ssl.rb +12 -3
- data/modules/mu/mommacat.rb +218 -2612
- data/modules/mu/mommacat/daemon.rb +403 -0
- data/modules/mu/mommacat/naming.rb +473 -0
- data/modules/mu/mommacat/search.rb +495 -0
- data/modules/mu/mommacat/storage.rb +722 -0
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +380 -122
- data/modules/mu/{clouds → providers}/aws/alarm.rb +7 -5
- data/modules/mu/{clouds → providers}/aws/bucket.rb +297 -59
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +37 -71
- data/modules/mu/providers/aws/cdn.rb +782 -0
- data/modules/mu/{clouds → providers}/aws/collection.rb +26 -25
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +724 -744
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +88 -70
- data/modules/mu/providers/aws/endpoint.rb +1072 -0
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +220 -247
- data/modules/mu/{clouds → providers}/aws/folder.rb +8 -8
- data/modules/mu/{clouds → providers}/aws/function.rb +300 -142
- data/modules/mu/{clouds → providers}/aws/group.rb +31 -29
- data/modules/mu/{clouds → providers}/aws/habitat.rb +18 -15
- data/modules/mu/providers/aws/job.rb +466 -0
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +66 -56
- data/modules/mu/{clouds → providers}/aws/log.rb +17 -14
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +29 -19
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +114 -16
- data/modules/mu/{clouds → providers}/aws/notifier.rb +142 -65
- data/modules/mu/{clouds → providers}/aws/role.rb +158 -118
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +201 -59
- data/modules/mu/{clouds → providers}/aws/server.rb +844 -1139
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +74 -65
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +26 -44
- data/modules/mu/{clouds → providers}/aws/user.rb +24 -25
- data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +5 -4
- data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +2 -1
- data/modules/mu/{clouds → providers}/aws/vpc.rb +525 -931
- data/modules/mu/providers/aws/vpc_subnet.rb +286 -0
- data/modules/mu/{clouds → providers}/azure.rb +29 -9
- data/modules/mu/{clouds → providers}/azure/container_cluster.rb +3 -8
- data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +18 -11
- data/modules/mu/{clouds → providers}/azure/habitat.rb +8 -6
- data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +5 -5
- data/modules/mu/{clouds → providers}/azure/role.rb +8 -10
- data/modules/mu/{clouds → providers}/azure/server.rb +97 -49
- data/modules/mu/{clouds → providers}/azure/user.rb +6 -8
- data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/vpc.rb +16 -21
- data/modules/mu/{clouds → providers}/cloudformation.rb +18 -7
- data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
- data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
- data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
- data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +5 -7
- data/modules/mu/{clouds → providers}/docker.rb +0 -0
- data/modules/mu/{clouds → providers}/google.rb +68 -30
- data/modules/mu/{clouds → providers}/google/bucket.rb +13 -15
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +85 -78
- data/modules/mu/{clouds → providers}/google/database.rb +11 -21
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +15 -14
- data/modules/mu/{clouds → providers}/google/folder.rb +20 -17
- data/modules/mu/{clouds → providers}/google/function.rb +140 -168
- data/modules/mu/{clouds → providers}/google/group.rb +29 -34
- data/modules/mu/{clouds → providers}/google/habitat.rb +21 -22
- data/modules/mu/{clouds → providers}/google/loadbalancer.rb +19 -21
- data/modules/mu/{clouds → providers}/google/role.rb +94 -58
- data/modules/mu/{clouds → providers}/google/server.rb +243 -156
- data/modules/mu/{clouds → providers}/google/server_pool.rb +26 -45
- data/modules/mu/{clouds → providers}/google/user.rb +95 -31
- data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/google/vpc.rb +103 -79
- data/modules/tests/aws-jobs-functions.yaml +46 -0
- data/modules/tests/bucket.yml +4 -0
- data/modules/tests/centos6.yaml +15 -0
- data/modules/tests/centos7.yaml +15 -0
- data/modules/tests/centos8.yaml +12 -0
- data/modules/tests/ecs.yaml +23 -0
- data/modules/tests/eks.yaml +1 -1
- data/modules/tests/functions/node-function/lambda_function.js +10 -0
- data/modules/tests/functions/python-function/lambda_function.py +12 -0
- data/modules/tests/includes-and-params.yaml +2 -1
- data/modules/tests/microservice_app.yaml +288 -0
- data/modules/tests/rds.yaml +108 -0
- data/modules/tests/regrooms/aws-iam.yaml +201 -0
- data/modules/tests/regrooms/bucket.yml +19 -0
- data/modules/tests/regrooms/rds.yaml +123 -0
- data/modules/tests/server-with-scrub-muisms.yaml +2 -1
- data/modules/tests/super_complex_bok.yml +2 -2
- data/modules/tests/super_simple_bok.yml +3 -5
- data/modules/tests/win2k12.yaml +17 -5
- data/modules/tests/win2k16.yaml +25 -0
- data/modules/tests/win2k19.yaml +25 -0
- data/requirements.txt +1 -0
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +240 -154
- data/extras/image-generators/AWS/windows.yaml +0 -18
- data/modules/mu/clouds/aws/database.rb +0 -1985
- data/modules/mu/clouds/aws/endpoint.rb +0 -592
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
module MU
|
|
16
16
|
class Cloud
|
|
17
17
|
class AWS
|
|
18
|
-
# A log as configured in {MU::Config::BasketofKittens::
|
|
18
|
+
# A log as configured in {MU::Config::BasketofKittens::folders}
|
|
19
19
|
class Folder < MU::Cloud::Folder
|
|
20
20
|
|
|
21
21
|
# Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like +@vpc+, for us.
|
|
@@ -59,7 +59,7 @@ module MU
|
|
|
59
59
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
|
60
60
|
# @param region [String]: The cloud provider region
|
|
61
61
|
# @return [void]
|
|
62
|
-
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
62
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
# Locate an existing AWS organization. If no identifying parameters are specified, this will return a description of the Organization which owns the account for our credentials.
|
|
@@ -78,20 +78,20 @@ module MU
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
# Cloud-specific configuration properties.
|
|
81
|
-
# @param
|
|
81
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
|
82
82
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
|
83
|
-
def self.schema(
|
|
83
|
+
def self.schema(_config)
|
|
84
84
|
toplevel_required = []
|
|
85
85
|
schema = {
|
|
86
86
|
}
|
|
87
87
|
[toplevel_required, schema]
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::
|
|
91
|
-
# @param
|
|
92
|
-
# @param
|
|
90
|
+
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::folders}, bare and unvalidated.
|
|
91
|
+
# @param _folder [Hash]: The resource to process and validate
|
|
92
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
|
93
93
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
|
94
|
-
def self.validateConfig(
|
|
94
|
+
def self.validateConfig(_folder, _configurator)
|
|
95
95
|
ok = true
|
|
96
96
|
|
|
97
97
|
ok
|
|
@@ -18,6 +18,18 @@ module MU
|
|
|
18
18
|
# A function as configured in {MU::Config::BasketofKittens::functions}
|
|
19
19
|
class Function < MU::Cloud::Function
|
|
20
20
|
|
|
21
|
+
# If we have sibling resources in our deployment, automatically inject
|
|
22
|
+
# interesting things about them into our function's environment
|
|
23
|
+
# variables.
|
|
24
|
+
SIBLING_VARS = {
|
|
25
|
+
"servers" => ["private_ip_address", "public_ip_address"],
|
|
26
|
+
"search_domains" => ["endpoint"],
|
|
27
|
+
"databases" => ["endpoint"],
|
|
28
|
+
"endpoints" => ["url"],
|
|
29
|
+
"notifiers" => ["TopicArn"],
|
|
30
|
+
"nosqldbs" => ["table_arn"]
|
|
31
|
+
}
|
|
32
|
+
|
|
21
33
|
# Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like +@vpc+, for us.
|
|
22
34
|
# @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
|
|
23
35
|
def initialize(**args)
|
|
@@ -29,12 +41,12 @@ module MU
|
|
|
29
41
|
def assign_tag(resource_arn, tag_list, region=@config['region'])
|
|
30
42
|
begin
|
|
31
43
|
tag_list.each do |each_pair|
|
|
32
|
-
|
|
44
|
+
MU::Cloud::AWS.lambda(region: region, credentials: @config['credentials']).tag_resource({
|
|
33
45
|
resource: resource_arn,
|
|
34
46
|
tags: each_pair
|
|
35
47
|
})
|
|
36
48
|
end
|
|
37
|
-
rescue
|
|
49
|
+
rescue StandardError => e
|
|
38
50
|
MU.log e, MU::ERR
|
|
39
51
|
end
|
|
40
52
|
end
|
|
@@ -42,92 +54,44 @@ module MU
|
|
|
42
54
|
|
|
43
55
|
# Called automatically by {MU::Deploy#createResources}
|
|
44
56
|
def create
|
|
45
|
-
role_arn = get_role_arn(@config['iam_role'])
|
|
46
57
|
|
|
47
|
-
lambda_properties =
|
|
48
|
-
code: {},
|
|
49
|
-
function_name: @mu_name,
|
|
50
|
-
handler: @config['handler'],
|
|
51
|
-
publish: true,
|
|
52
|
-
role: role_arn,
|
|
53
|
-
runtime: @config['runtime'],
|
|
54
|
-
}
|
|
58
|
+
lambda_properties = get_properties
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
lambda_properties[:code][:zip_file] = zip
|
|
60
|
-
else
|
|
61
|
-
lambda_properties[:code][:s3_bucket] = @config['code']['s3_bucket']
|
|
62
|
-
lambda_properties[:code][:s3_key] = @config['code']['s3_key']
|
|
63
|
-
if @config['code']['s3_object_version']
|
|
64
|
-
lambda_properties[:code][:s3_object_version] = @config['code']['s3_object_version']
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
if @config.has_key?('timeout')
|
|
69
|
-
lambda_properties[:timeout] = @config['timeout'].to_i ## secs
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
if @config.has_key?('memory')
|
|
73
|
-
lambda_properties[:memory_size] = @config['memory'].to_i
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
if @config.has_key?('environment_variables')
|
|
77
|
-
lambda_properties[:environment] = {
|
|
78
|
-
variables: {@config['environment_variables'][0]['key'] => @config['environment_variables'][0]['value']}
|
|
79
|
-
}
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
lambda_properties[:tags] = {}
|
|
83
|
-
MU::MommaCat.listStandardTags.each_pair { |k, v|
|
|
84
|
-
lambda_properties[:tags][k] = v
|
|
60
|
+
MU.retrier([Aws::Lambda::Errors::InvalidParameterValueException], max: 5, wait: 10) {
|
|
61
|
+
resp = MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).create_function(lambda_properties)
|
|
62
|
+
@cloud_id = resp.function_name
|
|
85
63
|
}
|
|
86
|
-
if @config['tags']
|
|
87
|
-
@config['tags'].each { |tag|
|
|
88
|
-
lambda_properties[:tags][tag.key.first] = tag.values.first
|
|
89
|
-
}
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
if @config.has_key?('vpc')
|
|
93
|
-
sgs = []
|
|
94
|
-
if @config['add_firewall_rules']
|
|
95
|
-
@config['add_firewall_rules'].each { |sg|
|
|
96
|
-
sg = @deploy.findLitterMate(type: "firewall_rule", name: sg['name'])
|
|
97
|
-
sgs << sg.cloud_id if sg and sg.cloud_id
|
|
98
|
-
}
|
|
99
|
-
end
|
|
100
|
-
if !@vpc
|
|
101
|
-
raise MuError, "Function #{@config['name']} had a VPC configured, but none was loaded"
|
|
102
|
-
end
|
|
103
|
-
lambda_properties[:vpc_config] = {
|
|
104
|
-
:subnet_ids => @vpc.subnets.map { |s| s.cloud_id },
|
|
105
|
-
:security_group_ids => sgs
|
|
106
|
-
}
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
retries = 0
|
|
110
|
-
resp = begin
|
|
111
|
-
MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).create_function(lambda_properties)
|
|
112
|
-
rescue Aws::Lambda::Errors::InvalidParameterValueException => e
|
|
113
|
-
# Freshly-made IAM roles sometimes aren't really ready
|
|
114
|
-
if retries < 5
|
|
115
|
-
sleep 10
|
|
116
|
-
retries += 1
|
|
117
|
-
retry
|
|
118
|
-
end
|
|
119
|
-
raise e
|
|
120
|
-
end
|
|
121
64
|
|
|
122
|
-
|
|
65
|
+
# the console does this and docs expect it to be there, so mimic the
|
|
66
|
+
# behavior
|
|
67
|
+
MU::Cloud::AWS.cloudwatchlogs(region: @config["region"], credentials: @credentials).create_log_group(
|
|
68
|
+
log_group_name: "/aws/lambda/#{@cloud_id}",
|
|
69
|
+
tags: @tags
|
|
70
|
+
)
|
|
123
71
|
end
|
|
124
72
|
|
|
125
73
|
# Called automatically by {MU::Deploy#createResources}
|
|
126
74
|
def groom
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
75
|
+
old_props = MU.structToHash(cloud_desc)
|
|
76
|
+
|
|
77
|
+
new_props = get_properties
|
|
78
|
+
code_block = new_props[:code]
|
|
79
|
+
new_props.reject! { |k, _v| [:code, :publish, :tags].include?(k) }
|
|
80
|
+
changes = {}
|
|
81
|
+
new_props.each_pair { |k, v|
|
|
82
|
+
changes[k] = v if v != old_props[k]
|
|
83
|
+
}
|
|
84
|
+
if !changes.empty?
|
|
85
|
+
MU.log "Updating Lambda #{@mu_name}", MU::NOTICE, details: changes
|
|
86
|
+
MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).update_function_configuration(new_props)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
if @code_sha256 and @code_sha256 != cloud_desc.code_sha_256.chomp
|
|
90
|
+
MU.log "Updating code in Lambda #{@mu_name}", MU::NOTICE, details: { "old" => @code_sha256, "new" => cloud_desc.code_sha_256 }
|
|
91
|
+
code_block[:publish] = true
|
|
92
|
+
code_block[:function_name] = @cloud_id
|
|
93
|
+
MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).update_function_code(code_block)
|
|
94
|
+
end
|
|
131
95
|
|
|
132
96
|
# tag_function = assign_tag(lambda_func.function_arn, @config['tags'])
|
|
133
97
|
|
|
@@ -141,7 +105,7 @@ module MU
|
|
|
141
105
|
### triggers must exist prior
|
|
142
106
|
if @config['triggers']
|
|
143
107
|
@config['triggers'].each { |tr|
|
|
144
|
-
trigger_arn =
|
|
108
|
+
trigger_arn = resolveARN(tr['service'], tr['name'])
|
|
145
109
|
|
|
146
110
|
trigger_properties = {
|
|
147
111
|
action: "lambda:InvokeFunction",
|
|
@@ -151,15 +115,33 @@ module MU
|
|
|
151
115
|
statement_id: "#{@mu_name}-ID-1",
|
|
152
116
|
}
|
|
153
117
|
|
|
154
|
-
MU.log
|
|
118
|
+
MU.log "Adding #{tr['service']} #{tr['name']} trigger to Lambda function #{@cloud_id}", details: trigger_properties
|
|
155
119
|
begin
|
|
156
|
-
|
|
120
|
+
MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).add_permission(trigger_properties)
|
|
157
121
|
rescue Aws::Lambda::Errors::ResourceConflictException
|
|
122
|
+
# just means the permission is already there
|
|
158
123
|
end
|
|
159
|
-
adjust_trigger(tr['service'], trigger_arn,
|
|
124
|
+
adjust_trigger(tr['service'], trigger_arn, arn, @mu_name)
|
|
160
125
|
}
|
|
161
126
|
|
|
162
127
|
end
|
|
128
|
+
|
|
129
|
+
if @config['invoke_on_completion']
|
|
130
|
+
invoke_params = {
|
|
131
|
+
function_name: @cloud_id,
|
|
132
|
+
invocation_type: @config['invoke_on_completion']['invocation_type'],
|
|
133
|
+
log_type: "Tail"
|
|
134
|
+
}
|
|
135
|
+
if @config['invoke_on_completion']['payload']
|
|
136
|
+
invoke_params[:payload] = JSON.generate(@config['invoke_on_completion']['payload'])
|
|
137
|
+
end
|
|
138
|
+
resp = MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).invoke(invoke_params)
|
|
139
|
+
if resp.status_code == 200
|
|
140
|
+
MU.log "Invoked #{@cloud_id}", MU::NOTICE, details: Base64.decode64(resp.log_result)
|
|
141
|
+
else
|
|
142
|
+
MU.log "Invoked #{@cloud_id} and got #{resp.status_code} (#{resp.function_error})", MU::WARN, details: Base64.decode64(resp.log_result)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
163
145
|
end
|
|
164
146
|
|
|
165
147
|
# Intended to be called by other Mu resources, such as Endpoints (API
|
|
@@ -170,13 +152,16 @@ module MU
|
|
|
170
152
|
function_name: @mu_name,
|
|
171
153
|
principal: "#{calling_service}.amazonaws.com",
|
|
172
154
|
source_arn: calling_arn,
|
|
173
|
-
statement_id: "#{calling_service}-#{calling_name}",
|
|
155
|
+
statement_id: "#{calling_service}-#{calling_name.gsub(/[^a-z0-9\-_]/i, '_')}",
|
|
174
156
|
}
|
|
175
157
|
|
|
176
158
|
begin
|
|
177
159
|
# XXX There doesn't seem to be an API call to list or view existing
|
|
178
160
|
# permissions, wtaf. This means we can't intelligently guard this.
|
|
179
|
-
|
|
161
|
+
MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).add_permission(trigger)
|
|
162
|
+
rescue Aws::Lambda::Errors::ValidationException => e
|
|
163
|
+
MU.log e.message+" (calling_arn: #{calling_arn}, calling_service: #{calling_service}, calling_name: #{calling_name})", MU::ERR, details: trigger
|
|
164
|
+
raise e
|
|
180
165
|
rescue Aws::Lambda::Errors::ResourceConflictException => e
|
|
181
166
|
if e.message.match(/already exists/)
|
|
182
167
|
MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).remove_permission(
|
|
@@ -192,17 +177,23 @@ module MU
|
|
|
192
177
|
end
|
|
193
178
|
|
|
194
179
|
# Look up an ARN for a given trigger type and resource name
|
|
195
|
-
def
|
|
196
|
-
supported_triggers = %w(apigateway sns events event cloudwatch_event)
|
|
180
|
+
def resolveARN(svc, name)
|
|
181
|
+
supported_triggers = %w(apigateway sns events event cloudwatch_event dynamodb)
|
|
197
182
|
if supported_triggers.include?(svc.downcase)
|
|
198
183
|
arn = nil
|
|
199
184
|
case svc.downcase
|
|
200
185
|
when 'sns'
|
|
201
|
-
|
|
186
|
+
sib_sns = @deploy.findLitterMate(name: name, type: "notifiers")
|
|
187
|
+
arn = sib_sns ? sib_sns.arn : "arn:aws:sns:#{@config['region']}:#{MU::Cloud::AWS.credToAcct(@config['credentials'])}:#{name}"
|
|
202
188
|
when 'alarm','events', 'event', 'cloudwatch_event'
|
|
203
|
-
|
|
189
|
+
sib_event = @deploy.findLitterMate(name: name, type: "job")
|
|
190
|
+
arn = sib_event ? sib_event.arn : "arn:aws:events:#{@config['region']}:#{MU::Cloud::AWS.credToAcct(@config['credentials'])}:rule/#{name}"
|
|
191
|
+
when 'dynamodb'
|
|
192
|
+
sib_dynamo = @deploy.findLitterMate(name: name, type: "nosqldb")
|
|
193
|
+
arn = sib_dynamo ? sib_dynamo.arn : "arn:aws:dynamodb:#{@config['region']}:#{MU::Cloud::AWS.credToAcct(@config['credentials'])}:table/#{name}"
|
|
204
194
|
when 'apigateway'
|
|
205
|
-
|
|
195
|
+
sib_apig = @deploy.findLitterMate(name: name, type: "endpoints")
|
|
196
|
+
arn = sib_apig ? sib_apig.arn : "arn:aws:apigateway:#{@config['region']}:#{MU::Cloud::AWS.credToAcct(@config['credentials'])}:#{name}"
|
|
206
197
|
when 's3'
|
|
207
198
|
arn = ''
|
|
208
199
|
end
|
|
@@ -219,16 +210,24 @@ module MU
|
|
|
219
210
|
case trig_type
|
|
220
211
|
|
|
221
212
|
when 'sns'
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
213
|
+
MU::Cloud.resourceClass("AWS", "Notifier").subscribe(trig_arn, arn, "lambda", region: @config['region'], credentials: @credentials)
|
|
214
|
+
when 'dynamodb'
|
|
215
|
+
stream = MU::Cloud::AWS.dynamostream(region: @config['region'], credentials: @config['credentials']).list_streams(table_name: trig_arn.sub(/.*?:table\//, '')).streams.first
|
|
216
|
+
# XXX guard this
|
|
217
|
+
MU.log "Adding DynamoDB Stream from #{stream.stream_arn} as trigger for #{@cloud_id}"
|
|
218
|
+
begin
|
|
219
|
+
MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).create_event_source_mapping(
|
|
220
|
+
event_source_arn: stream.stream_arn,
|
|
221
|
+
function_name: @cloud_id,
|
|
222
|
+
starting_position: "TRIM_HORIZON" # ...whatever that is
|
|
223
|
+
)
|
|
224
|
+
rescue ::Aws::Lambda::Errors::ResourceConflictException
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# MU::Cloud.resourceClass("AWS", "NoSQLDB").subscribe(trig_arn, arn, "lambda", region: @config['region'], credentials: @credentials)
|
|
229
228
|
when 'event','cloudwatch_event', 'events'
|
|
230
229
|
# XXX don't do this, use MU::Cloud::AWS::Log
|
|
231
|
-
|
|
230
|
+
MU::Cloud::AWS.cloudwatch_events(region: region, credentials: @config['credentials']).put_targets({
|
|
232
231
|
rule: @config['trigger']['name'],
|
|
233
232
|
targets: [
|
|
234
233
|
{
|
|
@@ -237,9 +236,8 @@ module MU
|
|
|
237
236
|
}
|
|
238
237
|
]
|
|
239
238
|
})
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
# MU.log "Creation of API Gateway integrations not yet implemented, you'll have to do this manually", MU::WARN, details: "(because we'll basically have to implement all of APIG for this)"
|
|
239
|
+
when 'apigateway'
|
|
240
|
+
addTrigger(trig_arn, "lambda", trig_arn.sub(/.*?([a-z0-9\-_]+)$/i, '\1'))
|
|
243
241
|
end
|
|
244
242
|
end
|
|
245
243
|
|
|
@@ -247,9 +245,8 @@ module MU
|
|
|
247
245
|
# Return the metadata for this Function rule
|
|
248
246
|
# @return [Hash]
|
|
249
247
|
def notify
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return deploy_struct
|
|
248
|
+
return nil if !cloud_desc
|
|
249
|
+
MU.structToHash(cloud_desc, stringify_keys: true)
|
|
253
250
|
end
|
|
254
251
|
|
|
255
252
|
# Does this resource type exist as a global (cloud-wide) artifact, or
|
|
@@ -270,12 +267,14 @@ module MU
|
|
|
270
267
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
|
271
268
|
# @param region [String]: The cloud provider region
|
|
272
269
|
# @return [void]
|
|
273
|
-
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
270
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
271
|
+
MU.log "AWS::Function.cleanup: need to support flags['known']", MU::DEBUG, details: flags
|
|
272
|
+
|
|
274
273
|
MU::Cloud::AWS.lambda(credentials: credentials, region: region).list_functions.functions.each { |f|
|
|
275
274
|
desc = MU::Cloud::AWS.lambda(credentials: credentials, region: region).get_function(
|
|
276
275
|
function_name: f.function_name
|
|
277
276
|
)
|
|
278
|
-
if desc.tags and desc.tags["MU-ID"] == MU.
|
|
277
|
+
if desc.tags and desc.tags["MU-ID"] == deploy_id and (desc.tags["MU-MASTER-IP"] == MU.mu_public_ip or ignoremaster)
|
|
279
278
|
MU.log "Deleting Lambda function #{f.function_name}"
|
|
280
279
|
if !noop
|
|
281
280
|
MU::Cloud::AWS.lambda(credentials: credentials, region: region).delete_function(
|
|
@@ -290,7 +289,7 @@ module MU
|
|
|
290
289
|
# Canonical Amazon Resource Number for this resource
|
|
291
290
|
# @return [String]
|
|
292
291
|
def arn
|
|
293
|
-
cloud_desc.function_arn
|
|
292
|
+
cloud_desc ? cloud_desc.function_arn : nil
|
|
294
293
|
end
|
|
295
294
|
|
|
296
295
|
# Locate an existing function.
|
|
@@ -312,7 +311,7 @@ module MU
|
|
|
312
311
|
# Reverse-map our cloud description into a runnable config hash.
|
|
313
312
|
# We assume that any values we have in +@config+ are placeholders, and
|
|
314
313
|
# calculate our own accordingly based on what's live in the cloud.
|
|
315
|
-
def toKitten(
|
|
314
|
+
def toKitten(**_args)
|
|
316
315
|
bok = {
|
|
317
316
|
"cloud" => "AWS",
|
|
318
317
|
"credentials" => @config['credentials'],
|
|
@@ -332,6 +331,20 @@ module MU
|
|
|
332
331
|
bok['timeout'] = cloud_desc.timeout
|
|
333
332
|
|
|
334
333
|
function = MU::Cloud::AWS.lambda(region: @config['region'], credentials: @credentials).get_function(function_name: bok['name'])
|
|
334
|
+
# event_srcs = MU::Cloud::AWS.lambda(region: @config['region'], credentials: @credentials).list_event_source_mappings(function_name: @cloud_id)
|
|
335
|
+
# if event_srcs and !event_srcs.event_source_mappings.empty?
|
|
336
|
+
# MU.log "dem mappings tho #{@cloud_id}", MU::WARN, details: event_srcs
|
|
337
|
+
# end
|
|
338
|
+
|
|
339
|
+
# begin
|
|
340
|
+
# invoke_cfg = MU::Cloud::AWS.lambda(region: @config['region'], credentials: @credentials).get_function_event_invoke_config(function_name: @cloud_id)
|
|
341
|
+
# MU.log "invoke config #{@cloud_id}", MU::WARN, details: invoke_cfg
|
|
342
|
+
# rescue ::Aws::Lambda::Errors::ResourceNotFoundException
|
|
343
|
+
# end
|
|
344
|
+
|
|
345
|
+
# MU.log @cloud_id, MU::WARN, details: cloud_desc if @cloud_id == "Espier-Scheduled-Scanner"
|
|
346
|
+
# MU.log "configuration #{@cloud_id}", MU::WARN, details: MU::Cloud::AWS.lambda(region: @config['region'], credentials: @credentials).get_function_configuration(function_name: @cloud_id) if @cloud_id == "Espier-Scheduled-Scanner"
|
|
347
|
+
|
|
335
348
|
|
|
336
349
|
if function.code.repository_type == "S3"
|
|
337
350
|
bok['code'] = {}
|
|
@@ -391,27 +404,56 @@ module MU
|
|
|
391
404
|
|
|
392
405
|
if function.configuration.role
|
|
393
406
|
shortname = function.configuration.role.sub(/.*?role\/([^\/]+)$/, '\1')
|
|
394
|
-
MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
395
407
|
bok['role'] = MU::Config::Ref.get(
|
|
396
408
|
id: shortname,
|
|
397
|
-
name: shortname,
|
|
398
409
|
cloud: "AWS",
|
|
399
410
|
type: "roles"
|
|
400
411
|
)
|
|
401
412
|
end
|
|
413
|
+
|
|
414
|
+
begin
|
|
415
|
+
pol = MU::Cloud::AWS.lambda(region: @config['region'], credentials: @credentials).get_policy(function_name: @cloud_id).policy
|
|
416
|
+
MU.log @cloud_id, MU::WARN, details: JSON.parse(pol) if @cloud_id == "ESPIER-DEV-2020080900-LN-ON-DEMAND-SCANNER"
|
|
417
|
+
if pol
|
|
418
|
+
bok['triggers'] ||= []
|
|
419
|
+
JSON.parse(pol)["Statement"].each { |s|
|
|
420
|
+
bok['triggers'] << {
|
|
421
|
+
"service" => s["Principal"]["Service"].sub(/\..*/, ''),
|
|
422
|
+
"name" => s["Resource"].sub(/.*?[:\/]([^:\/]+)$/, '\1')
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
end
|
|
426
|
+
rescue ::Aws::Lambda::Errors::ResourceNotFoundException
|
|
427
|
+
end
|
|
402
428
|
#MU.log @cloud_id, MU::NOTICE, details: function
|
|
403
|
-
# XXX
|
|
429
|
+
# XXX permissions
|
|
404
430
|
|
|
405
431
|
bok
|
|
406
432
|
end
|
|
407
433
|
|
|
408
434
|
|
|
409
435
|
# Cloud-specific configuration properties.
|
|
410
|
-
# @param
|
|
436
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
|
411
437
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
|
412
|
-
def self.schema(
|
|
438
|
+
def self.schema(_config)
|
|
413
439
|
toplevel_required = ["runtime"]
|
|
414
440
|
schema = {
|
|
441
|
+
"invoke_on_completion" => {
|
|
442
|
+
"type" => "object",
|
|
443
|
+
"description" => "Setting this will cause this Lambda function to be invoked when its groom phase is complete.",
|
|
444
|
+
"required" => ["invocation_type"],
|
|
445
|
+
"properties" => {
|
|
446
|
+
"invocation_type" => {
|
|
447
|
+
"type" => "string",
|
|
448
|
+
"enum" => ["RequestResponse", "Event", "Dryrun"],
|
|
449
|
+
"default" => "RequestReponse"
|
|
450
|
+
},
|
|
451
|
+
"payload" => {
|
|
452
|
+
"type" => "object",
|
|
453
|
+
"description" => "Optional input to the function, which will be formatted as JSON and sent for execution"
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
},
|
|
415
457
|
"triggers" => {
|
|
416
458
|
"type" => "array",
|
|
417
459
|
"items" => {
|
|
@@ -421,7 +463,7 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
|
421
463
|
"properties" => {
|
|
422
464
|
"service" => {
|
|
423
465
|
"type" => "string",
|
|
424
|
-
"enum" => %w{apigateway events s3 sns sqs dynamodb kinesis ses cognito alexa iot},
|
|
466
|
+
"enum" => %w{apigateway events s3 sns sqs dynamodb kinesis ses cognito alexa iot lex},
|
|
425
467
|
"description" => "The name of the AWS service that will trigger this function"
|
|
426
468
|
},
|
|
427
469
|
"name" => {
|
|
@@ -437,6 +479,7 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
|
437
479
|
},
|
|
438
480
|
"code" => {
|
|
439
481
|
"type" => "object",
|
|
482
|
+
"description" => "Zipped deployment package to upload to our function.",
|
|
440
483
|
"properties" => {
|
|
441
484
|
"s3_bucket" => {
|
|
442
485
|
"type" => "string",
|
|
@@ -479,6 +522,28 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
|
479
522
|
def self.validateConfig(function, configurator)
|
|
480
523
|
ok = true
|
|
481
524
|
|
|
525
|
+
if function['triggers']
|
|
526
|
+
function['triggers'].each { |t|
|
|
527
|
+
mu_type = if t["service"] == "sns"
|
|
528
|
+
"notifiers"
|
|
529
|
+
elsif t["service"] == "apigateway"
|
|
530
|
+
"endpoints"
|
|
531
|
+
elsif t["service"] == "s3"
|
|
532
|
+
"buckets"
|
|
533
|
+
elsif t["service"] == "dynamodb"
|
|
534
|
+
"nosqldbs"
|
|
535
|
+
elsif t["service"] == "events"
|
|
536
|
+
"jobs"
|
|
537
|
+
elsif t["service"] == "sqs"
|
|
538
|
+
"msg_queues"
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
if mu_type
|
|
542
|
+
MU::Config.addDependency(function, t['name'], mu_type, no_create_wait: true)
|
|
543
|
+
end
|
|
544
|
+
}
|
|
545
|
+
end
|
|
546
|
+
|
|
482
547
|
if function['vpc']
|
|
483
548
|
fwname = "lambda-#{function['name']}"
|
|
484
549
|
# default to allowing pings, if no ingress_rules were specified
|
|
@@ -502,14 +567,13 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
|
502
567
|
function["add_firewall_rules"] << {"name" => fwname}
|
|
503
568
|
function["permissions"] ||= []
|
|
504
569
|
function["permissions"] << "network"
|
|
505
|
-
function
|
|
506
|
-
function['dependencies'] << {
|
|
507
|
-
"name" => fwname,
|
|
508
|
-
"type" => "firewall_rule"
|
|
509
|
-
}
|
|
570
|
+
MU::Config.addDependency(function, fwname, "firewall_rule")
|
|
510
571
|
end
|
|
511
572
|
|
|
512
|
-
|
|
573
|
+
function['role'] ||= function['iam_role']
|
|
574
|
+
function.delete("iam_role")
|
|
575
|
+
|
|
576
|
+
if !function['role']
|
|
513
577
|
policy_map = {
|
|
514
578
|
"basic" => "AWSLambdaBasicExecutionRole",
|
|
515
579
|
"kinesis" => "AWSLambdaKinesisExecutionRole",
|
|
@@ -538,13 +602,21 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
|
538
602
|
}
|
|
539
603
|
configurator.insertKitten(roledesc, "roles")
|
|
540
604
|
|
|
541
|
-
function['
|
|
542
|
-
function['iam_role'] = function['name']+"execrole"
|
|
605
|
+
function['role'] = function['name']+"execrole"
|
|
543
606
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
607
|
+
end
|
|
608
|
+
|
|
609
|
+
if function['role'].is_a?(String)
|
|
610
|
+
function['role'] = MU::Config::Ref.get(
|
|
611
|
+
name: function['role'],
|
|
612
|
+
type: "roles",
|
|
613
|
+
cloud: "AWS",
|
|
614
|
+
credentials: function['credentials']
|
|
615
|
+
)
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
if function['role']['name']
|
|
619
|
+
MU::Config.addDependency(function, function['role']['name'], "role")
|
|
548
620
|
end
|
|
549
621
|
|
|
550
622
|
ok
|
|
@@ -552,23 +624,109 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
|
552
624
|
|
|
553
625
|
private
|
|
554
626
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
# @param name [String]
|
|
559
|
-
def get_role_arn(name)
|
|
560
|
-
sib_role = @deploy.findLitterMate(name: name, type: "roles")
|
|
561
|
-
return sib_role.cloudobj.arn if sib_role
|
|
627
|
+
def get_properties
|
|
628
|
+
role_obj = MU::Config::Ref.get(@config['role']).kitten(@deploy, cloud: "AWS")
|
|
629
|
+
raise MuError.new "Failed to fetch object from role reference", details: @config['role'].to_h if !role_obj
|
|
562
630
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
631
|
+
lambda_properties = {
|
|
632
|
+
code: {},
|
|
633
|
+
function_name: @mu_name,
|
|
634
|
+
handler: @config['handler'],
|
|
635
|
+
publish: true,
|
|
636
|
+
role: role_obj.arn,
|
|
637
|
+
runtime: @config['runtime'],
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
if @config['code']['zip_file'] or @config['code']['path']
|
|
641
|
+
tempfile = nil
|
|
642
|
+
if @config['code']['path']
|
|
643
|
+
tempfile = Tempfile.new
|
|
644
|
+
MU.log "#{@mu_name} using code at #{@config['code']['path']}"
|
|
645
|
+
MU::Master.zipDir(@config['code']['path'], tempfile.path)
|
|
646
|
+
@config['code']['zip_file'] = tempfile.path
|
|
647
|
+
else
|
|
648
|
+
MU.log "#{@mu_name} using code packaged at #{@config['code']['zip_file']}"
|
|
649
|
+
end
|
|
650
|
+
zip = File.read(@config['code']['zip_file'])
|
|
651
|
+
@code_sha256 = Base64.encode64(Digest::SHA256.digest(zip)).chomp
|
|
652
|
+
lambda_properties[:code][:zip_file] = zip
|
|
653
|
+
if tempfile
|
|
654
|
+
tempfile.close
|
|
655
|
+
tempfile.unlink
|
|
656
|
+
end
|
|
657
|
+
else
|
|
658
|
+
lambda_properties[:code][:s3_bucket] = @config['code']['s3_bucket']
|
|
659
|
+
lambda_properties[:code][:s3_key] = @config['code']['s3_key']
|
|
660
|
+
if @config['code']['s3_object_version']
|
|
661
|
+
lambda_properties[:code][:s3_object_version] = @config['code']['s3_object_version']
|
|
662
|
+
end
|
|
663
|
+
# XXX need to download to a temporarily file, read it in, and calculate the digest in order to trigger updates in groom
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
if @config.has_key?('timeout')
|
|
667
|
+
lambda_properties[:timeout] = @config['timeout'].to_i ## secs
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
if @config.has_key?('memory')
|
|
671
|
+
lambda_properties[:memory_size] = @config['memory'].to_i
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
SIBLING_VARS.each_key { |sib_type|
|
|
675
|
+
siblings = @deploy.findLitterMate(return_all: true, type: sib_type, cloud: "AWS")
|
|
676
|
+
if siblings
|
|
677
|
+
siblings.each_value { |sibling|
|
|
678
|
+
metadata = sibling.notify
|
|
679
|
+
if !metadata
|
|
680
|
+
MU.log "Failed to extract metadata from sibling #{sibling}", MU::WARN
|
|
681
|
+
next
|
|
682
|
+
end
|
|
683
|
+
SIBLING_VARS[sib_type].each { |var|
|
|
684
|
+
if metadata[var]
|
|
685
|
+
@config['environment_variables'] ||= []
|
|
686
|
+
@config['environment_variables'] << {
|
|
687
|
+
"key" => (sibling.config['name']+"_"+var).gsub(/[^a-z0-9_]/i, '_'),
|
|
688
|
+
"value" => metadata[var]
|
|
689
|
+
}
|
|
690
|
+
end
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
end
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
if @config.has_key?('environment_variables')
|
|
697
|
+
lambda_properties[:environment] = {
|
|
698
|
+
variables: Hash[@config['environment_variables'].map { |v| [v['key'], v['value']] }]
|
|
699
|
+
}
|
|
570
700
|
end
|
|
571
|
-
|
|
701
|
+
|
|
702
|
+
lambda_properties[:tags] = {}
|
|
703
|
+
MU::MommaCat.listStandardTags.each_pair { |k, v|
|
|
704
|
+
lambda_properties[:tags][k] = v
|
|
705
|
+
}
|
|
706
|
+
if @config['tags']
|
|
707
|
+
@config['tags'].each { |tag|
|
|
708
|
+
lambda_properties[:tags][tag.key.first] = tag.values.first
|
|
709
|
+
}
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
if @config.has_key?('vpc')
|
|
713
|
+
sgs = []
|
|
714
|
+
if @config['add_firewall_rules']
|
|
715
|
+
@config['add_firewall_rules'].each { |sg|
|
|
716
|
+
sg = @deploy.findLitterMate(type: "firewall_rule", name: sg['name'])
|
|
717
|
+
sgs << sg.cloud_id if sg and sg.cloud_id
|
|
718
|
+
}
|
|
719
|
+
end
|
|
720
|
+
if !@vpc
|
|
721
|
+
raise MuError, "Function #{@config['name']} had a VPC configured, but none was loaded"
|
|
722
|
+
end
|
|
723
|
+
lambda_properties[:vpc_config] = {
|
|
724
|
+
:subnet_ids => @vpc.subnets.map { |s| s.cloud_id },
|
|
725
|
+
:security_group_ids => sgs
|
|
726
|
+
}
|
|
727
|
+
end
|
|
728
|
+
|
|
729
|
+
lambda_properties
|
|
572
730
|
end
|
|
573
731
|
|
|
574
732
|
end
|