Skip to content
73 changes: 73 additions & 0 deletions lib/logstash-docket/aliased_plugin.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# encoding: utf-8

require_relative 'plugin'

module LogstashDocket

class AliasPlugin

SUPPORTED_TYPES = Set.new(%w(input output filter codec).map(&:freeze)).freeze

include Plugin

attr_reader :canonical_plugin, :doc_headers

def initialize(canonical_plugin:, alias_name:, doc_headers:)
fail(ArgumentError) unless canonical_plugin.kind_of?(ArtifactPlugin)

super(type: canonical_plugin.type, name: alias_name)

fail("#{canonical_plugin.desc} plugin type #{type} not supported as an integration plugin") unless SUPPORTED_TYPES.include?(type)

@canonical_plugin = canonical_plugin
@doc_headers = doc_headers
end

##
# @see Plugin#version
def version
@canonical_plugin.version
end

def documentation
content = @canonical_plugin.documentation
@doc_headers.each { |header| content = content.gsub(header["replace"], header["with"]) }
content
end

##
# @see Plugin#release_date
def release_date
@canonical_plugin.release_date
end

##
# @see Plugin#changelog_url
def changelog_url
@canonical_plugin.changelog_url
end

##
# @see Plugin#tag
def tag
@canonical_plugin.tag
end

##
# @see Plugin#desc
def desc
@desc ||= "[plugin:#{canonical_name}@#{tag}]"
end

##
# @see Plugin#==
def ==(other)
return false unless super

return false unless other.kind_of?(AliasPlugin)
return false unless self.canonical_plugin == other.canonical_plugin

return true
end
end
end
21 changes: 18 additions & 3 deletions lib/logstash-docket/artifact_plugin.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# encoding: utf-8

require_relative 'embedded_plugin'
require_relative 'aliased_plugin'
require_relative 'plugin'
require_relative 'repository'
require 'set'
Expand Down Expand Up @@ -71,7 +72,7 @@ def initialize(repository:,version:)
@repository = repository
@version = version && Gem::Version.new(version)

@embedded_plugins = Util::ThreadsafeDeferral.for(&method(:generate_embeded_plugins))
@embedded_plugins = Util::ThreadsafeDeferral.for(&method(:generate_embedded_plugins))
end

##
Expand Down Expand Up @@ -105,7 +106,7 @@ def desc
end

##
# Returns an {@link Enumerable[Plugin]} containing itself and any wrapped plugins
# Returns an {@link Enumerable[Plugin]} containing itself and any integrated plugins
#
# @return [Enumerable[Plugin]]
def with_embedded_plugins
Expand All @@ -118,6 +119,20 @@ def with_embedded_plugins
end
end

##
# Returns an {@link Enumerable[Plugin]} containing itself and any wrapped plugins
#
# @return [Enumerable[Plugin]]
def with_wrapped_plugins(alias_mappings)
return enum_for(:with_wrapped_plugins, alias_mappings) unless block_given?

with_embedded_plugins do |plugin|
plugin.with_alias(alias_mappings) do |plugin_or_alias|
yield plugin_or_alias
end
end
end

##
# Returns zero or more {@link Plugin::Wrapped} provided by
# an "integration" plugin.
Expand All @@ -144,7 +159,7 @@ def ==(other)
# @api private
#
# @return [Array[EmbeddedPlugin]]: a frozen array of {@link EmbeddedPlugin}
def generate_embeded_plugins
def generate_embedded_plugins
gem_data_version = version || repository.rubygem_info.latest
gem_data_version || fail("No releases on rubygems")

Expand Down
12 changes: 12 additions & 0 deletions lib/logstash-docket/plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ def desc
fail NotImplementedError
end

def with_alias(alias_mappings)
yield self

if alias_mappings.include?(type) && alias_mappings[type].include?(name)
alias_mappings[type][name].each do |alias_name|
yield AliasPlugin.new(canonical_plugin: self,
alias_name: alias_name["alias"],
doc_headers: alias_name["doc_headers"])
end
end
end

##
# @return [Boolean]
def ==(other)
Expand Down
20 changes: 20 additions & 0 deletions lib/logstash-docket/util/alias_plugin_util.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# encoding: utf-8

