sparkle_formation 2.1.4 → 2.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/docs/anatomy.md +1 -1
- data/docs/building-blocks.md +22 -0
- data/lib/sparkle_formation.rb +1 -0
- data/lib/sparkle_formation/composition.rb +179 -0
- data/lib/sparkle_formation/resources/aws_resources.json +330 -15
- data/lib/sparkle_formation/resources/azure_resources.json +46 -0
- data/lib/sparkle_formation/resources/heat_resources.json +650 -59
- data/lib/sparkle_formation/resources/rackspace_resources.json +171 -74
- data/lib/sparkle_formation/sparkle_formation.rb +42 -48
- data/lib/sparkle_formation/version.rb +1 -1
- metadata +3 -2
@@ -190,33 +190,6 @@
|
|
190
190
|
}
|
191
191
|
}
|
192
192
|
},
|
193
|
-
"OS::Heat::ResourceChain": {
|
194
|
-
"properties": [
|
195
|
-
"concurrent",
|
196
|
-
"resource_properties",
|
197
|
-
"resources"
|
198
|
-
],
|
199
|
-
"full_properties": {
|
200
|
-
"resources": {
|
201
|
-
"description": "The list of resource types to create. This list may contain type names or aliases defined in the resource registry. Specific template names are not supported.",
|
202
|
-
"required": true,
|
203
|
-
"type": "list",
|
204
|
-
"update_causes": "none"
|
205
|
-
},
|
206
|
-
"concurrent": {
|
207
|
-
"description": "If true, the resources in the chain will be created concurrently. If false or omitted, each resource will be treated as having a dependency on the previous resource in the list.",
|
208
|
-
"required": false,
|
209
|
-
"type": "boolean",
|
210
|
-
"update_causes": "replacement"
|
211
|
-
},
|
212
|
-
"resource_properties": {
|
213
|
-
"description": "Properties to pass to each resource being created in the chain.",
|
214
|
-
"required": false,
|
215
|
-
"type": "map",
|
216
|
-
"update_causes": "replacement"
|
217
|
-
}
|
218
|
-
}
|
219
|
-
},
|
220
193
|
"OS::Heat::ResourceGroup": {
|
221
194
|
"properties": [
|
222
195
|
"count",
|
@@ -507,7 +480,9 @@
|
|
507
480
|
"OS::Heat::TestResource": {
|
508
481
|
"properties": [
|
509
482
|
"action_wait_secs",
|
483
|
+
"attr_wait_secs",
|
510
484
|
"client_name",
|
485
|
+
"constraint_prop_secs",
|
511
486
|
"entity_name",
|
512
487
|
"fail",
|
513
488
|
"update_replace",
|
@@ -521,12 +496,24 @@
|
|
521
496
|
"type": "map",
|
522
497
|
"update_causes": "none"
|
523
498
|
},
|
499
|
+
"attr_wait_secs": {
|
500
|
+
"description": "Number value for timeout during resolving output value.",
|
501
|
+
"required": false,
|
502
|
+
"type": "number",
|
503
|
+
"update_causes": "none"
|
504
|
+
},
|
524
505
|
"client_name": {
|
525
506
|
"description": "Client to poll.",
|
526
507
|
"required": false,
|
527
508
|
"type": "string",
|
528
509
|
"update_causes": "none"
|
529
510
|
},
|
511
|
+
"constraint_prop_secs": {
|
512
|
+
"description": "Number value for delay during resolve constraint.",
|
513
|
+
"required": false,
|
514
|
+
"type": "number",
|
515
|
+
"update_causes": "none"
|
516
|
+
},
|
530
517
|
"entity_name": {
|
531
518
|
"description": "Client entity to poll.",
|
532
519
|
"required": false,
|
@@ -559,40 +546,6 @@
|
|
559
546
|
}
|
560
547
|
}
|
561
548
|
},
|
562
|
-
"OS::Neutron::AddressScope": {
|
563
|
-
"properties": [
|
564
|
-
"ip_version",
|
565
|
-
"name",
|
566
|
-
"shared",
|
567
|
-
"tenant_id"
|
568
|
-
],
|
569
|
-
"full_properties": {
|
570
|
-
"name": {
|
571
|
-
"description": "The name for the address scope.",
|
572
|
-
"required": true,
|
573
|
-
"type": "string",
|
574
|
-
"update_causes": "none"
|
575
|
-
},
|
576
|
-
"ip_version": {
|
577
|
-
"description": "Address family of the address scope, which is 4 or 6.",
|
578
|
-
"required": false,
|
579
|
-
"type": "integer",
|
580
|
-
"update_causes": "replacement"
|
581
|
-
},
|
582
|
-
"shared": {
|
583
|
-
"description": "Whether the address scope should be shared to other tenants. Note that the default policy setting restricts usage of this attribute to administrative users only, and restricts changing of shared address scope to unshared with update.",
|
584
|
-
"required": false,
|
585
|
-
"type": "boolean",
|
586
|
-
"update_causes": "none"
|
587
|
-
},
|
588
|
-
"tenant_id": {
|
589
|
-
"description": "The owner tenant ID of the address scope. Only administrative users can specify a tenant ID other than their own.",
|
590
|
-
"required": false,
|
591
|
-
"type": "string",
|
592
|
-
"update_causes": "replacement"
|
593
|
-
}
|
594
|
-
}
|
595
|
-
},
|
596
549
|
"OS::Neutron::Net": {
|
597
550
|
"properties": [
|
598
551
|
"admin_state_up",
|
@@ -670,7 +623,7 @@
|
|
670
623
|
"description": "Network this port belongs to. If you plan to use current port to assign Floating IP, you should specify fixed_ips with subnet. Note if this changes to a different network update, the port will be replaced",
|
671
624
|
"required": true,
|
672
625
|
"type": "string",
|
673
|
-
"update_causes": "
|
626
|
+
"update_causes": "replacement"
|
674
627
|
},
|
675
628
|
"device_id": {
|
676
629
|
"description": "Device ID of this port.",
|
@@ -710,6 +663,47 @@
|
|
710
663
|
}
|
711
664
|
}
|
712
665
|
},
|
666
|
+
"OS::Neutron::RBACPolicy": {
|
667
|
+
"properties": [
|
668
|
+
"action",
|
669
|
+
"object_id",
|
670
|
+
"object_type",
|
671
|
+
"target_tenant",
|
672
|
+
"tenant_id"
|
673
|
+
],
|
674
|
+
"full_properties": {
|
675
|
+
"action": {
|
676
|
+
"description": "Action for the RBAC policy.",
|
677
|
+
"required": true,
|
678
|
+
"type": "string",
|
679
|
+
"update_causes": "replacement"
|
680
|
+
},
|
681
|
+
"object_id": {
|
682
|
+
"description": "ID or name of the RBAC object.",
|
683
|
+
"required": true,
|
684
|
+
"type": "string",
|
685
|
+
"update_causes": "replacement"
|
686
|
+
},
|
687
|
+
"object_type": {
|
688
|
+
"description": "Type of the object that RBAC policy affects.",
|
689
|
+
"required": true,
|
690
|
+
"type": "string",
|
691
|
+
"update_causes": "replacement"
|
692
|
+
},
|
693
|
+
"target_tenant": {
|
694
|
+
"description": "ID of the tenant to which the RBAC policy will be enforced.",
|
695
|
+
"required": true,
|
696
|
+
"type": "string",
|
697
|
+
"update_causes": "none"
|
698
|
+
},
|
699
|
+
"tenant_id": {
|
700
|
+
"description": "The owner tenant ID. Only required if the caller has an administrative role and wants to create a RBAC for another tenant.",
|
701
|
+
"required": false,
|
702
|
+
"type": "string",
|
703
|
+
"update_causes": "replacement"
|
704
|
+
}
|
705
|
+
}
|
706
|
+
},
|
713
707
|
"OS::Neutron::SecurityGroup": {
|
714
708
|
"properties": [
|
715
709
|
"description",
|
@@ -1068,13 +1062,13 @@
|
|
1068
1062
|
"description": "Reference to a flavor for creating DB instance.",
|
1069
1063
|
"required": true,
|
1070
1064
|
"type": "string",
|
1071
|
-
"update_causes": "
|
1065
|
+
"update_causes": "none"
|
1072
1066
|
},
|
1073
1067
|
"size": {
|
1074
1068
|
"description": "Database volume size in GB.",
|
1075
1069
|
"required": true,
|
1076
1070
|
"type": "integer",
|
1077
|
-
"update_causes": "
|
1071
|
+
"update_causes": "none"
|
1078
1072
|
},
|
1079
1073
|
"availability_zone": {
|
1080
1074
|
"description": "Name of the availability zone for DB instance.",
|
@@ -1086,7 +1080,7 @@
|
|
1086
1080
|
"description": "List of databases to be created on DB instance creation.",
|
1087
1081
|
"required": false,
|
1088
1082
|
"type": "list",
|
1089
|
-
"update_causes": "
|
1083
|
+
"update_causes": "none"
|
1090
1084
|
},
|
1091
1085
|
"datastore_type": {
|
1092
1086
|
"description": "Name of registered datastore type.",
|
@@ -1104,7 +1098,7 @@
|
|
1104
1098
|
"description": "Name of the DB instance to create.",
|
1105
1099
|
"required": false,
|
1106
1100
|
"type": "string",
|
1107
|
-
"update_causes": "
|
1101
|
+
"update_causes": "none"
|
1108
1102
|
},
|
1109
1103
|
"networks": {
|
1110
1104
|
"description": "List of network interfaces to create on instance.",
|
@@ -1134,7 +1128,7 @@
|
|
1134
1128
|
"description": "List of users to be created on DB instance creation.",
|
1135
1129
|
"required": false,
|
1136
1130
|
"type": "list",
|
1137
|
-
"update_causes": "
|
1131
|
+
"update_causes": "none"
|
1138
1132
|
}
|
1139
1133
|
}
|
1140
1134
|
},
|
@@ -1305,7 +1299,8 @@
|
|
1305
1299
|
"StartTimeMinute",
|
1306
1300
|
"TimeZoneId",
|
1307
1301
|
"VersionRetention",
|
1308
|
-
"host_ip_address"
|
1302
|
+
"host_ip_address",
|
1303
|
+
"server"
|
1309
1304
|
],
|
1310
1305
|
"full_properties": {
|
1311
1306
|
"BackupConfigurationName": {
|
@@ -1368,12 +1363,6 @@
|
|
1368
1363
|
"type": "string",
|
1369
1364
|
"update_causes": "none"
|
1370
1365
|
},
|
1371
|
-
"host_ip_address": {
|
1372
|
-
"description": "Cloud server ip address.",
|
1373
|
-
"required": true,
|
1374
|
-
"type": "string",
|
1375
|
-
"update_causes": "replacement"
|
1376
|
-
},
|
1377
1366
|
"Enabled": {
|
1378
1367
|
"description": "Indicates backup configuration is enabled or not.",
|
1379
1368
|
"required": false,
|
@@ -1409,6 +1398,18 @@
|
|
1409
1398
|
"required": false,
|
1410
1399
|
"type": "integer",
|
1411
1400
|
"update_causes": "none"
|
1401
|
+
},
|
1402
|
+
"host_ip_address": {
|
1403
|
+
"description": "The IP address of the server to back up. Required if “server” is not specifed; should be omitted otherwise.",
|
1404
|
+
"required": false,
|
1405
|
+
"type": "string",
|
1406
|
+
"update_causes": "replacement"
|
1407
|
+
},
|
1408
|
+
"server": {
|
1409
|
+
"description": "The id of the Cloud Server to back up. Required if “host_ip_address” is not specified; should be omitted otherwise.",
|
1410
|
+
"required": false,
|
1411
|
+
"type": "string",
|
1412
|
+
"update_causes": "replacement"
|
1412
1413
|
}
|
1413
1414
|
}
|
1414
1415
|
},
|
@@ -1687,6 +1688,61 @@
|
|
1687
1688
|
}
|
1688
1689
|
}
|
1689
1690
|
},
|
1691
|
+
"Rackspace::Cloud::LBNode": {
|
1692
|
+
"properties": [
|
1693
|
+
"address",
|
1694
|
+
"condition",
|
1695
|
+
"draining_timeout",
|
1696
|
+
"load_balancer",
|
1697
|
+
"port",
|
1698
|
+
"type",
|
1699
|
+
"weight"
|
1700
|
+
],
|
1701
|
+
"full_properties": {
|
1702
|
+
"address": {
|
1703
|
+
"description": "IP address for the node.",
|
1704
|
+
"required": true,
|
1705
|
+
"type": "string",
|
1706
|
+
"update_causes": "replacement"
|
1707
|
+
},
|
1708
|
+
"load_balancer": {
|
1709
|
+
"description": "The ID of the load balancer to associate the node with.",
|
1710
|
+
"required": true,
|
1711
|
+
"type": "string",
|
1712
|
+
"update_causes": "replacement"
|
1713
|
+
},
|
1714
|
+
"port": {
|
1715
|
+
"description": "Integer value expected.",
|
1716
|
+
"required": true,
|
1717
|
+
"type": "updates",
|
1718
|
+
"update_causes": "unknown"
|
1719
|
+
},
|
1720
|
+
"condition": {
|
1721
|
+
"description": "String value expected.",
|
1722
|
+
"required": false,
|
1723
|
+
"type": "can",
|
1724
|
+
"update_causes": "unknown"
|
1725
|
+
},
|
1726
|
+
"draining_timeout": {
|
1727
|
+
"description": "The time to wait, in seconds, for the node to drain before it is deleted.",
|
1728
|
+
"required": false,
|
1729
|
+
"type": "integer",
|
1730
|
+
"update_causes": "none"
|
1731
|
+
},
|
1732
|
+
"type": {
|
1733
|
+
"description": "String value expected.",
|
1734
|
+
"required": false,
|
1735
|
+
"type": "can",
|
1736
|
+
"update_causes": "unknown"
|
1737
|
+
},
|
1738
|
+
"weight": {
|
1739
|
+
"description": "Number value expected.",
|
1740
|
+
"required": false,
|
1741
|
+
"type": "can",
|
1742
|
+
"update_causes": "unknown"
|
1743
|
+
}
|
1744
|
+
}
|
1745
|
+
},
|
1690
1746
|
"Rackspace::Cloud::LoadBalancer": {
|
1691
1747
|
"properties": [
|
1692
1748
|
"accessList",
|
@@ -1999,6 +2055,47 @@
|
|
1999
2055
|
}
|
2000
2056
|
}
|
2001
2057
|
},
|
2058
|
+
"Rackspace::CloudDatabase::ScheduledBackup": {
|
2059
|
+
"properties": [
|
2060
|
+
"day_of_week",
|
2061
|
+
"full_backup_retention",
|
2062
|
+
"hour",
|
2063
|
+
"minute",
|
2064
|
+
"source"
|
2065
|
+
],
|
2066
|
+
"full_properties": {
|
2067
|
+
"source": {
|
2068
|
+
"description": "The database or HA instance to back up.",
|
2069
|
+
"required": true,
|
2070
|
+
"type": "map",
|
2071
|
+
"update_causes": "replacement"
|
2072
|
+
},
|
2073
|
+
"day_of_week": {
|
2074
|
+
"description": "The day of the week to run the backup. Sunday is 0.",
|
2075
|
+
"required": false,
|
2076
|
+
"type": "integer",
|
2077
|
+
"update_causes": "none"
|
2078
|
+
},
|
2079
|
+
"full_backup_retention": {
|
2080
|
+
"description": "The number of full automated backups to keep.",
|
2081
|
+
"required": false,
|
2082
|
+
"type": "integer",
|
2083
|
+
"update_causes": "none"
|
2084
|
+
},
|
2085
|
+
"hour": {
|
2086
|
+
"description": "The hour of the day to run the backup. Midnight is 0.",
|
2087
|
+
"required": false,
|
2088
|
+
"type": "integer",
|
2089
|
+
"update_causes": "none"
|
2090
|
+
},
|
2091
|
+
"minute": {
|
2092
|
+
"description": "The minute of the hour to run the backup.",
|
2093
|
+
"required": false,
|
2094
|
+
"type": "integer",
|
2095
|
+
"update_causes": "none"
|
2096
|
+
}
|
2097
|
+
}
|
2098
|
+
},
|
2002
2099
|
"Rackspace::CloudMonitoring::AgentToken": {
|
2003
2100
|
"properties": [
|
2004
2101
|
"label"
|
@@ -357,10 +357,6 @@ class SparkleFormation
|
|
357
357
|
attr_reader :dynamics_directory
|
358
358
|
# @return [String] registry path
|
359
359
|
attr_reader :registry_directory
|
360
|
-
# @return [Array] components to load
|
361
|
-
attr_reader :components
|
362
|
-
# @return [Array] order of loading
|
363
|
-
attr_reader :load_order
|
364
360
|
# @return [Hash] parameters for stack generation
|
365
361
|
attr_reader :parameters
|
366
362
|
# @return [SparkleFormation] parent stack
|
@@ -377,6 +373,8 @@ class SparkleFormation
|
|
377
373
|
attr_accessor :template_path
|
378
374
|
# @return [Array<String>] black listed templates
|
379
375
|
attr_reader :blacklisted_templates
|
376
|
+
# @return [Composition]
|
377
|
+
attr_reader :composition
|
380
378
|
|
381
379
|
# Create new instance
|
382
380
|
#
|
@@ -389,7 +387,7 @@ class SparkleFormation
|
|
389
387
|
# @option options [Hash] :parameters parameters for stack generation
|
390
388
|
# @option options [Truthy, Falsey] :disable_aws_builtins do not load builtins
|
391
389
|
# @yield base context
|
392
|
-
def initialize(name, options={}, &
|
390
|
+
def initialize(name, options={}, &base_block)
|
393
391
|
@name = name.to_sym
|
394
392
|
@component_paths = []
|
395
393
|
if(options[:sparkle_collection])
|
@@ -423,25 +421,18 @@ class SparkleFormation
|
|
423
421
|
*options.fetch(:stack_resource_types, [])
|
424
422
|
].compact.uniq
|
425
423
|
@blacklisted_templates = [name]
|
426
|
-
@
|
427
|
-
@load_order = []
|
428
|
-
@overrides = []
|
424
|
+
@composition = Composition.new(self)
|
429
425
|
@parent = options[:parent]
|
430
426
|
@seed = Smash.new(
|
431
427
|
:inherit => options[:inherit],
|
432
428
|
:layering => options[:layering]
|
433
429
|
)
|
434
|
-
if(
|
435
|
-
load_block(
|
430
|
+
if(base_block)
|
431
|
+
load_block(base_block)
|
436
432
|
end
|
437
433
|
@compiled = nil
|
438
434
|
end
|
439
435
|
|
440
|
-
# @return [Array<Proc>]
|
441
|
-
def raw_overrides
|
442
|
-
@overrides
|
443
|
-
end
|
444
|
-
|
445
436
|
# Update underlying data structures based on inherit
|
446
437
|
# or layering behavior if defined for this template
|
447
438
|
#
|
@@ -494,6 +485,7 @@ class SparkleFormation
|
|
494
485
|
# @param template [SparkleFormation]
|
495
486
|
# @return [self]
|
496
487
|
def extract_template_data(template)
|
488
|
+
# TODO: Should allow forced override here for cases like: openstack -> rackspace
|
497
489
|
if(provider != template.provider)
|
498
490
|
raise TypeError.new "This template `#{name}` cannot inherit template `#{template.name}`! Provider mismatch: `#{provider}` != `#{template.provider}`" # rubocop:disable Metrics/LineLength
|
499
491
|
end
|
@@ -502,20 +494,22 @@ class SparkleFormation
|
|
502
494
|
blacklisted_templates.replace(
|
503
495
|
(blacklisted_templates + template.blacklisted_templates).map(&:to_s).uniq
|
504
496
|
)
|
505
|
-
@parameters = template.parameters
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
497
|
+
@parameters = template.parameters.to_smash.deep_merge(parameters.to_smash)
|
498
|
+
new_composition = Composition.new(self,
|
499
|
+
:components => template.composition.composite,
|
500
|
+
:overrides => composition.overrides
|
501
|
+
)
|
502
|
+
composition.components.each do |item|
|
503
|
+
if(item.respond_to?(:key) && item.key == '__base__')
|
504
|
+
item.key = Smash.new(
|
505
|
+
:template => name,
|
506
|
+
:component => :__base__,
|
507
|
+
:object_id => object_id
|
508
|
+
).checksum.to_s
|
509
|
+
end
|
510
|
+
new_composition.add_component(item)
|
511
|
+
end
|
512
|
+
@composition = new_composition
|
519
513
|
self
|
520
514
|
end
|
521
515
|
|
@@ -626,8 +620,7 @@ class SparkleFormation
|
|
626
620
|
# @param block [Proc]
|
627
621
|
# @return [TrueClass]
|
628
622
|
def block(block)
|
629
|
-
|
630
|
-
@load_order << :__base__
|
623
|
+
composition.new_component(:__base__, &block)
|
631
624
|
true
|
632
625
|
end
|
633
626
|
alias_method :load_block, :block
|
@@ -638,14 +631,13 @@ class SparkleFormation
|
|
638
631
|
# @return [self]
|
639
632
|
def load(*args)
|
640
633
|
args.each do |thing|
|
641
|
-
key = File.basename(thing.to_s).sub('.rb', '')
|
642
634
|
if(thing.is_a?(String))
|
643
635
|
# NOTE: This needs to be deprecated and removed
|
644
636
|
# TODO: deprecate
|
645
|
-
|
646
|
-
|
637
|
+
key = File.basename(thing.to_s).sub('.rb', '')
|
638
|
+
composition.new_component(key, &self.class.load_component(thing))
|
647
639
|
else
|
648
|
-
|
640
|
+
composition.new_component(thing)
|
649
641
|
end
|
650
642
|
end
|
651
643
|
self
|
@@ -656,7 +648,7 @@ class SparkleFormation
|
|
656
648
|
# @param args [Hash] optional arguments to provide state
|
657
649
|
# @yield override block
|
658
650
|
def overrides(args={}, &block)
|
659
|
-
|
651
|
+
composition.new_override(args, &block)
|
660
652
|
self
|
661
653
|
end
|
662
654
|
|
@@ -701,21 +693,23 @@ class SparkleFormation
|
|
701
693
|
if(compile_state)
|
702
694
|
compiled.set_state!(compile_state)
|
703
695
|
end
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
696
|
+
composition.each do |item|
|
697
|
+
case item
|
698
|
+
when Composition::Component
|
699
|
+
if(item.block)
|
700
|
+
self.class.build(compiled, &item.block)
|
701
|
+
else
|
702
|
+
sparkle.get(:component, item.key).monochrome.each do |component_block|
|
703
|
+
self.class.build(compiled, &component_block[:block])
|
704
|
+
end
|
710
705
|
end
|
706
|
+
when Composition::Override
|
707
|
+
if(item.args && !item.args.empty?)
|
708
|
+
compiled._set_state(item.args)
|
709
|
+
end
|
710
|
+
self.class.build(compiled, &item.block)
|
711
711
|
end
|
712
712
|
end
|
713
|
-
@overrides.each do |override|
|
714
|
-
if(override[:args] && !override[:args].empty?)
|
715
|
-
compiled._set_state(override[:args])
|
716
|
-
end
|
717
|
-
self.class.build(compiled, &override[:block])
|
718
|
-
end
|
719
713
|
if(compile_state && !compile_state.empty?)
|
720
714
|
compiled.outputs.compile_state.value MultiJson.dump(compile_state)
|
721
715
|
end
|