# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you 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. require "pluginmanager/command" require "pluginmanager/templates/render_context" require "erb" require "ostruct" require "fileutils" require "pathname" class LogStash::PluginManager::Generate < LogStash::PluginManager::Command TYPES = ["input", "filter", "output", "codec"] option "--type", "TYPE", "Type of the plugin {input, filter, codec, output}s", :required => true option "--name", "PLUGIN", "Name of the new plugin", :required => true option "--path", "PATH", "Location where the plugin skeleton will be created", :default => Dir.pwd def execute validate_params source = File.join(File.dirname(__FILE__), "templates", "#{type}-plugin") @target_path = File.join(path, full_plugin_name) FileUtils.mkdir(@target_path) puts " Creating #{@target_path}" begin create_scaffold(source, @target_path) rescue Errno::EACCES => exception report_exception("Permission denied when executing the plugin manager", exception) rescue => exception report_exception("Plugin creation Aborted", exception) end end private def validate_params raise(ArgumentError, "should be one of: input, filter, codec or output") unless TYPES.include?(type) end def create_scaffold(source, target) transform_r(source, target) end def transform_r(source, target) Dir.entries(source).each do |entry| next if [".", ".."].include?(entry) source_entry = File.join(source, entry) target_entry = File.join(target, entry) if File.directory?(source_entry) FileUtils.mkdir(target_entry) unless File.exist?(target_entry) transform_r(source_entry, target_entry) else # copy the new file, in case of being an .erb file should render first if source_entry.end_with?("erb") target_entry = target_entry.gsub(/.erb$/, "").gsub("example", name) File.open(target_entry, "w") { |f| f.write(render(source_entry)) } else FileUtils.cp(source_entry, target_entry) end puts "\t create #{File.join(full_plugin_name, Pathname.new(target_entry).relative_path_from(Pathname.new(@target_path)))}" end end end def render(source) template = File.read(source) renderer = ERB.new(template) context = LogStash::PluginManager::RenderContext.new(options) renderer.result(context.get_binding) end def options git_data = get_git_info @options ||= { :plugin_name => name, :author => git_data.author, :email => git_data.email, :min_version => "2.0", :logstash_path => File.expand_path('../..', File.dirname(__FILE__)) } end def get_git_info git = OpenStruct.new git.author = %x{git config --get user.name}.strip rescue "your_username" git.email = %x{git config --get user.email}.strip rescue "your_username@example.com" git end def full_plugin_name @full_plugin_name ||= "logstash-#{type}-#{name.downcase}" end end