oci-logging-analytics-kubernetes-discovery 1.0.2 → 1.1.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/.gitignore +2 -1
- data/bin/oci-loganalytics-kubernetes-discovery +102 -25
- data/lib/config/oci_client_retry_config.rb +11 -8
- data/lib/discover/infrastructure.rb +81 -29
- data/lib/discover/object.rb +19 -4
- data/lib/dto/infra/load_balancer_payload.rb +32 -0
- data/lib/dto/infra/node_pool_payload.rb +28 -0
- data/lib/dto/infra/{node_pool_entity_payload.rb → resource_payload.rb} +6 -6
- data/lib/dto/infra/subnet_payload.rb +34 -0
- data/lib/dto/infra_objects_payload.rb +3 -3
- data/lib/dto/kubernetes_objects_payload.rb +19 -15
- data/lib/dto/state.rb +7 -3
- data/lib/enum/auth_type_enum.rb +1 -0
- data/lib/enum/infrastructure_resource_discovery.rb +1 -0
- data/lib/enum/object_client_mapping_enum.rb +1 -1
- data/lib/enum/stack_job_lifecycle_state_enum.rb +14 -0
- data/lib/enum/stack_job_operation_enum.rb +10 -0
- data/lib/infra_resources.rb +142 -41
- data/lib/objects_resources.rb +16 -6
- data/lib/oci_loganalytics_resources_discovery.rb +104 -77
- data/lib/util/helper.rb +15 -0
- data/lib/util/kube_client.rb +1 -0
- data/lib/util/kubectl_ops.rb +1 -1
- data/lib/util/log_analytics.rb +2 -2
- data/lib/util/oci_clients.rb +222 -103
- data/lib/util/service_logs.rb +559 -0
- data/lib/util/state_manager.rb +12 -2
- data/lib/util/string_utils.rb +48 -0
- data/lib/version.rb +1 -1
- data/oci-logging-analytics-kubernetes-discovery.gemspec +1 -1
- metadata +13 -10
- data/lib/dto/infra/cluster_entity_payload.rb +0 -22
- data/lib/dto/infra/load_balancers_entity_payload.rb +0 -22
- data/lib/dto/infra/subnet_entity_payload.rb +0 -22
- data/lib/dto/infra/vcn_entity_payload.rb +0 -22
@@ -16,6 +16,7 @@ require_relative './util/kube_client'
|
|
16
16
|
require_relative './util/oci_clients'
|
17
17
|
require_relative './util/log_analytics'
|
18
18
|
require_relative './util/state_manager'
|
19
|
+
require_relative './util/service_logs'
|
19
20
|
|
20
21
|
# DTO
|
21
22
|
require_relative './dto/payload/log_events'
|
@@ -39,7 +40,7 @@ module OciLogAnalyticsResourcesDiscovery
|
|
39
40
|
module_function
|
40
41
|
|
41
42
|
attr_accessor :cluster_config_hash, :auth_config_hash, :kube_config_hash, :app_config_hash,
|
42
|
-
:auth_object, :kube_clients, :oci_clients, :snapshot_id
|
43
|
+
:auth_object, :kube_clients, :oci_clients, :oci_region, :oci_domain, :snapshot_id
|
43
44
|
|
44
45
|
@@oci_la_log_source_name = 'Kubernetes Objects Discovery Payload Logs'
|
45
46
|
@@oci_la_log_path = 'UNDEFINED'
|
@@ -49,58 +50,78 @@ module OciLogAnalyticsResourcesDiscovery
|
|
49
50
|
@auth_config_hash = auth_config_hash
|
50
51
|
@kube_config_hash = kube_config_hash
|
51
52
|
@app_config_hash = app_config_hash
|
53
|
+
end
|
52
54
|
|
53
|
-
|
55
|
+
def initiate_discovery
|
56
|
+
Util::OCIClients.initialize(@auth_config_hash)
|
54
57
|
|
55
|
-
|
58
|
+
@auth_object = Util::OCIClients.get_auth_config_object
|
59
|
+
@oci_clients = Util::OCIClients.get_clients
|
60
|
+
@oci_region = Util::OCIClients.get_region
|
61
|
+
@oci_domain = Util::OCIClients.get_domain
|
56
62
|
|
57
|
-
|
58
|
-
get_oci_clients(options)
|
63
|
+
@kube_clients = Util::KubeClient.create_clients(@kube_config_hash)
|
59
64
|
|
60
|
-
|
61
|
-
@snapshot_id = Time.now.to_i
|
62
|
-
get_kube_clients
|
63
|
-
Util::StateManager.init(@cluster_config_hash[:kubernetes_resourcename_prefix], @cluster_config_hash[:kubernetes_cluster_namespace])
|
64
|
-
Util::KubectlOps.set_chunk_limit @app_config_hash[:chunk_limit]
|
65
|
-
logger.debug("Chunk limit set to - #{@app_config_hash[:chunk_limit]}")
|
66
|
-
end
|
67
|
-
end
|
65
|
+
Util::StateManager.init(@cluster_config_hash[:kubernetes_resourcename_prefix], @cluster_config_hash[:kubernetes_cluster_namespace])
|
68
66
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
infra_objects_payload = get_infra_resources_payload
|
73
|
-
rescue StandardError => e
|
74
|
-
logger.error("Error occurred while fetching infrastructure resources. Error: #{e}")
|
75
|
-
raise StandardError, 'Error occurred while fetching infrastructure resources.'
|
76
|
-
end
|
67
|
+
# Collect infrastructure discovery data
|
68
|
+
infra_objects_payload = nil
|
69
|
+
infra_discovery_failed = false
|
77
70
|
|
78
|
-
logger.info('
|
79
|
-
logger.trace("Infrastructure discovery payload: \n#{Yajl.dump(infra_objects_payload.to_hash)}")
|
71
|
+
logger.info('Initiating Kubernetes Objects discovery.')
|
80
72
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
# TODO: Upload implemetation pending.
|
86
|
-
else
|
87
|
-
logger.warn('No infrastructure objects discovered.')
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
73
|
+
# Collect platform discovery data
|
74
|
+
@snapshot_id = Time.now.to_i
|
75
|
+
Util::KubectlOps.set_chunk_limit @app_config_hash[:chunk_limit]
|
76
|
+
logger.debug("Chunk limit set to - #{@app_config_hash[:chunk_limit]}")
|
91
77
|
|
92
|
-
def initiate_object_discovery
|
93
78
|
kubernetes_objects_payload = get_objects_resources_payload
|
79
|
+
|
94
80
|
if @app_config_hash[:collect_warning_events_only]
|
95
81
|
logger.info('Only Warning event logs will be collected as the following flag is set: --collect_warning_events_only')
|
96
82
|
end
|
83
|
+
|
97
84
|
kubernetes_objects_payload = filter_event_logs(kubernetes_objects_payload,
|
98
85
|
@app_config_hash[:collect_warning_events_only])
|
99
86
|
|
100
87
|
logger.info('Kubernetes objects discovery payload created.')
|
101
|
-
logger.trace("Object Discovery Payload: \n#{Yajl.dump(kubernetes_objects_payload[:processed_objects].to_hash)}")
|
102
88
|
logger.trace("Object Log Collection Payload: \n#{Yajl.dump(kubernetes_objects_payload[:raw_response].to_hash)}")
|
103
89
|
|
90
|
+
if @cluster_config_hash[:enable_infra_discovery]
|
91
|
+
logger.info('Initiating kubernetes infrastructure discovery.')
|
92
|
+
begin
|
93
|
+
lb_ip_array = parse_lb_ips(kubernetes_objects_payload)
|
94
|
+
logger.info("Discovered Load Balancer IPs: #{lb_ip_array}")
|
95
|
+
infra_objects_payload = InfraResources.get_infra_resources(
|
96
|
+
@app_config_hash,
|
97
|
+
@cluster_config_hash,
|
98
|
+
@cluster_config_hash[:kubernetes_cluster_id],
|
99
|
+
lb_ip_array
|
100
|
+
)
|
101
|
+
logger.trace("Infrastructure discovery payload: \n#{Yajl.dump(infra_objects_payload.to_hash)}")
|
102
|
+
logger.info('Infrastructure discovery payload created.')
|
103
|
+
rescue StandardError => e
|
104
|
+
# Not raising an error as platform discovery still needs to continue.
|
105
|
+
infra_discovery_failed = true
|
106
|
+
logger.error("Error occurred while fetching infrastructure resources. Error: #{e}")
|
107
|
+
logger.info('Proceeding with object discovery.')
|
108
|
+
end
|
109
|
+
else
|
110
|
+
logger.info('--kubernetes_cluster_id not provided. Infrastructure discovery skipped.') # TODO: should be Warn ?
|
111
|
+
end
|
112
|
+
|
113
|
+
# Combine discovery and infrastructure data
|
114
|
+
processed_objects = kubernetes_objects_payload[:processed_objects]
|
115
|
+
combined_data = Dto::KubernetesObjectsPayLoad.new(
|
116
|
+
processed_objects[:cluster], processed_objects[:nodes], processed_objects[:pods], processed_objects[:services], processed_objects[:endpoint_slices],
|
117
|
+
processed_objects[:deployments], processed_objects[:replica_sets], processed_objects[:daemon_sets], processed_objects[:cron_jobs],
|
118
|
+
processed_objects[:jobs], processed_objects[:stateful_sets], processed_objects[:events], processed_objects[:namespaces], infra_objects_payload
|
119
|
+
)
|
120
|
+
|
121
|
+
logger.info('Combined discovery payload created.')
|
122
|
+
logger.trace("Combined discovery payload: \n#{Yajl.dump(combined_data.to_hash)}")
|
123
|
+
|
124
|
+
# Send collected data
|
104
125
|
if @app_config_hash[:skip_upload]
|
105
126
|
logger.warn('--skip_upload Flag is set: Skipping payload upload to OCI logging analytics.')
|
106
127
|
else
|
@@ -118,7 +139,8 @@ module OciLogAnalyticsResourcesDiscovery
|
|
118
139
|
upload_data_via_discovery_api(zip_object_log_payload, object_logs_opts) unless zip_object_log_payload.nil?
|
119
140
|
logger.info('Successfully uploaded object logs to OCI')
|
120
141
|
|
121
|
-
# Update the Events tracker config map only after successful objects logs upload
|
142
|
+
# DEV NOTE: Update the Events tracker config map only after successful objects logs upload
|
143
|
+
# Carefully check how last_timestamp update is managed if you wish to move the below code
|
122
144
|
Util::StateManager.update_state_configmap
|
123
145
|
rescue StandardError
|
124
146
|
logger.error('Error occurred while uploading object logs to OCI')
|
@@ -128,34 +150,54 @@ module OciLogAnalyticsResourcesDiscovery
|
|
128
150
|
unless @cluster_config_hash[:oci_la_cluster_entity_id].nil?
|
129
151
|
begin
|
130
152
|
# Upload object discovery payload with relevant header parameters
|
131
|
-
logger.info('Uploading
|
153
|
+
logger.info('Uploading Discovery Payload to OCI')
|
132
154
|
object_discovery_opts = {
|
133
155
|
payload_type: 'JSON',
|
134
156
|
discovery_data_type: 'K8S_OBJECTS',
|
135
157
|
opc_meta_properties: "cluster-entity-id:#{@cluster_config_hash[:oci_la_cluster_entity_id]};sub-type:discovery_payload;cluster-id:#{@cluster_config_hash[:kubernetes_cluster_id]};cluster-name:#{@cluster_config_hash[:kubernetes_cluster_name]}"
|
136
158
|
}
|
137
|
-
json_object_discovery_payload = Yajl.dump(
|
159
|
+
json_object_discovery_payload = Yajl.dump(combined_data.to_hash)
|
138
160
|
upload_data_via_discovery_api(json_object_discovery_payload, object_discovery_opts)
|
139
|
-
logger.info('Successfully uploaded
|
161
|
+
logger.info('Successfully uploaded discovery payload to OCI')
|
140
162
|
rescue StandardError
|
141
|
-
logger.error('Error occurred while uploading
|
163
|
+
logger.error('Error occurred while uploading discovery payload to OCI')
|
142
164
|
upload_failure = true
|
143
165
|
end
|
144
166
|
end
|
145
167
|
|
146
|
-
raise StandardError, 'Error
|
168
|
+
raise StandardError, 'Error uploading payloads to OCI' if upload_failure
|
147
169
|
end
|
148
|
-
end
|
149
170
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
171
|
+
# Execute Resource Manager Stack
|
172
|
+
if !infra_discovery_failed && @app_config_hash[:enable_service_log]
|
173
|
+
logger.info('Initiating service logs collection.')
|
174
|
+
log_analytics_entity_details = nil
|
175
|
+
begin
|
176
|
+
log_analytics_entity_details = Util::ServiceLogs.fetch_log_analytics_entity_details(
|
177
|
+
@cluster_config_hash[:oci_la_namespace],
|
178
|
+
@cluster_config_hash[:oci_la_cluster_entity_id]
|
179
|
+
)
|
180
|
+
rescue StandardError => e
|
181
|
+
logger.error('Error fetching log analytics entity details.')
|
182
|
+
end
|
183
|
+
unless log_analytics_entity_details.nil?
|
184
|
+
begin
|
185
|
+
logger.info('Invoking resource manager stack for service log creation')
|
186
|
+
Util::ServiceLogs.invoke_resource_manager_stack(infra_objects_payload,
|
187
|
+
@app_config_hash,
|
188
|
+
@cluster_config_hash[:oci_la_log_group_id],
|
189
|
+
log_analytics_entity_details.compartment_id,
|
190
|
+
@oci_region,
|
191
|
+
@oci_domain)
|
192
|
+
rescue StandardError => e
|
193
|
+
logger.error('Error invoking/updating service logs collection')
|
194
|
+
raise e
|
195
|
+
end
|
196
|
+
end
|
197
|
+
else
|
198
|
+
log_msg = infra_discovery_failed ? 'No infrastructure objects discovered' : 'Flag --enable_service_log not provided'
|
199
|
+
logger.info("#{log_msg}. Stack operations skipped")
|
156
200
|
end
|
157
|
-
@auth_object = Util::OCIClients.get_auth_config_object
|
158
|
-
logger.debug('Successfully loaded the OCI auth config.')
|
159
201
|
end
|
160
202
|
|
161
203
|
def get_kube_clients
|
@@ -165,33 +207,9 @@ module OciLogAnalyticsResourcesDiscovery
|
|
165
207
|
logger.error("Error occurred in creating kubeclients - #{e}")
|
166
208
|
raise e
|
167
209
|
end
|
168
|
-
@kube_clients =
|
169
|
-
logger.debug('
|
170
|
-
|
171
|
-
|
172
|
-
def get_oci_clients(options)
|
173
|
-
begin
|
174
|
-
Util::OCIClients.create_clients(@auth_object, options)
|
175
|
-
rescue StandardError => e
|
176
|
-
logger.error("Error occurred in creating OCI clients - #{e}")
|
177
|
-
raise e
|
178
|
-
end
|
179
|
-
@oci_clients = Util::OCIClients.get_clients
|
180
|
-
logger.debug('OCI clients created successfully.')
|
181
|
-
end
|
182
|
-
|
183
|
-
def get_infra_resources_payload
|
184
|
-
logger.debug('Discovering Infrastructure Resources')
|
185
|
-
infra_resources_payload = nil
|
186
|
-
|
187
|
-
unless @auth_object.nil?
|
188
|
-
begin
|
189
|
-
infra_resources_payload = InfraResources.get_infra_resources(@auth_object, @cluster_config_hash[:oci_la_cluster_entity_id])
|
190
|
-
rescue StandardError => e
|
191
|
-
logger.error("Error in getting infrastructure resources: #{e}")
|
192
|
-
end
|
193
|
-
end
|
194
|
-
infra_resources_payload
|
210
|
+
@kube_clients =
|
211
|
+
logger.debug('Kube client created successfully.')
|
212
|
+
Util::KubeClient.get_clients
|
195
213
|
end
|
196
214
|
|
197
215
|
def get_objects_resources_payload
|
@@ -205,6 +223,15 @@ module OciLogAnalyticsResourcesDiscovery
|
|
205
223
|
)
|
206
224
|
end
|
207
225
|
|
226
|
+
def parse_lb_ips(kubernetes_objects_payload)
|
227
|
+
ip_array = []
|
228
|
+
lbs = kubernetes_objects_payload[:processed_objects][:services].select { |service| service[:serviceType] == "LoadBalancer" }
|
229
|
+
lbs.each do |lb|
|
230
|
+
ip_array.append lb.loadBalancerIP unless lb.loadBalancerIP.nil?
|
231
|
+
end
|
232
|
+
ip_array
|
233
|
+
end
|
234
|
+
|
208
235
|
def filter_event_logs(kubernetes_objects_payload, collect_warning_events_only)
|
209
236
|
cluster_events_processed_time = Util::StateManager.state.last_timestamp
|
210
237
|
new_processed_time = cluster_events_processed_time
|
data/lib/util/helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Util
|
2
|
+
module Helper
|
3
|
+
module_function
|
4
|
+
# Function to check if a value is defined in the enum
|
5
|
+
def enum_value_defined?(enum_module, value)
|
6
|
+
enum_module.constants(false).any? { |const| enum_module.const_get(const) == value }
|
7
|
+
end
|
8
|
+
|
9
|
+
# Function to get enum values as list
|
10
|
+
def enum_values(enum_module)
|
11
|
+
enum_module.constants(false).map { |const| enum_module.const_get(const) }
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
data/lib/util/kube_client.rb
CHANGED
data/lib/util/kubectl_ops.rb
CHANGED
@@ -48,7 +48,7 @@ module Util
|
|
48
48
|
case method
|
49
49
|
when :get_objects
|
50
50
|
if client.nil?
|
51
|
-
client = Util::KubeClient.get_clients[Enum::
|
51
|
+
client = Util::KubeClient.get_clients[Enum::ObjectClientMappingEnum.const_get(object_type.upcase.to_s)]
|
52
52
|
end
|
53
53
|
logger.debug("Fetching '#{object_type}' details from all namespaces")
|
54
54
|
method_verb = 'GET'
|
data/lib/util/log_analytics.rb
CHANGED
@@ -33,7 +33,7 @@ module Util
|
|
33
33
|
upload_discovery_data_details = payload,
|
34
34
|
opts)
|
35
35
|
rescue StandardError => e
|
36
|
-
logger.error("Error while uploading payload to 'Log Analytics': #{e}")
|
36
|
+
logger.error("Error while uploading payload to 'Log Analytics'. Error: #{e}")
|
37
37
|
raise StandardError, "Unable to upload data to 'Log Analytics' client."
|
38
38
|
end
|
39
39
|
response
|
@@ -56,7 +56,7 @@ module Util
|
|
56
56
|
region = signer.region
|
57
57
|
else
|
58
58
|
logger.warn("Unknown auth_type provided for Discovery API (raw request): #{auth_object[:auth_type]}")
|
59
|
-
raise StandardError 'Unknown auth_type for Discovery API (raw request)'
|
59
|
+
raise StandardError, 'Unknown auth_type for Discovery API (raw request)'
|
60
60
|
end
|
61
61
|
|
62
62
|
# Construct URL protocol, subdomain, domain and port
|