azdeploy 1.0.30 → 1.0.31
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/azdeploy.gemspec +2 -2
- data/lib/azdeploy.rb +6 -4
- data/lib/install.rb +142 -143
- data/lib/semantic_versioning.rb +280 -0
- data/lib/transform.rb +389 -389
- data/lib/update.rb +83 -83
- metadata +3 -2
data/lib/transform.rb
CHANGED
@@ -1,429 +1,429 @@
|
|
1
1
|
class Transform
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
result
|
3
|
+
attr_accessor :env
|
4
|
+
attr_accessor :svc
|
5
|
+
attr_accessor :table
|
6
|
+
attr_accessor :settings
|
7
|
+
attr_accessor :config_files
|
8
|
+
attr_accessor :debug_mode
|
9
|
+
|
10
|
+
NO_VALUE = 'no'
|
11
|
+
ROWKEY = 'RowKey'
|
12
|
+
SETTING = 'setting'
|
13
|
+
VALUE = 'value'
|
14
|
+
APPCLIENTID = 'AppClientId'
|
15
|
+
APPIDURI = 'AppIdUri'
|
16
|
+
OLDAPPID = 'AppId'
|
17
|
+
EMPTY_STR = ''
|
18
|
+
STORAGEACCOUNT = 'StorageAccount'
|
19
|
+
STORAGEACCOUNTKEY = "#{STORAGEACCOUNT}Key"
|
20
|
+
CONNECTIONSTRING = 'connectionString'
|
21
|
+
|
22
|
+
def get key
|
23
|
+
begin
|
24
|
+
result = @svc.get_entity @table, @env, key
|
25
|
+
rescue
|
26
|
+
puts $!
|
27
|
+
puts "Error retrieving key: #{@key}"
|
28
|
+
puts
|
32
29
|
end
|
33
30
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
31
|
+
result
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_all
|
35
|
+
begin
|
36
|
+
query = { :filter => "PartitionKey eq '#{@env}'" }
|
37
|
+
result = @svc.query_entities @table, query
|
38
|
+
rescue
|
39
|
+
puts $!
|
40
|
+
puts "Error retrieving table entities for Env : #{@env}"
|
41
|
+
puts
|
45
42
|
end
|
46
43
|
|
47
|
-
|
48
|
-
|
49
|
-
return
|
50
|
-
end
|
51
|
-
value = EMPTY_STR
|
52
|
-
@settings.each { |i|
|
53
|
-
if i.properties[ROWKEY] == key
|
54
|
-
value = i.properties[SETTING]
|
55
|
-
break
|
56
|
-
end
|
57
|
-
}
|
44
|
+
result
|
45
|
+
end
|
58
46
|
|
59
|
-
|
47
|
+
def get_value key
|
48
|
+
if @settings.nil?
|
49
|
+
return
|
60
50
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
51
|
+
value = EMPTY_STR
|
52
|
+
@settings.each { |i|
|
53
|
+
if i.properties[ROWKEY] == key
|
54
|
+
value = i.properties[SETTING]
|
55
|
+
break
|
56
|
+
end
|
57
|
+
}
|
58
|
+
|
59
|
+
value
|
60
|
+
end
|
61
|
+
|
62
|
+
def transform_appsettings key = EMPTY_STR, value = EMPTY_STR
|
63
|
+
# go to each file and replace value of matching appSettings key
|
64
|
+
@config_files.each{|file|
|
65
|
+
doc = Nokogiri::XML(File.read file)
|
66
|
+
puts "Processing file: #{file}"
|
67
|
+
if (key.to_s != EMPTY_STR && value.to_s != EMPTY_STR)
|
68
|
+
k = key
|
69
|
+
v = value
|
70
|
+
status = update_appsetting k, v, doc, file
|
71
|
+
if status == :updated
|
72
|
+
if @debug_mode
|
73
|
+
puts "Updated key #{k} with #{v}"
|
74
|
+
else
|
75
|
+
puts "Updated key: #{k}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
else
|
79
|
+
if !@settings.nil?
|
80
|
+
@settings.each { |i|
|
81
|
+
k = i.properties[ROWKEY] || NO_VALUE
|
82
|
+
v = i.properties[SETTING] || NO_VALUE
|
83
|
+
status = update_appsetting k, v, doc, file
|
84
|
+
if status == :updated
|
85
|
+
if @debug_mode
|
86
|
+
puts "Updated key #{k} with #{v}"
|
87
|
+
else
|
88
|
+
puts "Updated key: #{k}"
|
89
|
+
end
|
93
90
|
end
|
94
|
-
|
91
|
+
}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def update_appsetting k, v, doc, file
|
98
|
+
status = :noargs
|
99
|
+
if (k != NO_VALUE && v != NO_VALUE)
|
100
|
+
node = doc.at_css "appSettings/add[@key='#{k}']"
|
101
|
+
if !node.nil?
|
102
|
+
puts "Old value: #{node[VALUE]}" if @debug_mode
|
103
|
+
node[VALUE] = v
|
104
|
+
puts "New value: #{v}" if @debug_mode
|
105
|
+
File.write file, doc.to_xml
|
106
|
+
status = :updated
|
107
|
+
else
|
108
|
+
status = :notfound
|
109
|
+
end
|
95
110
|
end
|
96
111
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
112
|
+
status
|
113
|
+
end
|
114
|
+
|
115
|
+
def transform_servicemodelconfig
|
116
|
+
@config_files.each{|file|
|
117
|
+
doc = Nokogiri::XML(File.read file)
|
118
|
+
doc.xpath('//system.serviceModel').each do |node|
|
119
|
+
if !node.nil?
|
120
|
+
if file.end_with?('app.config') || file.end_with?('App.config')
|
121
|
+
val = get_value 'system.ServiceModel.Client'
|
122
|
+
node.replace val if !val.nil?
|
123
|
+
elsif file.end_with?('Web.config')
|
124
|
+
val = get_value 'system.ServiceModel.Service'
|
125
|
+
node.replace val if !val.nil?
|
126
|
+
end
|
127
|
+
File.write file, doc.to_xml
|
110
128
|
end
|
129
|
+
end
|
130
|
+
}
|
131
|
+
end
|
111
132
|
|
112
|
-
|
113
|
-
|
133
|
+
def transform_systemwebcompilationattribs
|
134
|
+
@config_files.each{|file|
|
135
|
+
doc = Nokogiri::XML(File.read file)
|
136
|
+
node = doc.at_css 'compilation'
|
137
|
+
if !node.nil?
|
138
|
+
#puts node
|
139
|
+
node.xpath('//@debug').remove
|
140
|
+
node.xpath('//@tempDirectory').remove
|
141
|
+
#puts node
|
142
|
+
File.write file, doc.to_xml
|
143
|
+
end
|
144
|
+
}
|
145
|
+
end
|
114
146
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
if !node.nil?
|
120
|
-
if file.end_with?('app.config') || file.end_with?('App.config')
|
121
|
-
val = get_value('system.ServiceModel.Client')
|
122
|
-
node.replace(val) if (!val.nil?)
|
123
|
-
elsif file.end_with?('Web.config')
|
124
|
-
val = get_value('system.ServiceModel.Service')
|
125
|
-
node.replace(val) if (!val.nil?)
|
126
|
-
end
|
127
|
-
File.write(file, doc.to_xml)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
}
|
131
|
-
end
|
147
|
+
def transform_csdef
|
148
|
+
csdef = Dir.glob '**/*.csdef'
|
149
|
+
csdef.each{ |file|
|
150
|
+
doc = Nokogiri::XML(File.read file)
|
132
151
|
|
133
|
-
|
134
|
-
|
135
|
-
doc = Nokogiri::XML(File.read(file))
|
136
|
-
node = doc.at_css 'compilation'
|
137
|
-
if !node.nil?
|
138
|
-
#puts node
|
139
|
-
node.xpath('//@debug').remove
|
140
|
-
node.xpath('//@tempDirectory').remove
|
141
|
-
#puts node
|
142
|
-
File.write(file, doc.to_xml)
|
143
|
-
end
|
144
|
-
}
|
145
|
-
end
|
152
|
+
node = doc.at_css 'ServiceDefinition'
|
153
|
+
node['name'] = @service_name if !node.nil?
|
146
154
|
|
147
|
-
|
148
|
-
|
149
|
-
csdef.each{ |file|
|
150
|
-
doc = Nokogiri::XML(File.read(file))
|
151
|
-
|
152
|
-
node = doc.at_css 'ServiceDefinition'
|
153
|
-
node['name'] = @service_name if !node.nil?
|
154
|
-
|
155
|
-
node = doc.at_css 'WebRole'
|
156
|
-
node['name'] = @service_name if !node.nil?
|
157
|
-
|
158
|
-
node = doc.at_css 'WorkerRole'
|
159
|
-
node['name'] = @service_name if !node.nil?
|
160
|
-
|
161
|
-
node = doc.at_css 'Certificates'
|
162
|
-
node.replace(get_value('Certificates_csdef')) if !node.nil?
|
163
|
-
|
164
|
-
node = doc.at_css 'Endpoints'
|
165
|
-
node.replace(get_value('Endpoints')) if !node.nil?
|
166
|
-
|
167
|
-
node = doc.at_css 'Bindings'
|
168
|
-
node.replace(get_value('Bindings')) if !node.nil?
|
169
|
-
|
170
|
-
node = doc.at_css 'Sites'
|
171
|
-
node.replace(get_value('Sites')) if !node.nil?
|
172
|
-
|
173
|
-
node = doc.at_css 'Imports'
|
174
|
-
node.replace(get_value('Imports')) if !node.nil?
|
175
|
-
|
176
|
-
node = doc.at_css 'LocalResources'
|
177
|
-
node.replace(get_value('LocalResources')) if !node.nil?
|
178
|
-
|
179
|
-
File.write(file, doc.to_xml)
|
180
|
-
}
|
181
|
-
end
|
155
|
+
node = doc.at_css 'WebRole'
|
156
|
+
node['name'] = @service_name if !node.nil?
|
182
157
|
|
183
|
-
|
184
|
-
|
185
|
-
csdef.each{ |file|
|
186
|
-
doc = Nokogiri::XML(File.read(file))
|
158
|
+
node = doc.at_css 'WorkerRole'
|
159
|
+
node['name'] = @service_name if !node.nil?
|
187
160
|
|
188
|
-
|
189
|
-
|
161
|
+
node = doc.at_css 'Certificates'
|
162
|
+
node.replace(get_value 'Certificates_csdef') if !node.nil?
|
190
163
|
|
191
|
-
|
192
|
-
|
164
|
+
node = doc.at_css 'Endpoints'
|
165
|
+
node.replace(get_value 'Endpoints') if !node.nil?
|
193
166
|
|
194
|
-
|
195
|
-
|
167
|
+
node = doc.at_css 'Bindings'
|
168
|
+
node.replace(get_value 'Bindings') if !node.nil?
|
196
169
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
File.write(file, doc.to_xml)
|
201
|
-
}
|
202
|
-
end
|
170
|
+
node = doc.at_css 'Sites'
|
171
|
+
node.replace(get_value 'Sites') if !node.nil?
|
203
172
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
remove_paths_from_list(paths_to_exclude, aiconfig)
|
208
|
-
|
209
|
-
aiconfig.each{ |file|
|
210
|
-
doc = Nokogiri::XML(File.read(file))
|
211
|
-
|
212
|
-
node = doc.at_css 'InstrumentationKey'
|
213
|
-
if (!node.nil?)
|
214
|
-
val_from_settings = get_value('AI_InstrumentationKey')
|
215
|
-
if (val_from_settings.to_s == EMPTY_STR)
|
216
|
-
aikey = ENV['AI_InstrumentationKey'] || NO_VALUE
|
217
|
-
else
|
218
|
-
aikey = val_from_settings
|
219
|
-
end
|
220
|
-
if (aikey != NO_VALUE)
|
221
|
-
node.content = aikey
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
File.write(file, doc.to_xml)
|
226
|
-
}
|
227
|
-
end
|
173
|
+
node = doc.at_css 'Imports'
|
174
|
+
node.replace(get_value 'Imports') if !node.nil?
|
228
175
|
|
229
|
-
|
230
|
-
|
231
|
-
csdef.each{ |file|
|
232
|
-
doc = Nokogiri::XML(File.read(file))
|
233
|
-
|
234
|
-
node = doc.at_css "PrivateConfig/#{STORAGEACCOUNT}"
|
235
|
-
node['name'] = get_value(STORAGEACCOUNT)
|
236
|
-
node['key'] = get_value(STORAGEACCOUNTKEY)
|
237
|
-
node = doc.at_css STORAGEACCOUNT
|
238
|
-
node.content = get_value(STORAGEACCOUNT)
|
239
|
-
|
240
|
-
File.write(file, doc.to_xml)
|
241
|
-
}
|
242
|
-
end
|
176
|
+
node = doc.at_css 'LocalResources'
|
177
|
+
node.replace(get_value 'LocalResources') if !node.nil?
|
243
178
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
doc = Nokogiri::XML(File.read(file))
|
179
|
+
File.write file, doc.to_xml
|
180
|
+
}
|
181
|
+
end
|
248
182
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
183
|
+
def transform_cscfg
|
184
|
+
csdef = Dir.glob '**/*.cscfg'
|
185
|
+
csdef.each{ |file|
|
186
|
+
doc = Nokogiri::XML(File.read file)
|
253
187
|
|
254
|
-
|
255
|
-
|
256
|
-
end
|
257
|
-
|
258
|
-
# log level and azure table appender parameters are transformed
|
259
|
-
def transform_log4net
|
260
|
-
config_files = Dir.glob('**/log4net.config')
|
261
|
-
config_files.each{ |file|
|
262
|
-
doc = Nokogiri::XML(File.read(file))
|
263
|
-
|
264
|
-
# azure table name is service name
|
265
|
-
node = doc.at_css 'log4net/appender[@name=AzureTableAppender]/param[@name=TableName]'
|
266
|
-
node['value'] = @service_name if (!node.nil?)
|
267
|
-
|
268
|
-
node = doc.at_css 'log4net/appender[@name=AzureTableAppender]/param[@name=ConnectionString]'
|
269
|
-
log_connstr = ENV["log#{CONNECTIONSTRING}"] || NO_VALUE
|
270
|
-
if log_connstr == NO_VALUE
|
271
|
-
puts "No logging #{CONNECTIONSTRING} found."
|
272
|
-
else
|
273
|
-
node['value'] = log_connstr if (!node.nil?)
|
274
|
-
end
|
275
|
-
|
276
|
-
# log level
|
277
|
-
node = doc.at_css 'log4net/root/level'
|
278
|
-
node['value'] = ENV['loglevel'] if (!node.nil?)
|
279
|
-
|
280
|
-
File.write(file, doc.to_xml)
|
281
|
-
}
|
282
|
-
end
|
283
|
-
|
284
|
-
def remove_paths_from_list(paths_to_exclude, source_list)
|
285
|
-
paths_to_exclude.each { |path|
|
286
|
-
source_list.delete_if { |file|
|
287
|
-
file.include?(path)
|
288
|
-
}
|
289
|
-
}
|
290
|
-
end
|
291
|
-
|
292
|
-
# paths_to_exclude is array of partial or full paths of projects where transform needs skipped
|
293
|
-
def transform(paths_to_exclude = [])
|
294
|
-
|
295
|
-
@debug_mode = ENV['transform_debug_mode']
|
296
|
-
|
297
|
-
# --- Get environment invoked
|
298
|
-
@env = ENV['env'] || NO_VALUE
|
299
|
-
if @env == NO_VALUE
|
300
|
-
puts 'Environment name required to transform. No configuration changes will be done...'
|
301
|
-
return false
|
302
|
-
else
|
303
|
-
puts "Transforming config for environment: #{@env} ..."
|
304
|
-
end
|
188
|
+
node = doc.at_css 'ServiceConfiguration'
|
189
|
+
node['serviceName'] = @service_name if !node.nil?
|
305
190
|
|
306
|
-
|
307
|
-
|
308
|
-
if (settings_account_name == NO_VALUE)
|
309
|
-
puts "No settings storage account name found"
|
310
|
-
return false
|
311
|
-
end
|
312
|
-
settings_access_key = ENV['SettingsAccountKey'] || ENV[STORAGEACCOUNTKEY] || NO_VALUE
|
313
|
-
if (settings_access_key == NO_VALUE)
|
314
|
-
puts "No settings storage account key found"
|
315
|
-
return false
|
316
|
-
end
|
317
|
-
config_table = ENV['ConfigSettingsTable'] || NO_VALUE
|
318
|
-
if (config_table == NO_VALUE)
|
319
|
-
puts "No configuration table found"
|
320
|
-
end
|
191
|
+
node = doc.at_css 'Role'
|
192
|
+
node['name'] = @service_name if !node.nil?
|
321
193
|
|
322
|
-
|
323
|
-
|
324
|
-
@config_files = Dir.glob('**/app.config')
|
325
|
-
@config_files.concat(Dir.glob('**/appSettings.config'))
|
326
|
-
@config_files.concat(Dir.glob('**/web.config'))
|
327
|
-
@config_files.concat(Dir.glob('**/RuntimeWeb/*Web.dll.config'))
|
328
|
-
@config_files.concat(Dir.glob('**/RuntimeService/*.exe.config'))
|
329
|
-
|
330
|
-
# remove projects which need not be transformed
|
331
|
-
remove_paths_from_list(paths_to_exclude, @config_files)
|
332
|
-
|
333
|
-
# --- Load Settings from storage
|
334
|
-
# azure table storage account where settings reside
|
335
|
-
Azure.config.storage_account_name = settings_account_name
|
336
|
-
Azure.config.storage_access_key = settings_access_key
|
337
|
-
@table = config_table
|
338
|
-
|
339
|
-
# table service
|
340
|
-
@svc = Azure::TableService.new
|
341
|
-
|
342
|
-
# get all settings for environment
|
343
|
-
@settings = get_all
|
344
|
-
|
345
|
-
# --- Start Transformations ---
|
346
|
-
puts "updating settings #{CONNECTIONSTRING}..."
|
347
|
-
settings_connstr = "DefaultEndpointsProtocol=https;AccountName=#{settings_account_name};AccountKey=#{settings_access_key}"
|
348
|
-
should_update_settings_connstr = ENV['should_update_settings_connstr'] || NO_VALUE
|
349
|
-
if should_update_settings_connstr == NO_VALUE
|
350
|
-
puts "Flag for Setttings #{CONNECTIONSTRING} Update not set."
|
351
|
-
else
|
352
|
-
transform_appsettings(CONNECTIONSTRING, settings_connstr)
|
353
|
-
end
|
194
|
+
node = doc.at_css 'Certificates'
|
195
|
+
node.replace(get_value 'Certificates_cscfg') if !node.nil?
|
354
196
|
|
355
|
-
|
356
|
-
|
357
|
-
if unitest_connstr == NO_VALUE
|
358
|
-
puts "No unit test #{CONNECTIONSTRING} found."
|
359
|
-
else
|
360
|
-
transform_appsettings("unitest#{CONNECTIONSTRING}", unitest_connstr)
|
361
|
-
end
|
197
|
+
node = doc.at_css 'ConfigurationSettings'
|
198
|
+
node.replace(get_value 'ConfigurationSettings_cscfg') if !node.nil?
|
362
199
|
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
transform_appsettings(APPCLIENTID, appClientId)
|
375
|
-
end
|
200
|
+
File.write file, doc.to_xml
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
204
|
+
def transform_appinsights paths_to_exclude
|
205
|
+
aiconfig = Dir.glob '**/ApplicationInsights.config'
|
206
|
+
|
207
|
+
remove_paths_from_list paths_to_exclude, aiconfig
|
208
|
+
|
209
|
+
aiconfig.each{ |file|
|
210
|
+
doc = Nokogiri::XML(File.read file)
|
376
211
|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
212
|
+
node = doc.at_css 'InstrumentationKey'
|
213
|
+
if !node.nil?
|
214
|
+
val_from_settings = get_value 'AI_InstrumentationKey'
|
215
|
+
if val_from_settings.to_s == EMPTY_STR
|
216
|
+
aikey = ENV['AI_InstrumentationKey'] || NO_VALUE
|
381
217
|
else
|
382
|
-
|
218
|
+
aikey = val_from_settings
|
383
219
|
end
|
384
|
-
|
385
|
-
|
386
|
-
is_service = @service_name || NO_VALUE
|
387
|
-
if is_service != NO_VALUE
|
388
|
-
puts "Transforming config for service: #{@service_name}"
|
389
|
-
|
390
|
-
puts 'Obtaining cloud configuration templates...'
|
391
|
-
csdefTemplate = get_value('ServiceDefinitionTemplate')
|
392
|
-
File.write('ServiceDefinition.csdef', csdefTemplate)
|
393
|
-
cscfgTemplate = get_value('ServiceConfigurationTemplate')
|
394
|
-
File.write('ServiceConfiguration.cscfg', cscfgTemplate)
|
395
|
-
|
396
|
-
puts 'Transforming csdef...'
|
397
|
-
transform_csdef
|
398
|
-
|
399
|
-
puts 'Transforming cscfg...'
|
400
|
-
transform_cscfg
|
401
|
-
|
402
|
-
puts 'Transforming diagnostics cfg...'
|
403
|
-
transform_diagnosticscfg
|
404
|
-
|
405
|
-
puts 'Replacing service model settings...'
|
406
|
-
transform_servicemodelconfig
|
407
|
-
else
|
408
|
-
puts 'Target to transform is not a service...'
|
220
|
+
if aikey != NO_VALUE
|
221
|
+
node.content = aikey
|
409
222
|
end
|
410
|
-
|
411
|
-
|
412
|
-
|
223
|
+
end
|
224
|
+
|
225
|
+
File.write file, doc.to_xml
|
226
|
+
}
|
227
|
+
end
|
228
|
+
|
229
|
+
def transform_diagnosticscfg
|
230
|
+
csdef = Dir.glob '**/*.wadcfgx'
|
231
|
+
csdef.each{ |file|
|
232
|
+
doc = Nokogiri::XML(File.read file)
|
233
|
+
|
234
|
+
node = doc.at_css "PrivateConfig/#{STORAGEACCOUNT}"
|
235
|
+
node['name'] = get_value STORAGEACCOUNT
|
236
|
+
node['key'] = get_value STORAGEACCOUNTKEY
|
237
|
+
node = doc.at_css STORAGEACCOUNT
|
238
|
+
node.content = get_value STORAGEACCOUNT
|
239
|
+
|
240
|
+
File.write file, doc.to_xml
|
241
|
+
}
|
242
|
+
end
|
243
|
+
|
244
|
+
def transform_cacheclient
|
245
|
+
cacheclient_id = get_value 'CacheClient_Identifier'
|
246
|
+
@config_files.each{ |file|
|
247
|
+
doc = Nokogiri::XML(File.read file)
|
248
|
+
|
249
|
+
node = doc.at_css 'dataCacheClients/dataCacheClient/autoDiscover'
|
250
|
+
if !node.nil?
|
251
|
+
node['identifier'] = cacheclient_id
|
252
|
+
end
|
253
|
+
|
254
|
+
File.write file, doc.to_xml
|
255
|
+
}
|
256
|
+
end
|
257
|
+
|
258
|
+
# log level and azure table appender parameters are transformed
|
259
|
+
def transform_log4net
|
260
|
+
config_files = Dir.glob '**/log4net.config'
|
261
|
+
config_files.each{ |file|
|
262
|
+
doc = Nokogiri::XML(File.read file)
|
263
|
+
|
264
|
+
# azure table name is service name
|
265
|
+
node = doc.at_css 'log4net/appender[@name=AzureTableAppender]/param[@name=TableName]'
|
266
|
+
node['value'] = @service_name if !node.nil?
|
267
|
+
|
268
|
+
node = doc.at_css 'log4net/appender[@name=AzureTableAppender]/param[@name=ConnectionString]'
|
269
|
+
log_connstr = ENV["log#{CONNECTIONSTRING}"] || NO_VALUE
|
270
|
+
if log_connstr == NO_VALUE
|
271
|
+
puts "No logging #{CONNECTIONSTRING} found."
|
272
|
+
else
|
273
|
+
node['value'] = log_connstr if !node.nil?
|
274
|
+
end
|
275
|
+
|
276
|
+
# log level
|
277
|
+
node = doc.at_css 'log4net/root/level'
|
278
|
+
node['value'] = ENV['loglevel'] if !node.nil?
|
279
|
+
|
280
|
+
File.write file, doc.to_xml
|
281
|
+
}
|
282
|
+
end
|
283
|
+
|
284
|
+
def remove_paths_from_list paths_to_exclude, source_list
|
285
|
+
paths_to_exclude.each { |path|
|
286
|
+
source_list.delete_if { |file|
|
287
|
+
file.include? path
|
288
|
+
}
|
289
|
+
}
|
290
|
+
end
|
291
|
+
|
292
|
+
# paths_to_exclude is array of partial or full paths of projects where transform needs skipped
|
293
|
+
def transform paths_to_exclude = []
|
294
|
+
|
295
|
+
@debug_mode = ENV['transform_debug_mode']
|
296
|
+
|
297
|
+
# --- Get environment invoked
|
298
|
+
@env = ENV['env'] || NO_VALUE
|
299
|
+
if @env == NO_VALUE
|
300
|
+
puts 'Environment name required to transform. No configuration changes will be done...'
|
301
|
+
return false
|
302
|
+
else
|
303
|
+
puts "Transforming config for environment: #{@env} ..."
|
304
|
+
end
|
305
|
+
|
306
|
+
# --- Get Settings Account Name, Key and Table from Environment variables
|
307
|
+
settings_account_name = ENV['SettingsAccount'] || ENV[STORAGEACCOUNT] || NO_VALUE
|
308
|
+
if settings_account_name == NO_VALUE
|
309
|
+
puts "No settings storage account name found"
|
310
|
+
return false
|
311
|
+
end
|
312
|
+
settings_access_key = ENV['SettingsAccountKey'] || ENV[STORAGEACCOUNTKEY] || NO_VALUE
|
313
|
+
if settings_access_key == NO_VALUE
|
314
|
+
puts "No settings storage account key found"
|
315
|
+
return false
|
316
|
+
end
|
317
|
+
config_table = ENV['ConfigSettingsTable'] || NO_VALUE
|
318
|
+
if config_table == NO_VALUE
|
319
|
+
puts "No configuration table found"
|
320
|
+
end
|
321
|
+
|
322
|
+
# --- Collect config files to transform
|
323
|
+
# find all App.config and web.config files
|
324
|
+
@config_files = Dir.glob '**/app.config'
|
325
|
+
@config_files.concat(Dir.glob '**/appSettings.config')
|
326
|
+
@config_files.concat(Dir.glob '**/web.config')
|
327
|
+
@config_files.concat(Dir.glob '**/RuntimeWeb/*Web.dll.config')
|
328
|
+
@config_files.concat(Dir.glob '**/RuntimeService/*.exe.config')
|
329
|
+
|
330
|
+
# remove projects which need not be transformed
|
331
|
+
remove_paths_from_list paths_to_exclude, @config_files
|
332
|
+
|
333
|
+
# --- Load Settings from storage
|
334
|
+
# azure table storage account where settings reside
|
335
|
+
Azure.config.storage_account_name = settings_account_name
|
336
|
+
Azure.config.storage_access_key = settings_access_key
|
337
|
+
@table = config_table
|
338
|
+
|
339
|
+
# table service
|
340
|
+
@svc = Azure::TableService.new
|
341
|
+
|
342
|
+
# get all settings for environment
|
343
|
+
@settings = get_all
|
344
|
+
|
345
|
+
# --- Start Transformations ---
|
346
|
+
puts "updating settings #{CONNECTIONSTRING}..."
|
347
|
+
settings_connstr = "DefaultEndpointsProtocol=https;AccountName=#{settings_account_name};AccountKey=#{settings_access_key}"
|
348
|
+
should_update_settings_connstr = ENV['should_update_settings_connstr'] || NO_VALUE
|
349
|
+
if should_update_settings_connstr == NO_VALUE
|
350
|
+
puts "Flag for Setttings #{CONNECTIONSTRING} Update not set."
|
351
|
+
else
|
352
|
+
transform_appsettings CONNECTIONSTRING, settings_connstr
|
353
|
+
end
|
354
|
+
|
355
|
+
puts "updating unit test #{CONNECTIONSTRING}..."
|
356
|
+
unitest_connstr = ENV["unitest#{CONNECTIONSTRING}"] || NO_VALUE
|
357
|
+
if unitest_connstr == NO_VALUE
|
358
|
+
puts "No unit test #{CONNECTIONSTRING} found."
|
359
|
+
else
|
360
|
+
transform_appsettings "unitest#{CONNECTIONSTRING}", unitest_connstr
|
361
|
+
end
|
362
|
+
|
363
|
+
puts "updating #{APPCLIENTID}..."
|
364
|
+
appClientId = ENV[APPCLIENTID] || NO_VALUE
|
365
|
+
if appClientId == NO_VALUE
|
366
|
+
puts "No #{APPCLIENTID} found."
|
367
|
+
# old version notify check
|
368
|
+
oldAppId = ENV[OLDAPPID]
|
369
|
+
if oldAppId != NO_VALUE
|
370
|
+
puts "You appear to be using the old AppId environment variable, AppClientId is expected. Proceeding with old AppId update."
|
371
|
+
transform_appsettings OLDAPPID, oldAppId
|
372
|
+
end
|
373
|
+
else
|
374
|
+
transform_appsettings APPCLIENTID, appClientId
|
375
|
+
end
|
376
|
+
|
377
|
+
puts "updating #{APPIDURI}..."
|
378
|
+
appIdUri = ENV[APPIDURI] || NO_VALUE
|
379
|
+
if appIdUri == NO_VALUE
|
380
|
+
puts "No #{APPIDURI} found."
|
381
|
+
else
|
382
|
+
transform_appsettings APPIDURI, appIdUri
|
383
|
+
end
|
384
|
+
|
385
|
+
@service_name = ENV['ServiceName']
|
386
|
+
is_service = @service_name || NO_VALUE
|
387
|
+
if is_service != NO_VALUE
|
388
|
+
puts "Transforming config for service: #{@service_name}"
|
413
389
|
|
414
|
-
|
415
|
-
|
390
|
+
puts 'Obtaining cloud configuration templates...'
|
391
|
+
csdefTemplate = get_value 'ServiceDefinitionTemplate'
|
392
|
+
File.write 'ServiceDefinition.csdef', csdefTemplate
|
393
|
+
cscfgTemplate = get_value 'ServiceConfigurationTemplate'
|
394
|
+
File.write 'ServiceConfiguration.cscfg', cscfgTemplate
|
416
395
|
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
puts 'Transforming Application Insights...'
|
421
|
-
transform_appinsights(paths_to_exclude)
|
396
|
+
puts 'Transforming csdef...'
|
397
|
+
transform_csdef
|
422
398
|
|
423
|
-
|
424
|
-
|
399
|
+
puts 'Transforming cscfg...'
|
400
|
+
transform_cscfg
|
425
401
|
|
426
|
-
|
402
|
+
puts 'Transforming diagnostics cfg...'
|
403
|
+
transform_diagnosticscfg
|
404
|
+
|
405
|
+
puts 'Replacing service model settings...'
|
406
|
+
transform_servicemodelconfig
|
407
|
+
else
|
408
|
+
puts 'Target to transform is not a service...'
|
427
409
|
end
|
428
410
|
|
429
|
-
|
411
|
+
puts 'Replacing app settings...'
|
412
|
+
transform_appsettings
|
413
|
+
|
414
|
+
puts 'Removing debug compilation attributes...'
|
415
|
+
transform_systemwebcompilationattribs
|
416
|
+
|
417
|
+
puts 'Transforming cache client...'
|
418
|
+
transform_cacheclient
|
419
|
+
|
420
|
+
puts 'Transforming Application Insights...'
|
421
|
+
transform_appinsights paths_to_exclude
|
422
|
+
|
423
|
+
puts 'Transforming log4net config...'
|
424
|
+
transform_log4net
|
425
|
+
|
426
|
+
return true
|
427
|
+
end
|
428
|
+
|
429
|
+
end
|