fog-azure-rm 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +27 -0
- data/CONTRIBUTORS.md +4 -0
- data/LICENSE.md +20 -0
- data/README.md +82 -0
- data/lib/fog/azurerm.rb +40 -0
- data/lib/fog/azurerm/compute.rb +61 -0
- data/lib/fog/azurerm/config.rb +1 -0
- data/lib/fog/azurerm/core.rb +12 -0
- data/lib/fog/azurerm/credentials.rb +37 -0
- data/lib/fog/azurerm/dns.rb +48 -0
- data/lib/fog/azurerm/models/compute/availability_set.rb +31 -0
- data/lib/fog/azurerm/models/compute/availability_sets.rb +36 -0
- data/lib/fog/azurerm/models/compute/server.rb +94 -0
- data/lib/fog/azurerm/models/compute/servers.rb +32 -0
- data/lib/fog/azurerm/models/dns/record_set.rb +28 -0
- data/lib/fog/azurerm/models/dns/record_sets.rb +44 -0
- data/lib/fog/azurerm/models/dns/zone.rb +21 -0
- data/lib/fog/azurerm/models/dns/zones.rb +30 -0
- data/lib/fog/azurerm/models/network/network_interface.rb +34 -0
- data/lib/fog/azurerm/models/network/network_interfaces.rb +35 -0
- data/lib/fog/azurerm/models/network/public_ip.rb +34 -0
- data/lib/fog/azurerm/models/network/public_ips.rb +46 -0
- data/lib/fog/azurerm/models/network/subnet.rb +34 -0
- data/lib/fog/azurerm/models/network/subnets.rb +37 -0
- data/lib/fog/azurerm/models/network/virtual_network.rb +30 -0
- data/lib/fog/azurerm/models/network/virtual_networks.rb +42 -0
- data/lib/fog/azurerm/models/resources/resource_group.rb +21 -0
- data/lib/fog/azurerm/models/resources/resource_groups.rb +28 -0
- data/lib/fog/azurerm/models/storage/storage_account.rb +37 -0
- data/lib/fog/azurerm/models/storage/storage_accounts.rb +45 -0
- data/lib/fog/azurerm/network.rb +67 -0
- data/lib/fog/azurerm/requests/compute/create_availability_set.rb +45 -0
- data/lib/fog/azurerm/requests/compute/create_virtual_machine.rb +100 -0
- data/lib/fog/azurerm/requests/compute/deallocate_virtual_machine.rb +26 -0
- data/lib/fog/azurerm/requests/compute/delete_availability_set.rb +26 -0
- data/lib/fog/azurerm/requests/compute/delete_virtual_machine.rb +26 -0
- data/lib/fog/azurerm/requests/compute/generalize_virtual_machine.rb +26 -0
- data/lib/fog/azurerm/requests/compute/get_virtual_machine.rb +24 -0
- data/lib/fog/azurerm/requests/compute/list_availability_sets.rb +24 -0
- data/lib/fog/azurerm/requests/compute/list_available_sizes_for_virtual_machine.rb +24 -0
- data/lib/fog/azurerm/requests/compute/list_virtual_machines.rb +64 -0
- data/lib/fog/azurerm/requests/compute/power_off_virtual_machine.rb +26 -0
- data/lib/fog/azurerm/requests/compute/redeploy_virtual_machine.rb +26 -0
- data/lib/fog/azurerm/requests/compute/restart_virtual_machine.rb +26 -0
- data/lib/fog/azurerm/requests/compute/start_virtual_machine.rb +26 -0
- data/lib/fog/azurerm/requests/dns/check_for_zone.rb +39 -0
- data/lib/fog/azurerm/requests/dns/create_record_set.rb +61 -0
- data/lib/fog/azurerm/requests/dns/create_zone.rb +47 -0
- data/lib/fog/azurerm/requests/dns/delete_record_set.rb +38 -0
- data/lib/fog/azurerm/requests/dns/delete_zone.rb +38 -0
- data/lib/fog/azurerm/requests/dns/get_records_from_record_set.rb +57 -0
- data/lib/fog/azurerm/requests/dns/list_record_sets.rb +44 -0
- data/lib/fog/azurerm/requests/dns/list_zones.rb +52 -0
- data/lib/fog/azurerm/requests/network/check_for_public_ip.rb +27 -0
- data/lib/fog/azurerm/requests/network/check_for_virtual_network.rb +27 -0
- data/lib/fog/azurerm/requests/network/create_network_interface.rb +52 -0
- data/lib/fog/azurerm/requests/network/create_public_ip.rb +28 -0
- data/lib/fog/azurerm/requests/network/create_subnet.rb +30 -0
- data/lib/fog/azurerm/requests/network/create_virtual_network.rb +80 -0
- data/lib/fog/azurerm/requests/network/delete_network_interface.rb +27 -0
- data/lib/fog/azurerm/requests/network/delete_public_ip.rb +27 -0
- data/lib/fog/azurerm/requests/network/delete_subnet.rb +27 -0
- data/lib/fog/azurerm/requests/network/delete_virtual_network.rb +27 -0
- data/lib/fog/azurerm/requests/network/list_network_interfaces.rb +32 -0
- data/lib/fog/azurerm/requests/network/list_public_ips.rb +32 -0
- data/lib/fog/azurerm/requests/network/list_subnets.rb +30 -0
- data/lib/fog/azurerm/requests/network/list_virtual_networks.rb +29 -0
- data/lib/fog/azurerm/requests/resources/create_resource_group.rb +27 -0
- data/lib/fog/azurerm/requests/resources/delete_resource_group.rb +25 -0
- data/lib/fog/azurerm/requests/resources/list_resource_groups.rb +28 -0
- data/lib/fog/azurerm/requests/storage/check_storage_account_name_availability.rb +33 -0
- data/lib/fog/azurerm/requests/storage/create_storage_account.rb +33 -0
- data/lib/fog/azurerm/requests/storage/delete_storage_account.rb +27 -0
- data/lib/fog/azurerm/requests/storage/list_storage_account_for_rg.rb +25 -0
- data/lib/fog/azurerm/requests/storage/list_storage_accounts.rb +28 -0
- data/lib/fog/azurerm/resources.rb +48 -0
- data/lib/fog/azurerm/storage.rb +51 -0
- data/lib/fog/azurerm/version.rb +5 -0
- metadata +278 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
require "fog/core/collection"
|
2
|
+
require "fog/azurerm/models/compute/server"
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Compute
|
6
|
+
class AzureRM
|
7
|
+
# This class is giving implementation of all/list, and get
|
8
|
+
# for Server.
|
9
|
+
class Servers < Fog::Collection
|
10
|
+
attribute :resource_group
|
11
|
+
model Fog::Compute::AzureRM::Server
|
12
|
+
|
13
|
+
def all
|
14
|
+
requires :resource_group
|
15
|
+
virtual_machines = []
|
16
|
+
service.list_virtual_machines(resource_group).each do |vm|
|
17
|
+
virtual_machines << Fog::Compute::AzureRM::Server.parse(vm)
|
18
|
+
end
|
19
|
+
load(virtual_machines)
|
20
|
+
end
|
21
|
+
|
22
|
+
def get(resource_group, identity)
|
23
|
+
all.find { |s| s.name == identity && s.resource_group == resource_group}
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_from_remote(resource_group, name)
|
27
|
+
service.get_virtual_machine(resource_group, name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class AzureRM
|
4
|
+
class RecordSet < Fog::Model
|
5
|
+
identity :name
|
6
|
+
attribute :resource_group
|
7
|
+
attribute :zone_name
|
8
|
+
attribute :records
|
9
|
+
attribute :type
|
10
|
+
attribute :ttl
|
11
|
+
|
12
|
+
def save
|
13
|
+
requires :name
|
14
|
+
requires :resource_group
|
15
|
+
requires :zone_name
|
16
|
+
requires :records
|
17
|
+
requires :type
|
18
|
+
requires :ttl
|
19
|
+
service.create_record_set(resource_group, zone_name, name, records, type, ttl)
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy
|
23
|
+
service.delete_record_set(name, resource_group, zone_name, type.split("/").last)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "fog/core/collection"
|
2
|
+
require "fog/azurerm/models/dns/record_set"
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module DNS
|
6
|
+
class AzureRM
|
7
|
+
class RecordSets < Fog::Collection
|
8
|
+
|
9
|
+
attribute :resource_group
|
10
|
+
attribute :zone_name
|
11
|
+
attribute :type
|
12
|
+
|
13
|
+
model Fog::DNS::AzureRM::RecordSet
|
14
|
+
|
15
|
+
def all
|
16
|
+
requires :resource_group
|
17
|
+
requires :zone_name
|
18
|
+
record_sets = []
|
19
|
+
exclude = false
|
20
|
+
service.list_record_sets(resource_group, zone_name).each do |r|
|
21
|
+
hash = {}
|
22
|
+
r.each do |k, v|
|
23
|
+
if (k == 'name' && v == '@')
|
24
|
+
exclude = true
|
25
|
+
end
|
26
|
+
hash[k] = v
|
27
|
+
hash['zone_name'] = zone_name
|
28
|
+
hash['resource_group'] = resource_group
|
29
|
+
end
|
30
|
+
record_sets << hash if !exclude
|
31
|
+
exclude = false
|
32
|
+
end
|
33
|
+
load(record_sets)
|
34
|
+
end
|
35
|
+
|
36
|
+
def get(identity, type)
|
37
|
+
all.find { |f| f.name == identity && f.type == "Microsoft.Network/dnszones/#{type}"}
|
38
|
+
rescue Fog::Errors::NotFound
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class AzureRM
|
4
|
+
class Zone < Fog::Model
|
5
|
+
identity :name
|
6
|
+
attribute :id
|
7
|
+
attribute :resource_group
|
8
|
+
|
9
|
+
def save
|
10
|
+
requires :name
|
11
|
+
requires :resource_group
|
12
|
+
service.create_zone(resource_group, name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy
|
16
|
+
service.delete_zone(name, resource_group)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/azurerm/models/dns/zone'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module DNS
|
6
|
+
class AzureRM
|
7
|
+
class Zones < Fog::Collection
|
8
|
+
model Fog::DNS::AzureRM::Zone
|
9
|
+
|
10
|
+
def all
|
11
|
+
zones = []
|
12
|
+
service.list_zones.each do |z|
|
13
|
+
hash = {}
|
14
|
+
z.each do |k, v|
|
15
|
+
hash[k] = v
|
16
|
+
end
|
17
|
+
zones << hash
|
18
|
+
end
|
19
|
+
load(zones)
|
20
|
+
end
|
21
|
+
|
22
|
+
def get(identity, resource_group)
|
23
|
+
all.find { |f| f.name == identity && f.resource_group == resource_group }
|
24
|
+
rescue Fog::Errors::NotFound
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Fog
|
2
|
+
module Network
|
3
|
+
class AzureRM
|
4
|
+
# NetworkInterface model class for Network Service
|
5
|
+
class NetworkInterface < Fog::Model
|
6
|
+
identity :name
|
7
|
+
attribute :location
|
8
|
+
attribute :resource_group
|
9
|
+
attribute :subnet_id
|
10
|
+
attribute :ip_configuration_name
|
11
|
+
attribute :private_ip_allocation_method
|
12
|
+
attribute :properties
|
13
|
+
|
14
|
+
def save
|
15
|
+
requires :name
|
16
|
+
requires :location
|
17
|
+
requires :resource_group
|
18
|
+
requires :subnet_id
|
19
|
+
requires :ip_configuration_name
|
20
|
+
requires :private_ip_allocation_method
|
21
|
+
|
22
|
+
Fog::Logger.debug "Creating Network Interface Card: #{name}..."
|
23
|
+
network_interface = service.create_network_interface(name, location, resource_group, subnet_id, ip_configuration_name, private_ip_allocation_method)
|
24
|
+
Fog::Logger.debug "Network Interface #{name} created successfully."
|
25
|
+
network_interface
|
26
|
+
end
|
27
|
+
|
28
|
+
def destroy
|
29
|
+
service.delete_network_interface(resource_group, name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/azurerm/models/network/network_interface'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Network
|
6
|
+
class AzureRM
|
7
|
+
# NetworkInterfaces collection class for Network Service
|
8
|
+
class NetworkInterfaces < Fog::Collection
|
9
|
+
model Fog::Network::AzureRM::NetworkInterface
|
10
|
+
attribute :resource_group
|
11
|
+
|
12
|
+
def all
|
13
|
+
requires :resource_group
|
14
|
+
network_interfaces = []
|
15
|
+
network_interface_list = service.list_network_interfaces(resource_group)
|
16
|
+
network_interface_list.each do |nic|
|
17
|
+
hash = {}
|
18
|
+
nic.instance_variables.each do |var|
|
19
|
+
hash[var.to_s.delete('@')] = nic.instance_variable_get(var)
|
20
|
+
end
|
21
|
+
hash['resource_group'] = resource_group
|
22
|
+
network_interfaces << hash
|
23
|
+
end
|
24
|
+
load(network_interfaces)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get(identity)
|
28
|
+
all.find { |f| f.name == identity }
|
29
|
+
rescue Fog::Errors::NotFound
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Fog
|
2
|
+
module Network
|
3
|
+
class AzureRM
|
4
|
+
# PublicIP model class for Network Service
|
5
|
+
class PublicIp < Fog::Model
|
6
|
+
identity :name
|
7
|
+
attribute :type
|
8
|
+
attribute :location
|
9
|
+
attribute :resource_group
|
10
|
+
|
11
|
+
def save
|
12
|
+
requires :name
|
13
|
+
requires :type
|
14
|
+
requires :location
|
15
|
+
requires :resource_group
|
16
|
+
|
17
|
+
properties = Azure::ARM::Network::Models::PublicIPAddressPropertiesFormat.new
|
18
|
+
properties.public_ipallocation_method = type
|
19
|
+
|
20
|
+
public_ip = Azure::ARM::Network::Models::PublicIPAddress.new
|
21
|
+
public_ip.name = name
|
22
|
+
public_ip.location = location
|
23
|
+
public_ip.properties = properties
|
24
|
+
|
25
|
+
service.create_public_ip(resource_group, name, public_ip)
|
26
|
+
end
|
27
|
+
|
28
|
+
def destroy
|
29
|
+
service.delete_public_ip(resource_group, name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/azurerm/models/network/public_ip'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Network
|
6
|
+
class AzureRM
|
7
|
+
# PublicIPs collection class for Network Service
|
8
|
+
class PublicIps < Fog::Collection
|
9
|
+
model Fog::Network::AzureRM::PublicIp
|
10
|
+
attribute :resource_group
|
11
|
+
|
12
|
+
def all
|
13
|
+
requires :resource_group
|
14
|
+
public_ips = []
|
15
|
+
pubip_list = service.list_public_ips(resource_group)
|
16
|
+
pubip_list.each do |pip|
|
17
|
+
hash = {}
|
18
|
+
pip.instance_variables.each do |var|
|
19
|
+
hash[var.to_s.delete('@')] = pip.instance_variable_get(var)
|
20
|
+
end
|
21
|
+
hash['resource_group'] = resource_group
|
22
|
+
public_ips << hash
|
23
|
+
end
|
24
|
+
load(public_ips)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get(identity)
|
28
|
+
all.find { |f| f.name == identity }
|
29
|
+
rescue Fog::Errors::NotFound
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def check_if_exists(resource_group, name)
|
34
|
+
Fog::Logger.debug "Checkng if PublicIP #{name} exists."
|
35
|
+
if service.check_for_public_ip(resource_group, name)
|
36
|
+
Fog::Logger.debug "PublicIP #{name} exists."
|
37
|
+
true
|
38
|
+
else
|
39
|
+
Fog::Logger.debug "PublicIP #{name} doesn't exists."
|
40
|
+
false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Fog
|
2
|
+
module Network
|
3
|
+
class AzureRM
|
4
|
+
# Subnet model for Network Service
|
5
|
+
class Subnet < Fog::Model
|
6
|
+
identity :name
|
7
|
+
attribute :id
|
8
|
+
attribute :resource_group
|
9
|
+
attribute :virtual_network_name
|
10
|
+
attribute :properties
|
11
|
+
attribute :addressPrefix
|
12
|
+
attribute :networkSecurityGroupId
|
13
|
+
attribute :routeTableId
|
14
|
+
attribute :ipConfigurations
|
15
|
+
|
16
|
+
def save
|
17
|
+
requires :name
|
18
|
+
requires :resource_group
|
19
|
+
requires :virtual_network_name
|
20
|
+
Fog::Logger.debug "Creating Subnet: #{name}..."
|
21
|
+
#puts "Creating Subnet: #{name}..."
|
22
|
+
subnet = service.create_subnet(resource_group, virtual_network_name, name, addressPrefix)
|
23
|
+
Fog::Logger.debug "Subnet #{name} created successfully."
|
24
|
+
#puts "Subnet #{name} created successfully."
|
25
|
+
subnet
|
26
|
+
end
|
27
|
+
|
28
|
+
def destroy
|
29
|
+
service.delete_subnet(resource_group, virtual_network_name, name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/azurerm/models/network/subnet'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Network
|
6
|
+
class AzureRM
|
7
|
+
# Subnet collection for network service
|
8
|
+
class Subnets < Fog::Collection
|
9
|
+
model Fog::Network::AzureRM::Subnet
|
10
|
+
attribute :resource_group
|
11
|
+
attribute :virtual_network_name
|
12
|
+
|
13
|
+
def all
|
14
|
+
requires :resource_group
|
15
|
+
requires :virtual_network_name
|
16
|
+
subnets = []
|
17
|
+
service.list_subnets(resource_group, virtual_network_name).each do |subnet|
|
18
|
+
hash = {}
|
19
|
+
subnet.instance_variables.each do |var|
|
20
|
+
hash[var.to_s.delete('@')] = subnet.instance_variable_get(var)
|
21
|
+
end
|
22
|
+
hash['resource_group'] = subnet.instance_variable_get('@id').split('/')[4]
|
23
|
+
hash['virtual_network_name'] = subnet.instance_variable_get('@id').split('/')[8]
|
24
|
+
subnets << hash
|
25
|
+
end
|
26
|
+
load(subnets)
|
27
|
+
end
|
28
|
+
|
29
|
+
def get(identity)
|
30
|
+
all.find { |f| f.name == identity }
|
31
|
+
rescue Fog::Errors::NotFound
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Fog
|
2
|
+
module Network
|
3
|
+
class AzureRM
|
4
|
+
class VirtualNetwork < Fog::Model
|
5
|
+
identity :name
|
6
|
+
attribute :id
|
7
|
+
attribute :location
|
8
|
+
attribute :dns_list
|
9
|
+
attribute :subnet_address_list
|
10
|
+
attribute :network_address_list
|
11
|
+
attribute :resource_group
|
12
|
+
attribute :properties
|
13
|
+
|
14
|
+
def save
|
15
|
+
requires :name
|
16
|
+
requires :location
|
17
|
+
requires :resource_group
|
18
|
+
Fog::Logger.debug "Creating Virtual Network: #{name}..."
|
19
|
+
virtual_network = service.create_virtual_network(name, location, resource_group, dns_list, subnet_address_list, network_address_list)
|
20
|
+
Fog::Logger.debug "Virtual Network #{name} created successfully."
|
21
|
+
virtual_network
|
22
|
+
end
|
23
|
+
|
24
|
+
def destroy
|
25
|
+
service.delete_virtual_network(resource_group, name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/azurerm/models/network/virtual_network'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Network
|
6
|
+
class AzureRM
|
7
|
+
class VirtualNetworks < Fog::Collection
|
8
|
+
model Fog::Network::AzureRM::VirtualNetwork
|
9
|
+
|
10
|
+
def all
|
11
|
+
virtual_networks = []
|
12
|
+
service.list_virtual_networks.each do |vnet|
|
13
|
+
hash = {}
|
14
|
+
vnet.instance_variables.each do |var|
|
15
|
+
hash[var.to_s.delete('@')] = vnet.instance_variable_get(var)
|
16
|
+
end
|
17
|
+
hash['resource_group'] = vnet.instance_variable_get('@id').split('/')[4]
|
18
|
+
virtual_networks << hash
|
19
|
+
end
|
20
|
+
load(virtual_networks)
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(identity, resource_group)
|
24
|
+
all.find { |f| f.name == identity && f.resource_group == resource_group }
|
25
|
+
rescue Fog::Errors::NotFound
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def check_if_exists(name, resource_group)
|
30
|
+
Fog::Logger.debug "Checkng if Virtual Network #{name} exists."
|
31
|
+
if service.check_for_virtual_network(name, resource_group)
|
32
|
+
Fog::Logger.debug "Virtual Network #{name} exists."
|
33
|
+
true
|
34
|
+
else
|
35
|
+
Fog::Logger.debug "Virtual Network #{name} doesn't exists."
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|