require "yaml"
require "net/http"

module LogstashDocket
module Util
##
# A util class defines repetitive logics for aliased plugins.
#
class AliasPluginUtil

ALIAS_MAPPINGS_URL = 'https://raw.githubusercontent.com/elastic/logstash/master/logstash-core/src/main/resources/org/logstash/plugins/AliasRegistry.yml'

def fetch_alias_mappings
YAML::safe_load(Net::HTTP.get(URI(ALIAS_MAPPINGS_URL))) || {}
end
end
end
end
27 changes: 25 additions & 2 deletions plugindocs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
require "fileutils"
require "time"
require "yaml"
require "net/http"
require "stud/try"
require "pmap" # Enumerable#peach

require_relative 'lib/logstash-docket'
require_relative 'lib/logstash-docket/util/alias_plugin_util'

class PluginDocs < Clamp::Command
option "--output-path", "OUTPUT", "Path to the top-level of the logstash-docs path to write the output.", required: true
Expand All @@ -26,6 +26,8 @@ def execute
report = JSON.parse(File.read(plugins_json))
repositories = report["successful"]

alias_mappings = load_alias_mappings

repositories.peach(parallelism) do |repository_name, details|
if settings['skip'].include?(repository_name)
$stderr.puts("Skipping #{repository_name}\n")
Expand All @@ -50,7 +52,7 @@ def execute
next
end

released_plugin.with_embedded_plugins.each do |plugin|
released_plugin.with_wrapped_plugins(alias_mappings).each do |plugin|
$stderr.puts("#{plugin.desc}: fetching documentation\n")
content = plugin.documentation

Expand Down Expand Up @@ -130,6 +132,27 @@ def tag(version)
version ? "v#{version}" : "main"
end

# returns alias mappings for each plugin type & name ([type][target]=alias) ex: (["input"]["beats"]="agent")
def load_alias_mappings
alias_util = Util::AliasPluginUtil.new
yaml = alias_util.fetch_alias_mappings

aliases = Hash.new

yaml.each do |type, alias_defs|
aliases[type] = Hash.new
alias_defs.each do |alias_definition|
mapping = {}
mapping["alias"] = alias_definition["alias"]
mapping["doc_headers"] = alias_definition["docs"]
aliases[type][alias_definition["from"]] ||= []
aliases[type][alias_definition["from"]] << mapping
end
end

aliases
end

##
# Checks if no version bump and return true if so, false otherwise.
#
Expand Down
18 changes: 7 additions & 11 deletions versioned_plugins.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@
require "json"
require "fileutils"
require "time"
require "yaml"
require "net/http"
require "stud/try"
require "octokit"
require "erb"
require "pmap"
require "yaml"

require_relative 'lib/logstash-docket'

require_relative 'lib/core_ext/erb_result_with_hash'
require_relative 'lib/logstash-docket'
require_relative 'lib/logstash-docket/util/alias_plugin_util'

class VersionedPluginDocs < Clamp::Command
option "--output-path", "OUTPUT", "Path to a directory where logstash-docs repository will be cloned and written to", required: true
Expand Down Expand Up @@ -413,16 +410,15 @@ def lazy_create_output_folder(output_asciidoc)
# param plugin_names_by_type: map of lists {:input => [beats, tcp, ...]}
# return list of triples (type, alias, target) es: ("input", "agent", "beats")
def load_alias_definitions_for_target_plugins(plugin_names_by_type)
alias_url = URI('https://raw.githubusercontent.com/elastic/logstash/master/logstash-core/src/main/resources/org/logstash/plugins/AliasRegistry.yml')
alias_yml = Net::HTTP.get(alias_url)
yaml = YAML::safe_load(alias_yml) || {}
alias_plugin_util = Util::AliasPluginUtil.new
yaml = alias_plugin_util.fetch_alias_mappings

aliases = []

yaml.each do |type, alias_defs|
alias_defs.each do |alias_name, target|
if plugin_names_by_type.fetch(type).include?(target)
aliases << [type, alias_name, target]
alias_defs.each do |alias_definition|
if plugin_names_by_type.fetch(type).include?(alias_definition["from"])
aliases << [type, alias_definition["alias"], alias_definition["from"]]
end
end
end
Expand Down