brpm_module_bladelogic 0.1.5

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.
data/config.yml ADDED
@@ -0,0 +1,13 @@
1
+ dependencies:
2
+ - brpm
3
+
4
+ integration_servers:
5
+ - BladeLogic
6
+
7
+ version: 0.1.5
8
+
9
+ author: Niek Bartholomeus
10
+ email: niek.bartholomeus@gmail.com
11
+ homepage: https://github.com/BMC-RLM/brpm_module_bladelogic
12
+ summary: BladeLogic automation scripts and libraries to run on top of the BRPM Content framework
13
+ description: BladeLogic automation scripts and libraries to run on top of the BRPM Content framework. See https://github.com/BMC-RLM/brpm_content for more information about the BRPM Content framework
@@ -0,0 +1,65 @@
1
+ class BsaRestClient
2
+ def initialize(integration_settings = BrpmAuto.integration_settings)
3
+ @url = integration_settings.dns
4
+ @username = integration_settings.username
5
+ @password = integration_settings.password
6
+ @role = integration_settings.details["role"]
7
+
8
+ @api_url = "#{@url}/rest/api/2"
9
+ end
10
+
11
+ def get_component_by_name(component_name)
12
+ result = run_query("SELECT * FROM \"SystemObject/Component\" WHERE NAME equals \"#{component_name}\"")
13
+
14
+ raise "BSA component '#{component_name}' not found" if result.empty?
15
+
16
+ result[0]
17
+ end
18
+
19
+ def run_query(query)
20
+ path = "query?bquery=#{query}"
21
+
22
+ BrpmAuto.log "Running query #{path}..."
23
+ result = bl_get(path)
24
+ response = result["response"]
25
+
26
+ if response.has_key? "ErrorResponse"
27
+ raise "#{response["ErrorResponse"]["Error"]}"
28
+ end
29
+
30
+ if response["PropertySetClassChildrenResponse"] && response["PropertySetClassChildrenResponse"]["PropertySetClassChildren"]
31
+ unless response["PropertySetClassChildrenResponse"]["PropertySetClassChildren"]["PropertySetInstances"]["Elements"].empty?
32
+ return response["PropertySetClassChildrenResponse"]["PropertySetClassChildren"]["PropertySetInstances"]["Elements"]
33
+ end
34
+ unless response["PropertySetClassChildrenResponse"]["PropertySetClassChildren"]["Groups"]["Elements"].empty?
35
+ return response["PropertySetClassChildrenResponse"]["PropertySetClassChildren"]["Groups"]["Elements"]
36
+ end
37
+ unless response["PropertySetClassChildrenResponse"]["PropertySetClassChildren"]["PropertySetClasses"]["Elements"].empty?
38
+ return response["PropertySetClassChildrenResponse"]["PropertySetClassChildren"]["PropertySetClasses"]["Elements"]
39
+ end
40
+ end
41
+ []
42
+ end
43
+
44
+ private
45
+
46
+ def add_credentials(path)
47
+ path + (path.include?("?") ? "&" : "?") + "username=#{@username}&password=#{@password}&role=#{@role}"
48
+ end
49
+
50
+ def bl_get(path, options = {})
51
+ Rest.get("#{@url}/#{add_credentials(path)}", options)
52
+ end
53
+
54
+ def bl_post(path, data, options = {})
55
+ Rest.post("#{@url}/#{add_credentials(path)}", data, options)
56
+ end
57
+
58
+ def bl_put(path, data, options = {})
59
+ Rest.put("#{@url}/#{add_credentials(path)}", data, options)
60
+ end
61
+
62
+ def bl_delete(path, options = {})
63
+ Rest.delete("#{@url}/#{add_credentials(path)}", options)
64
+ end
65
+ end
@@ -0,0 +1,43 @@
1
+ class BlPackage < BsaSoapBase
2
+ def create_package_from_component(options = {})
3
+ validate_cli_options_hash([:package_name, :depot_group_id, :component_key], options)
4
+ integer_result = execute_cli_with_param_list(self.class, "createPackageFromComponent",
5
+ [
6
+ options[:package_name],
7
+ options[:depot_group_id],
8
+ false, #bSoftLinked
9
+ false, #bCollectFileAcl
10
+ false, #bCollectFileAttributes
11
+ true, #bCopyFileContents
12
+ false, #bCollectRegistryAcl
13
+ options[:component_key]
14
+ ])
15
+ integer_value = get_cli_return_value(integer_result)
16
+ rescue => exception
17
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
18
+ end
19
+
20
+ def delete_blpackage_by_group_and_name(options = {})
21
+ validate_cli_options_hash([:parent_group, :package_name], options)
22
+ integer_result = execute_cli_with_param_list(self.class, "deleteBlPackageByGroupAndName",
23
+ [
24
+ options[:parent_group],
25
+ options[:package_name],
26
+ ])
27
+ integer_value = get_cli_return_value(integer_result)
28
+ rescue => exception
29
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
30
+ end
31
+
32
+ def get_dbkey_by_group_and_name(options = {})
33
+ validate_cli_options_hash([:parent_group, :depot_group_path], options)
34
+ integer_result = execute_cli_with_param_list(self.class, "getDBKeyByGroupAndName",
35
+ [
36
+ options[:parent_group],
37
+ options[:depot_group_path],
38
+ ])
39
+ integer_value = get_cli_return_value(integer_result)
40
+ rescue => exception
41
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
42
+ end
43
+ end
@@ -0,0 +1,118 @@
1
+ require 'savon'
2
+
3
+ class BsaSoapBase
4
+ # Filter out password data when logging enabled
5
+ HTTPI.log = false
6
+ Savon.configure do |config|
7
+ config._logger.filter << :password
8
+ config.log = false
9
+ end
10
+
11
+ # Module Constants
12
+ HTTP_READ_TIMEOUT = 300
13
+ DEFAULT_AUTH_TYPE = "SRP"
14
+ LOGIN_WSDL = "/services/BSALoginService.wsdl"
15
+ ROLE_WSDL = "/services/BSAAssumeRoleService.wsdl"
16
+ CLI_WSDL = "/services/BSACLITunnelService.wsdl"
17
+ LOGIN_SERVICE = "/services/LoginService"
18
+ ROLE_SERVICE = "/services/AssumeRoleService"
19
+ CLI_SERVICE = "/services/CLITunnelService"
20
+
21
+ def initialize(url, session_id)
22
+ @url = url
23
+ @session_id = session_id
24
+ end
25
+
26
+ def validate_cli_options_hash(required_keys, options)
27
+ required_keys.each { |key| raise "Invalid options hash(missing #{key}) for command, cannot continue" unless options.has_key?(key) }
28
+ end
29
+
30
+ def validate_cli_option_hash_string_values(supported_values, options_key)
31
+ supported_values.any? {
32
+ |value| raise "options key value(#{options_value}) not supported" unless options_key.eql?(value)
33
+ }
34
+ end
35
+
36
+ def get_all_servers(server_group)
37
+ result = execute_cli_with_param_list("Server", "listServersInGroup", [server_group])
38
+ servers = get_cli_return_value(result)
39
+ rescue => exception
40
+ raise "Failed to get all servers for #{server_group}: #{exception.to_s}"
41
+ end
42
+
43
+ def validate_servers(servers = [])
44
+ error = {}
45
+ servers.each do |server|
46
+ result = execute_cli_with_param_list("Server", "printPropertyValue", [server, "AGENT_STATUS"])
47
+ if result[:success] == false || result[:return_value] != "agent is alive"
48
+ error[:"#{server}"] = "cannot validate server status"
49
+ end
50
+ end
51
+ if error.length > 0
52
+ raise "Problem validating server: #{error}"
53
+ end
54
+ rescue => exception
55
+ raise "Failed to validate server: #{exception.to_s}"
56
+ end
57
+
58
+ def validate_cli_result(result)
59
+ if result && (result.is_a? Hash)
60
+ if result[:success] == false
61
+ raise "Command execution failed: #{result[:error]}, #{result[:comments]}"
62
+ end
63
+ return result
64
+ else
65
+ raise "Command execution did not return a valid response: #{result.inspect}"
66
+ end
67
+ nil
68
+ end
69
+
70
+ def get_cli_return_value(result)
71
+ if result && result.is_a?(Hash) && result.has_key?(:success) && result[:success]
72
+ return result[:return_value]
73
+ end
74
+ nil
75
+ end
76
+
77
+ def execute_cli_with_attachments(namespace, command, args, payload)
78
+ BrpmAuto.log("blcli #{namespace} #{command} #{args.join(" ")}")
79
+
80
+ client = Savon.client("#{@url}#{CLI_WSDL}") do |wsdl, http|
81
+ http.auth.ssl.verify_mode = :none
82
+ end
83
+ client.http.read_timeout = HTTP_READ_TIMEOUT
84
+ response = client.request(:execute_command_using_attachments) do |soap|
85
+ soap.endpoint = "#{@url}#{CLI_SERVICE}"
86
+ soap.header = {"ins1:sessionId" => @session_id}
87
+ body_details = { :nameSpace => namespace, :commandName => command, :commandArguments => args }
88
+ body_details.merge!({:payload => payload}) if payload
89
+ soap.body = body_details
90
+ end
91
+ result = response.body[:execute_command_using_attachments_response][:return]
92
+ return validate_cli_result(result)
93
+ rescue Savon::Error => error
94
+ raise "Error while executing CLI command over SOAP protocol: #{error.to_s}"
95
+ rescue => exception
96
+ raise "Error processing CLI(#{namespace}:#{command}) result: #{exception.to_s}"
97
+ end
98
+
99
+ def execute_cli_with_param_list(namespace, command, args = [])
100
+ BrpmAuto.log("blcli #{namespace} #{command} #{args.join(" ")}")
101
+
102
+ client = Savon.client("#{@url}#{CLI_WSDL}") do |wsdl, http|
103
+ http.auth.ssl.verify_mode = :none
104
+ end
105
+ client.http.read_timeout = HTTP_READ_TIMEOUT
106
+ response = client.request(:execute_command_by_param_list) do |soap|
107
+ soap.endpoint = "#{@url}#{CLI_SERVICE}"
108
+ soap.header = {"ins1:sessionId" => @session_id}
109
+ soap.body = { :nameSpace => namespace, :commandName => command, :commandArguments => args }
110
+ end
111
+ result = response.body[:execute_command_by_param_list_response][:return]
112
+ return validate_cli_result(result)
113
+ rescue Savon::Error => error
114
+ raise "Error while executing CLI command over SOAP protocol: #{error.to_s}"
115
+ rescue Exception => exception
116
+ raise "Error processing CLI(#{namespace}:#{command}) results: #{exception.to_s}"
117
+ end
118
+ end
@@ -0,0 +1,34 @@
1
+ class BsaSoapClient < BsaSoapBase
2
+ def initialize(integration_settings = BrpmAuto.integration_settings)
3
+ @url = integration_settings.dns
4
+ @session_id = Login.new(integration_settings).login
5
+ end
6
+
7
+ def blpackage
8
+ @blpackage ||= BlPackage.new(@url, @session_id)
9
+ end
10
+
11
+ def job
12
+ @job ||= Job.new(@url, @session_id)
13
+ end
14
+
15
+ def job_run
16
+ @job_run ||= JobRun.new(@url, @session_id)
17
+ end
18
+
19
+ def deploy_job
20
+ @deploy_job ||= DeployJob.new(@url, @session_id)
21
+ end
22
+
23
+ def job_group
24
+ @job_group ||= JobGroup.new(@url, @session_id)
25
+ end
26
+
27
+ def depot_group
28
+ @depot_group ||= DepotGroup.new(@url, @session_id)
29
+ end
30
+
31
+ def utility
32
+ @utility ||= Utility.new(@url, @session_id)
33
+ end
34
+ end
@@ -0,0 +1,155 @@
1
+ class ComplianceJob < BsaSoapBase
2
+ def add_component_to_job_by_job_db_key(options = {})
3
+ validate_cli_options_hash([:compliance_key, :component_key], options)
4
+ db_key_result = execute_cli_with_param_list(self.class, "addComponentToJobByJobDBKey",
5
+ [
6
+ options[:compliance_key], # Handle to compliance Job
7
+ options[:component_key] # Handle to component to be added
8
+ ])
9
+ db_key = get_cli_return_value(db_key_result)
10
+ rescue => exception
11
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
12
+ end
13
+
14
+ def add_named_server_to_job_by_job_db_key(options = {})
15
+ validate_cli_options_hash([:db_key, :server_name], options)
16
+ db_key_result = execute_cli_with_param_list(self.class, "addNamedServerToJobByJobDBKey",
17
+ [
18
+ options[:db_key], # Handle to the Compliance Job
19
+ options[:server_name] # Name of the server to be added
20
+ ])
21
+ db_key = get_cli_return_value(db_key_result)
22
+ rescue => exception
23
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
24
+ end
25
+
26
+ def create_component_based_compliance_job(options = {})
27
+ validate_cli_options_hash([:job_name, :group_id, :template_key, :server_name], options)
28
+ db_key_result = execute_cli_with_param_list(self.class, "createComponentBasedComplianceJob",
29
+ [
30
+ options[:job_name], # Name of the job to be created
31
+ options[:group_id], # Id of the parent job group for the compliance job
32
+ options[:template_key], # Handle to template describing the assets to be included in compliance
33
+ options[:server_name], # Target server for compliance job
34
+ options[:component_index] || 0 # Index of component on target server (typically 0)
35
+ ])
36
+ db_key = get_cli_return_value(db_key_result)
37
+ rescue => exception
38
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
39
+ end
40
+
41
+ def create_remediation_job_from_compliance_result_by_rule(options = {})
42
+ validate_cli_options_hash(
43
+ [:remediation_name, :job_group_name, :depot_group_name, :comp_job_key, :comp_job_run_id, :template_group_name, :template_name, :rule_grp_name, :rule_name, :target_component],
44
+ options)
45
+ db_key_result = execute_cli_with_param_list(self.class, "createRemediationJobFromComplianceResultByRule",
46
+ [
47
+ options[:remediation_name], # Name of the package
48
+ options[:job_group_name], # Name of a group that should contain the new remediation job(s)
49
+ options[:depot_group_name], # Name of a group that should contain the new package(s)
50
+ options[:comp_job_key], # Handle to compliance job whose job run result you want to package
51
+ options[:comp_job_run_id], # ID of the compliance job run whose result you want to package
52
+ options[:template_group_name], # Group name of the template used in the compliance job run
53
+ options[:template_name], # Name of the template used in the compliance job run
54
+ options[:rule_grp_name], # Name of the template rule group used in the compliance job run
55
+ options[:rule_name], # Name of the template rule used in the compliance job run
56
+ options[:target_component], # Name of the target component
57
+ options[:use_component_device_for_targets] || true, # Use the device of a component as the target of the remediation (defualt = true) devices are targets
58
+ options[:keep_unique_package_props] || true # Indicates if the package should uniquely save each local property for the compliance rule packages that are used
59
+ ])
60
+ db_key = get_cli_return_value(db_key_result)
61
+ rescue => exception
62
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
63
+ end
64
+
65
+ def create_remediation_job_from_compliance_result_by_server(options = {})
66
+ validate_cli_options_hash(
67
+ [:remediation_name, :job_group_name, :depot_group_name, :comp_job_key, :comp_job_run_id, :target_server, :template_group_name, :template_name, :target_component, :rule_grp_name, :rule_name],
68
+ options)
69
+ db_key_result = execute_cli_with_param_list(self.class, "createRemediationJobFromComplianceResultByServer",
70
+ [
71
+ options[:remediation_name], # Name of the package
72
+ options[:job_group_name], # Name of a group that should contain the new remediation job(s)
73
+ options[:depot_group_name], # Name of a group that should contain the new package(s)
74
+ options[:comp_job_key], # Handle to compliance job whose job run result you want to package
75
+ options[:comp_job_run_id], # ID of the compliance job run whose result you want to package
76
+ options[:target_server], # Name of the target server
77
+ options[:template_group_name], # Group name of the template used in the compliance job run
78
+ options[:template_name], # Name of the template used in the compliance job run
79
+ options[:target_component], # Name of the target component
80
+ options[:rule_grp_name], # Name of the template rule group used in the compliance job run
81
+ options[:rule_name], # Name of the template rule used in the compliance job run
82
+ options[:use_component_device_for_targets] || true, # Use the device of a component as the target of the remediation (defualt = true) devices are targets
83
+ options[:keep_unique_package_props] || true # Indicates if the package should uniquely save each local property for the compliance rule packages that are used
84
+ ])
85
+ db_key = get_cli_return_value(db_key_result)
86
+ rescue => exception
87
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
88
+ end
89
+
90
+ def create_template_fltered_compliance_job(options = {})
91
+ validate_cli_options_hash([:job_name, :group_id, :template_key, :server_name], options)
92
+ db_key_result = execute_cli_with_param_list(self.class, "createTemplateFilteredComplianceJob",
93
+ [
94
+ options[:job_name], # Name of the job to be created
95
+ options[:group_id], # Id of the parent job group for the compliance job
96
+ options[:template_key], # Handle to the template describing the assets to be including in the compliance job
97
+ options[:server_name] # Target server for the compliance job
98
+ ])
99
+ db_key = get_cli_return_value(db_key_result)
100
+ rescue => exception
101
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
102
+ end
103
+
104
+ def execute_job_and_wait(options = {})
105
+ validate_cli_options_hash([:job_key], options)
106
+ job_key_result = execute_cli_with_param_list(self.class, "executeJobAndWait",
107
+ [
108
+ options[:job_key] # Handle to the compliance job to be executed
109
+ ])
110
+ job_key = get_cli_return_value(job_key_result)
111
+ rescue => exception
112
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
113
+ end
114
+
115
+ def get_dbkey_by_group_and_name(options = {})
116
+ validate_cli_options_hash([:group_name, :job_name], options)
117
+ db_key_result = execute_cli_with_param_list(self.class, "getDBKeyByGroupAndName",
118
+ [
119
+ options[:group_name], # Fully qualified path to the job group containing the job
120
+ options[:job_name] # Name of the job
121
+ ])
122
+ db_key = get_cli_return_value(db_key_result)
123
+ rescue => exception
124
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
125
+ end
126
+
127
+ def set_auto_remediation(options = {})
128
+ validate_cli_options_hash([:job_key, :job_name, :depot_group, :job_group], options)
129
+ db_key_result = execute_cli_with_param_list(self.class, "setAutoRemediation",
130
+ [
131
+ options[:job_key], # Handle to compliance job
132
+ options[:job_name], # Name for auto-remediation job
133
+ options[:depot_group], # Name of the depot group to store files in
134
+ options[:job_group], # Name of the job group to store the remediation job in
135
+ options[:is_auto_remediate] || true, # Auto-remediation state for the job - true = set
136
+ options[:use_component_device_for_targets] || true, # Use the device of a component as the target of the remediation (defualt = true) devices are targets
137
+ options[:keep_unique_package_props] || true # Indicates if the package should uniquely save each local property for the compliance rule packages that are used
138
+ ])
139
+ db_key = get_cli_return_value(db_key_result)
140
+ rescue => exception
141
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
142
+ end
143
+
144
+ def set_description(options = {})
145
+ validate_cli_options_hash([:job_key, :desc], options)
146
+ db_key_result = execute_cli_with_param_list(self.class, "setDescription",
147
+ [
148
+ options[:job_key], # handle to compliance job
149
+ options[:desc] # description of job
150
+ ])
151
+ db_key = get_cli_return_value(db_key_result)
152
+ rescue => exception
153
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
154
+ end
155
+ end
@@ -0,0 +1,48 @@
1
+ # very basic support right now
2
+ class DeployJob < BsaSoapBase
3
+ def create_deploy_job(options = {})
4
+ validate_cli_options_hash([:job_name, :group_id, :package_db_key, :server_name], options)
5
+ db_key_result = execute_cli_with_param_list(self.class, "createDeployJob",
6
+ [
7
+ options[:job_name],
8
+ options[:group_id],
9
+ options[:package_db_key],
10
+ options[:server_name],
11
+ true, #isSimulateEnabled
12
+ true, #isCommitEnabled
13
+ false, #isStagedIndirect
14
+ ])
15
+ db_key = get_cli_return_value(db_key_result)
16
+ rescue => exception
17
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
18
+ end
19
+
20
+ def get_dbkey_by_group_and_name(options = {})
21
+ validate_cli_options_hash([:group_name, :job_name], options)
22
+ db_key_result = execute_cli_with_param_list(self.class, "getDBKeyByGroupAndName",
23
+ [
24
+ options[:group_name], # Fully qualified path to the job group containing the job
25
+ options[:job_name] # Name of the job
26
+ ])
27
+ db_key = get_cli_return_value(db_key_result)
28
+ rescue => exception
29
+ raise "Exception executing #{self.class} function: #{exception.to_s}"
30
+ end
31
+
32
+ def set_phase_schedule_by_dbkey(options = {})
33
+ validate_cli_options_hash([:job_run_key], options)
34
+ void_result = execute_cli_with_param_list(self.class, "setAdvanceDeployJobPhaseScheduleByDBKey",
35
+ [
36
+ options[:job_run_key],
37
+ options[:simulate_type],
38
+ options[:simulate_date],
39
+ options[:stage_type],
40
+ options[:stage_date],
41
+ options[:commit_type],
42
+ options[:commit_date],
43
+ ])
44
+ void_value = get_cli_return_value(void_result)
45
+ rescue => exception
46
+ raise "#{self.class} Exception: #{exception.to_s}"
47
+ end
48
+ end