lib/fluent/plugin/kubernetes_metadata_common.rb
# frozen_string_literal: true
#
# Fluentd Kubernetes Metadata Filter Plugin - Enrich Fluentd events with
# Kubernetes metadata
#
# Copyright 2017 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
module KubernetesMetadata
module Common
class GoneError < StandardError
def initialize(msg = '410 Gone')
super
end
end
def match_annotations(annotations)
result = {}
@annotations_regexps.each do |regexp|
annotations.each do |key, value|
if ::Fluent::StringUtil.match_regexp(regexp, key.to_s)
result[key] = value
end
end
end
result
end
def parse_namespace_metadata(namespace_object)
labels = ''
labels = syms_to_strs(namespace_object[:metadata][:labels].to_h) unless (@skip_labels || @skip_namespace_labels)
annotations = match_annotations(syms_to_strs(namespace_object[:metadata][:annotations].to_h))
kubernetes_metadata = {
'namespace_id' => namespace_object[:metadata][:uid],
'creation_timestamp' => namespace_object[:metadata][:creationTimestamp]
}
kubernetes_metadata['namespace_labels'] = labels unless labels.empty?
kubernetes_metadata['namespace_annotations'] = annotations unless annotations.empty?
kubernetes_metadata
end
def parse_pod_metadata(pod_object)
labels = ''
labels = syms_to_strs(pod_object[:metadata][:labels].to_h) unless (@skip_labels || @skip_pod_labels)
annotations = match_annotations(syms_to_strs(pod_object[:metadata][:annotations].to_h))
# collect container information
container_meta = {}
begin
pod_object[:status][:containerStatuses].each do |container_status|
container_id = (container_status[:containerID]||"").sub(%r{^[-_a-zA-Z0-9]+://}, '')
key = container_status[:name]
container_meta[key] = if @skip_container_metadata
{
'name' => container_status[:name]
}
else
{
'name' => container_status[:name],
'image' => container_status[:image],
'image_id' => container_status[:imageID],
:containerID => container_id
}
end
end if pod_object[:status] && pod_object[:status][:containerStatuses]
rescue StandardError=>e
log.warn("parsing container meta information failed for: #{pod_object[:metadata][:namespace]}/#{pod_object[:metadata][:name]}: #{e}")
end
ownerrefs_meta = []
begin
pod_object[:metadata][:ownerReferences].each do |owner_reference|
ownerrefs_meta.append({
'kind' => owner_reference[:kind],
'name' => owner_reference[:name]
})
end
rescue StandardError => e
log.warn("parsing ownerrefs meta information failed for: #{pod_object[:metadata][:namespace]}/#{pod_object[:metadata][:name]}: #{e}")
end if @include_ownerrefs_metadata && pod_object[:metadata][:ownerReferences]
kubernetes_metadata = {
'namespace_name' => pod_object[:metadata][:namespace],
'pod_id' => pod_object[:metadata][:uid],
'pod_name' => pod_object[:metadata][:name],
'pod_ip' => pod_object[:status][:podIP],
'containers' => syms_to_strs(container_meta),
'host' => pod_object[:spec][:nodeName],
'ownerrefs' => (ownerrefs_meta if @include_ownerrefs_metadata)
}.compact
kubernetes_metadata['annotations'] = annotations unless annotations.empty?
kubernetes_metadata['labels'] = labels unless labels.empty?
kubernetes_metadata['master_url'] = @kubernetes_url unless @skip_master_url
kubernetes_metadata
end
def syms_to_strs(hsh)
newhsh = {}
hsh.each_pair do |kk, vv|
if vv.is_a?(Hash)
vv = syms_to_strs(vv)
end
if kk.is_a?(Symbol)
newhsh[kk.to_s] = vv
else
newhsh[kk] = vv
end
end
newhsh
end
end
end