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
@@ -31,9 +31,9 @@ module Dto
|
|
31
31
|
{
|
32
32
|
cluster: @cluster.to_hash,
|
33
33
|
vcn: @vcn.to_hash,
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
subnets: get_hash(@subnet, SUBNET.to_s),
|
35
|
+
loadbalancers: get_hash(@load_balancer, LOAD_BALANCER.to_s),
|
36
|
+
nodepools: get_hash(@node_pools, NODE_POOLS.to_s)
|
37
37
|
}.compact
|
38
38
|
end
|
39
39
|
end
|
@@ -8,24 +8,27 @@ module Dto
|
|
8
8
|
include Enum::KubernetesObjectsEnum
|
9
9
|
extend Util::Logging
|
10
10
|
|
11
|
-
attr_accessor :cluster, :nodes, :pods, :services, :
|
12
|
-
:
|
11
|
+
attr_accessor :cluster, :nodes, :pods, :services, :endpointslices, :deployments,
|
12
|
+
:replicasets, :daemonsets, :cronjobs, :jobs, :statefulsets, :events, :namespaces,
|
13
|
+
:infra
|
13
14
|
|
14
|
-
def initialize(cluster, nodes, pods, services,
|
15
|
-
|
15
|
+
def initialize(cluster, nodes, pods, services, endpointslices, deployments,
|
16
|
+
replicasets, daemonsets, cronjobs, jobs, statefulsets, events, namespaces,
|
17
|
+
infra)
|
16
18
|
@cluster = cluster
|
17
19
|
@nodes = nodes
|
18
20
|
@pods = pods
|
19
21
|
@services = services
|
20
|
-
@
|
22
|
+
@endpointslices = endpointslices
|
21
23
|
@deployments = deployments
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
24
|
+
@replicasets = replicasets
|
25
|
+
@daemonsets = daemonsets
|
26
|
+
@cronjobs = cronjobs
|
25
27
|
@jobs = jobs
|
26
|
-
@
|
28
|
+
@statefulsets = statefulsets
|
27
29
|
@events = events
|
28
30
|
@namespaces = namespaces
|
31
|
+
@infra = infra
|
29
32
|
end
|
30
33
|
|
31
34
|
def get_hash(obj, obj_name)
|
@@ -43,15 +46,16 @@ module Dto
|
|
43
46
|
nodes: get_hash(@nodes, NODES.to_s),
|
44
47
|
pods: get_hash(@pods, PODS.to_s),
|
45
48
|
services: get_hash(@services, SERVICES.to_s),
|
46
|
-
endpointslices: get_hash(@
|
49
|
+
endpointslices: get_hash(@endpointslices, ENDPOINT_SLICES.to_s),
|
47
50
|
deployments: get_hash(@deployments, DEPLOYMENTS.to_s),
|
48
|
-
replicasets: get_hash(@
|
49
|
-
daemonsets: get_hash(@
|
50
|
-
cronjobs: get_hash(@
|
51
|
+
replicasets: get_hash(@replicasets, REPLICA_SETS.to_s),
|
52
|
+
daemonsets: get_hash(@daemonsets, DAEMON_SETS.to_s),
|
53
|
+
cronjobs: get_hash(@cronjobs, CRON_JOBS.to_s),
|
51
54
|
jobs: get_hash(@jobs, JOBS.to_s),
|
52
|
-
statefulsets: get_hash(@
|
55
|
+
statefulsets: get_hash(@statefulsets, STATEFUL_SETS.to_s),
|
53
56
|
events: get_hash(@events, EVENTS.to_s),
|
54
|
-
namespaces: get_hash(@namespaces, NAMESPACES.to_s)
|
57
|
+
namespaces: get_hash(@namespaces, NAMESPACES.to_s),
|
58
|
+
infra: @infra.nil? ? nil : @infra.to_hash
|
55
59
|
}.compact
|
56
60
|
end
|
57
61
|
end
|
data/lib/dto/state.rb
CHANGED
@@ -3,16 +3,20 @@
|
|
3
3
|
|
4
4
|
module Dto
|
5
5
|
class State
|
6
|
-
attr_accessor :last_timestamp
|
6
|
+
attr_accessor :last_timestamp, :retry_eligible_resources, :svc_log_stack_id
|
7
7
|
|
8
|
-
def initialize(last_timestamp = nil)
|
8
|
+
def initialize(last_timestamp = nil, retry_eligible_resources = nil, svc_log_stack_id = nil)
|
9
9
|
@last_timestamp = last_timestamp unless last_timestamp.nil?
|
10
|
+
@retry_eligible_resources = retry_eligible_resources unless retry_eligible_resources.nil?
|
11
|
+
@svc_log_stack_id = svc_log_stack_id unless svc_log_stack_id.nil?
|
10
12
|
end
|
11
13
|
|
12
14
|
# make sure all values are strings
|
13
15
|
def to_hash
|
14
16
|
{
|
15
|
-
last_timestamp: @last_timestamp.to_s
|
17
|
+
last_timestamp: @last_timestamp.to_s,
|
18
|
+
retry_eligible_resources: @retry_eligible_resources.to_s,
|
19
|
+
svc_log_stack_id: @svc_log_stack_id.to_s
|
16
20
|
}.compact
|
17
21
|
end
|
18
22
|
end
|
data/lib/enum/auth_type_enum.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
## Copyright (c) 2024 Oracle and/or its affiliates.
|
2
|
+
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
3
|
+
|
4
|
+
module Enum
|
5
|
+
module StackJobLifecycleStateEnum
|
6
|
+
# Documentation: https://docs.oracle.com/en-us/iaas/Content/ResourceManager/Tasks/jobs.htm
|
7
|
+
ACCEPTED = 'ACCEPTED'.freeze
|
8
|
+
IN_PROGRESS = 'IN_PROGRESS'.freeze
|
9
|
+
FAILED = 'FAILED'.freeze
|
10
|
+
SUCCEEDED = 'SUCCEEDED'.freeze
|
11
|
+
CANCELING = 'CANCELING'.freeze
|
12
|
+
CANCELED = 'CANCELED'.freeze
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
## Copyright (c) 2024 Oracle and/or its affiliates.
|
2
|
+
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
3
|
+
|
4
|
+
module Enum
|
5
|
+
module StackJobOperationEnum
|
6
|
+
APPLY = 'APPLY'.freeze
|
7
|
+
PLAN = 'PLAN'.freeze
|
8
|
+
DESTROY = 'DESTROY'.freeze
|
9
|
+
end
|
10
|
+
end
|
data/lib/infra_resources.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
## Copyright (c) 2024 Oracle and/or its affiliates.
|
2
2
|
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
3
3
|
|
4
|
+
require 'set'
|
5
|
+
|
4
6
|
# Infra
|
5
7
|
require_relative './discover/infrastructure'
|
6
8
|
|
@@ -8,11 +10,10 @@ require_relative './discover/infrastructure'
|
|
8
10
|
require_relative './dto/infra_objects_payload'
|
9
11
|
|
10
12
|
# DTOs
|
11
|
-
require_relative './dto/infra/
|
12
|
-
require_relative './dto/infra/
|
13
|
-
require_relative './dto/infra/
|
14
|
-
require_relative './dto/infra/
|
15
|
-
require_relative './dto/infra/node_pool_entity_payload'
|
13
|
+
require_relative './dto/infra/resource_payload'
|
14
|
+
require_relative './dto/infra/subnet_payload'
|
15
|
+
require_relative './dto/infra/node_pool_payload'
|
16
|
+
require_relative './dto/infra/load_balancer_payload'
|
16
17
|
|
17
18
|
# Util
|
18
19
|
require_relative './util/logging'
|
@@ -23,66 +24,166 @@ module InfraResources
|
|
23
24
|
|
24
25
|
module_function
|
25
26
|
|
26
|
-
|
27
|
+
IP_Address = Struct.new(:ip, :isPublic)
|
28
|
+
Nodes = Struct.new(:id, :name, :subnetId, :privateIp, :publicIp, :lifecycleState)
|
29
|
+
|
30
|
+
def get_infra_resources(app_config, cluster_config, cluster_id, lb_ip_array)
|
31
|
+
|
27
32
|
# Fetch cluster details using cluster OCID provided as argument during program run
|
28
33
|
logger.debug('Fetching cluster details.')
|
29
|
-
ce_response = Discover::Infrastructure.fetch_cluster_details(
|
30
|
-
|
34
|
+
ce_response = Discover::Infrastructure.fetch_cluster_details(cluster_id)
|
35
|
+
cluster_details = Dto::Infra::ResourcePayload.new(ce_response.name, ce_response.id, ce_response.compartment_id)
|
31
36
|
|
32
37
|
# Fetch VCN associated with cluster
|
33
38
|
logger.debug('Fetching virtual cloud network details.')
|
34
|
-
vcn_response = Discover::Infrastructure.fetch_vcn_response(
|
35
|
-
|
39
|
+
vcn_response = Discover::Infrastructure.fetch_vcn_response(ce_response.vcn_id)
|
40
|
+
vcn_details = Dto::Infra::ResourcePayload.new(vcn_response.display_name, vcn_response.id, vcn_response.compartment_id)
|
36
41
|
|
37
|
-
#
|
38
|
-
logger.debug('Fetching
|
39
|
-
subnet_response = Discover::Infrastructure.fetch_subnet_list_response(auth_object, ce_response.compartment_id, vcn_response.id)
|
42
|
+
# Use resource search query to fetch load balancers associated with cluster OCID
|
43
|
+
logger.debug('Fetching load balancers associated with cluster.')
|
40
44
|
|
41
|
-
|
42
|
-
subnet_entity_payload = []
|
43
|
-
subnet_response.each do |subnet|
|
44
|
-
next if subnet.nil?
|
45
|
+
load_balancer_details = []
|
45
46
|
|
46
|
-
|
47
|
-
|
47
|
+
lb_ip_array.each do |ip|
|
48
|
+
structured_query = "query loadbalancer resources matching '#{ip}'"
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
50
|
+
resource_query_search_response = Discover::Infrastructure.search_with_structured_query(structured_query)
|
51
|
+
|
52
|
+
# TODO: We only expect one LB per IP address, remove looping over result ?
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
54
|
+
# Load Balancer Lifecycle State: CREATING, ACTIVE, DELETING
|
55
|
+
resource_query_search_response.items.each do |item|
|
56
|
+
lb_response = Discover::Infrastructure.fetch_load_balancer_details(item.identifier)
|
57
|
+
next if lb_response[:data].nil?
|
58
|
+
lb_ip_addresses = []
|
56
59
|
|
57
|
-
|
60
|
+
lb_response[:data].ip_addresses.each do |item|
|
61
|
+
lb_ip_addresses.push(IP_Address.new(item.ip_address, item.is_public))
|
62
|
+
end
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
+
subnet_ids = lb_response[:data].subnet_ids.nil? ? [] : lb_response[:data].subnet_ids
|
65
|
+
|
66
|
+
load_balancer_details.push(Dto::Infra::LoadBalancerPayload.new(lb_response[:data].display_name,
|
67
|
+
lb_response[:data].id,
|
68
|
+
lb_response[:data].compartment_id,
|
69
|
+
lb_response[:data].is_private,
|
70
|
+
lb_ip_addresses,
|
71
|
+
lb_response[:data].lifecycle_state,
|
72
|
+
subnet_ids))
|
73
|
+
|
74
|
+
logger.debug("LB detected : #{lb_response}")
|
64
75
|
end
|
65
76
|
end
|
66
77
|
|
78
|
+
logger.info("Discovered load balancer count: #{load_balancer_details.length}")
|
79
|
+
|
67
80
|
# Iterate through all the compartments (starting from root tenancy level) and fetch node pools
|
68
81
|
# associated with the cluster OCID
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
82
|
+
node_pool_details = []
|
83
|
+
node_pool_subnet_ids = []
|
84
|
+
worker_node_subnet_ids = []
|
85
|
+
|
86
|
+
logger.debug('Fetching node pools associated with cluster.')
|
87
|
+
|
88
|
+
node_pool_compartment_id = nil
|
89
|
+
scoped_at_tenancy = false
|
90
|
+
if app_config[:probe_all_compartments]
|
91
|
+
# Tenancy OCID is compulsory input if probe_all_compartments flag is set
|
92
|
+
logger.info('Node pool discovery scope set at tenancy level.')
|
93
|
+
|
94
|
+
node_pool_compartment_id = app_config[:tenancy_ocid]
|
95
|
+
scoped_at_tenancy = true
|
96
|
+
else
|
97
|
+
logger.info('Node pool discovery scoped to cluster compartment.')
|
98
|
+
node_pool_compartment_id = ce_response.compartment_id
|
99
|
+
end
|
100
|
+
|
101
|
+
begin
|
102
|
+
compartment_list_response = Discover::Infrastructure.fetch_compartment_list(node_pool_compartment_id, scoped_at_tenancy)
|
103
|
+
rescue StandardError => e
|
104
|
+
logger.error("Error while fetching compartment list. Error: [#{e}]")
|
105
|
+
raise StandardError, 'Error while fetching compartment list.'
|
106
|
+
end
|
107
|
+
|
108
|
+
compartment_list = []
|
109
|
+
compartment_list_response[:data]&.each do |compartment|
|
110
|
+
compartment_list.push(compartment.id)
|
111
|
+
end
|
112
|
+
|
113
|
+
if scoped_at_tenancy
|
114
|
+
compartment_list.push(app_config[:tenancy_ocid])
|
115
|
+
else
|
116
|
+
compartment_list.push(ce_response.compartment_id)
|
117
|
+
end
|
118
|
+
|
119
|
+
compartment_list.each do |compartment|
|
120
|
+
|
121
|
+
node_pool_list_response = Discover::Infrastructure.fetch_node_pool_lists(compartment, ce_response.id)
|
122
|
+
|
123
|
+
node_pool_list_response.each do |node_pool|
|
124
|
+
|
125
|
+
subnet_ids = node_pool.subnet_ids.nil? ? [] : node_pool.subnet_ids
|
126
|
+
|
127
|
+
subnet_ids.each do |node_pool_subnet|
|
128
|
+
node_pool_subnet_ids.push(node_pool_subnet)
|
129
|
+
end
|
130
|
+
|
131
|
+
node_pool_response = Discover::Infrastructure.fetch_node_pool(node_pool.id)
|
132
|
+
|
133
|
+
nodes = []
|
134
|
+
node_pool_response&.nodes&.each do |node_instance|
|
135
|
+
nodes.push(Nodes.new(node_instance.id, node_instance.name, node_instance&.subnet_id,
|
136
|
+
node_instance&.private_ip, node_instance&.public_ip, node_instance.lifecycle_state))
|
137
|
+
end
|
138
|
+
|
139
|
+
node_pool_details.push(Dto::Infra::NodePoolPayload.new(node_pool.name, node_pool.id,
|
140
|
+
node_pool.compartment_id, subnet_ids, nodes))
|
141
|
+
|
142
|
+
# Fetch worker node subnet details from placement configurations
|
143
|
+
placement_configs_details = node_pool.node_config_details.placement_configs
|
144
|
+
placement_configs_details.each do |placement_config|
|
145
|
+
next if placement_config.nil?
|
146
|
+
|
147
|
+
worker_node_subnet_ids.push(placement_config.subnet_id)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Fetch details of subnets associated with cluster
|
153
|
+
# Subnet Lifecycle State: AVAILABLE, PROVISIONING, TERMINATED, TERMINATING, UPDATING
|
154
|
+
logger.debug('Fetching subnet details associated with cluster.')
|
155
|
+
|
156
|
+
subnet_resource_details = []
|
157
|
+
cluster_subnet_ids = []
|
158
|
+
|
159
|
+
kubernetes_api_endpoint_subnet_id = ce_response.endpoint_config.subnet_id
|
160
|
+
service_loadbalancer_subnet_ids = ce_response.options.service_lb_subnet_ids
|
161
|
+
|
162
|
+
cluster_subnet_ids.push(kubernetes_api_endpoint_subnet_id)
|
163
|
+
cluster_subnet_ids += service_loadbalancer_subnet_ids
|
164
|
+
cluster_subnet_ids += node_pool_subnet_ids
|
165
|
+
cluster_subnet_ids += worker_node_subnet_ids
|
166
|
+
|
167
|
+
# Remove duplicates. The | operator is used to compute the union of two arrays
|
168
|
+
# and ensures there are no duplicates. Adding the union of an array with [] does
|
169
|
+
# not change the original array but removes the duplicates
|
170
|
+
cluster_subnet_ids = cluster_subnet_ids | []
|
73
171
|
|
74
|
-
|
172
|
+
cluster_subnet_ids.each do |subnet_id|
|
75
173
|
|
76
|
-
|
77
|
-
next if node_pool.nil?
|
174
|
+
subnet_details = Discover::Infrastructure.fetch_subnet_details(subnet_id)
|
78
175
|
|
79
|
-
|
176
|
+
if !subnet_details[:data].nil? && subnet_details[:status] == 200
|
177
|
+
subnet = subnet_details[:data]
|
178
|
+
subnet_resource_details.push(Dto::Infra::SubnetPayload.new(subnet.display_name, subnet.id, subnet.compartment_id,
|
179
|
+
subnet.prohibit_internet_ingress, subnet.prohibit_public_ip_on_vnic,
|
180
|
+
subnet.cidr_block, subnet.lifecycle_state))
|
80
181
|
end
|
81
182
|
end
|
82
183
|
|
83
184
|
Dto::InfraObjectsPayLoad.new(
|
84
|
-
|
85
|
-
|
185
|
+
cluster_details, vcn_details, subnet_resource_details,
|
186
|
+
load_balancer_details, node_pool_details
|
86
187
|
)
|
87
188
|
rescue StandardError => e
|
88
189
|
logger.error("Error in getting infrastructure resources: #{e}")
|
data/lib/objects_resources.rb
CHANGED
@@ -56,7 +56,7 @@ module ObjectsResources
|
|
56
56
|
|
57
57
|
begin
|
58
58
|
payload_executors = Enum::KubernetesObjectsEnum.constants(false).map do |object_type|
|
59
|
-
if Enum::
|
59
|
+
if Enum::ObjectClientMappingEnum.const_defined? object_type
|
60
60
|
if enable_threading == true
|
61
61
|
Concurrent::Future.execute({ executor: thread_pool }) do
|
62
62
|
get_objects_resources(object_type)
|
@@ -80,11 +80,21 @@ module ObjectsResources
|
|
80
80
|
end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
81
81
|
logger.debug("Time elapsed in collecting objects: #{(end_time - start_time).round(2)} seconds.")
|
82
82
|
|
83
|
-
kubernetes_objects_processed =
|
84
|
-
cluster
|
85
|
-
|
86
|
-
|
87
|
-
|
83
|
+
kubernetes_objects_processed = {
|
84
|
+
cluster: cluster,
|
85
|
+
nodes: @nodes[:processed],
|
86
|
+
pods: @pods[:processed],
|
87
|
+
services: @services[:processed],
|
88
|
+
endpoint_slices: @endpoint_slices[:processed],
|
89
|
+
deployments: @deployments[:processed],
|
90
|
+
replica_sets: @replica_sets[:processed],
|
91
|
+
daemon_sets: @daemon_sets[:processed],
|
92
|
+
cron_jobs: @cron_jobs[:processed],
|
93
|
+
jobs: @jobs[:processed],
|
94
|
+
stateful_sets: @stateful_sets[:processed],
|
95
|
+
events: @events[:processed],
|
96
|
+
namespaces: @namespaces[:processed]
|
97
|
+
}
|
88
98
|
|
89
99
|
kubernetes_objects_raw_responses = {
|
90
100
|
nodes: @nodes[:raw],
|