idcfcloud 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,165 @@
1
+ require 'idcf/cli/lib/util/cli_logger'
2
+ module Idcf
3
+ module Cli
4
+ module Lib
5
+ # api execute class
6
+ class Api
7
+ attr_accessor :links, :client, :raw
8
+
9
+ class << self
10
+ # command str
11
+ #
12
+ # @param link
13
+ # @return String
14
+ def command_param_str(link)
15
+ list = []
16
+ link.url_param_names.each do |name|
17
+ list << "<#{name}>"
18
+ end
19
+
20
+ if !link.query_param_names.size.zero? || !link.properties.size.zero?
21
+ list << (param_required?(link) ? '<params>' : '[params]')
22
+ end
23
+
24
+ list.join(' ')
25
+ end
26
+
27
+ def param_required?(link)
28
+ param_names = link.properties.keys
29
+ get_names = link.query_param_names
30
+ link.required.each do |name|
31
+ return true if param_names.include?(name) || get_names.include?(name)
32
+ end
33
+ false
34
+ end
35
+ end
36
+
37
+ # initialize
38
+ #
39
+ # @param links [Array] in Idcf::JsonHyperSchema::Expands::LinkinfoBase
40
+ # @param client [Faraday]
41
+ def initialize(links: [], client: nil)
42
+ @links = links
43
+ @client = client
44
+ end
45
+
46
+ # find link
47
+ #
48
+ # @param command [String]
49
+ # @return Idcf::JsonHyperSchema::Expands::LinkInfoBase
50
+ def find_link(command)
51
+ result = nil
52
+ @links.each do |link|
53
+ if link.title.to_s == command.to_s
54
+ result = link
55
+ break
56
+ end
57
+ end
58
+ result
59
+ end
60
+
61
+ # do
62
+ #
63
+ # @param command [String]
64
+ # @param args [Array]
65
+ # @return Hash
66
+ # @raise
67
+ def do(command, *args)
68
+ args ||= []
69
+ link = find_link(command)
70
+ cli_error("Not found #{command} Api") if link.nil?
71
+
72
+ between_param(link, args)
73
+ @raw = do_api(link, args)
74
+ result_log(@raw)
75
+
76
+ return @raw.body if @raw.success?
77
+
78
+ raise Idcf::Cli::Error::ApiError.new(@raw), ''
79
+ end
80
+
81
+ # result_api
82
+ #
83
+ # @param command [String]
84
+ # @param args [Array]
85
+ # @param api_result [Hash]
86
+ # @param resource_id
87
+ def result_api(command, args, api_result, resource_id = nil)
88
+ link = find_link(command)
89
+ cli_error("Not found #{command} Api") if link.nil?
90
+ r_api_title = link.result_api_title
91
+ return nil if r_api_title.empty?
92
+ r_api_params = link.result_api_params(args, api_result, resource_id)
93
+ self.do(r_api_title, *r_api_params)
94
+ end
95
+
96
+ protected
97
+
98
+ def result_log(result)
99
+ log = Idcf::Cli::Lib::Util::CliLogger
100
+ log.info("result_headers: #{result.headers}")
101
+ log.info("result_status: #{result.status}")
102
+ log.info("result_body: #{result.body}")
103
+ end
104
+
105
+ # between link param
106
+ #
107
+ # @param link [Idcf::JsonHyperSchema::Expands::LinkInfoBase]
108
+ # @param args
109
+ # @raise
110
+ def between_param(link, args)
111
+ offset = (self.class.param_required?(link) ? 1 : 0)
112
+ min = link.url_param_names.size + offset
113
+ max = between_max(min, link)
114
+
115
+ msg = format('Argument: %s', self.class.command_param_str(link))
116
+ cli_error msg unless args.size.between?(min, max)
117
+ end
118
+
119
+ def between_max(min, link)
120
+ offset = 0
121
+ required_f = self.class.param_required?(link)
122
+ if !required_f && (link.properties.present? || link.query_param_names.present?)
123
+ offset = 1
124
+ end
125
+ min + offset
126
+ end
127
+
128
+ def do_api(link, args)
129
+ method = link.method.downcase
130
+ uri = link.make_uri_for_cli(args)
131
+ request_params = link.make_params_for_cli(args)
132
+
133
+ log = Idcf::Cli::Lib::Util::CliLogger
134
+ log.info("request_headers: #{@client.headers}")
135
+ log.info("arguments: #{args.join(' ')}")
136
+ log.info("uri: #{uri}")
137
+ log.info("method: #{method}")
138
+ log.info("request_params: #{request_params}")
139
+
140
+ client_send(method, uri, request_params)
141
+ end
142
+
143
+ def client_send(method, uri, request_params)
144
+ case method.to_s
145
+ when 'get', 'delete'
146
+ @client.__send__(method, uri, nil) do |req|
147
+ if request_params.present?
148
+ req.headers[:content_type] = 'application/json'
149
+ body = JSON.generate(request_params)
150
+ req.headers['Content-Length'] = body.size.to_s
151
+ req.body = body
152
+ end
153
+ end
154
+ else
155
+ @client.__send__(method, uri, request_params)
156
+ end
157
+ end
158
+
159
+ def cli_error(msg)
160
+ raise Idcf::Cli::Error::CliError, msg
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,94 @@
1
+ require 'idcf/cli/conf/const'
2
+ require 'idcf/cli/lib/util/ini_conf'
3
+ require 'idcf/cli/lib/util/yml_conf'
4
+
5
+ module Idcf
6
+ module Cli
7
+ module Lib
8
+ # configure
9
+ class Configure
10
+ class << self
11
+ attr_reader :config, :code_config
12
+
13
+ def reload
14
+ @config = nil
15
+ @code_config = nil
16
+ end
17
+
18
+ # get user config value
19
+ #
20
+ # @param name [String]
21
+ # @param profile [String]
22
+ # @return String or Hash
23
+ # @raise
24
+ def get_user_conf(name, profile = 'default')
25
+ return config.find(name, profile) if config
26
+ @config = load_user_conf
27
+ msg = 'Run the command `configure`'
28
+ raise Idcf::Cli::Error::CliError, msg unless config
29
+
30
+ config.find(name, profile)
31
+ end
32
+
33
+ # get code setting value
34
+ #
35
+ # @param path [String] find path
36
+ # @param o [Hash] options
37
+ # @return String or Hash
38
+ # @raise
39
+ def get_code_conf(path, o = {})
40
+ profile = get_profile(o)
41
+
42
+ return get_user_conf(path, profile)
43
+ rescue
44
+ return code_config.find(path) if code_config
45
+ f_path = Idcf::Cli::Conf::Const::CODE_CONF_PATH
46
+ @code_config = Idcf::Cli::Lib::Util::YmlConf.new(f_path)
47
+ code_config.find(path)
48
+ end
49
+
50
+ # get profile
51
+ #
52
+ # @param o [Hash] options
53
+ # @return String
54
+ def get_profile(o)
55
+ o['profile'] || 'default'
56
+ end
57
+
58
+ # get region
59
+ #
60
+ # @param o [Hash] options
61
+ # @param read_conf [Boolean]
62
+ # @return String
63
+ def get_region(o, read_conf = false)
64
+ return o['region'] if o['region']
65
+ region = ''
66
+ region = get_user_conf('region', get_profile(o)) if read_conf
67
+ region.empty? ? 'default' : region
68
+ rescue
69
+ 'default'
70
+ end
71
+
72
+ protected
73
+
74
+ # load user config
75
+ # read only object
76
+ #
77
+ # @return Idcf::Cli::Lib::Util::IniConf
78
+ def load_user_conf
79
+ result = nil
80
+ [
81
+ Idcf::Cli::Conf::Const::USER_CONF_GLOBAL,
82
+ Idcf::Cli::Conf::Const::USER_CONF_PATH
83
+ ].each do |v|
84
+ tmp = Idcf::Cli::Lib::Util::IniConf.new(File.expand_path(v))
85
+ next if tmp.load_error?
86
+ result = result.nil? ? tmp : result.merge!(tmp)
87
+ end
88
+ result
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,40 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+ module Idcf
4
+ module Cli
5
+ module Lib
6
+ module Convert
7
+ module Filter
8
+ # filter base
9
+ class Base
10
+ attr_accessor :options
11
+
12
+ MSG_NO_DATA = 'No data is extracted.'.freeze
13
+
14
+ def initialize(table_flag: false)
15
+ @options = {
16
+ table_flag: table_flag
17
+ }
18
+ end
19
+
20
+ # filter
21
+ #
22
+ # @param _data [Hash]
23
+ # @param _condition [String]
24
+ # @return Hash
25
+ # @raise
26
+ def filter(_data, _condition)
27
+ raise Idcf::Cli::Error::CliError, 'override'
28
+ end
29
+
30
+ protected
31
+
32
+ def cli_error(msg)
33
+ raise Idcf::Cli::Error::CliError, msg
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,73 @@
1
+ require_relative './base'
2
+ module Idcf
3
+ module Cli
4
+ module Lib
5
+ module Convert
6
+ module Filter
7
+ # filter fields
8
+ class FieldFilter < Base
9
+ MSG_NO_TARGETS = '[fields][%s] is not found.'.freeze
10
+
11
+ # filter
12
+ #
13
+ # @param data [Hash]
14
+ # @param condition [String]
15
+ # @return Hash
16
+ def filter(data, condition)
17
+ return data if condition.empty?
18
+ cli_error(MSG_NO_DATA) unless [Array, Hash].include?(data.class)
19
+ return extraction(data, condition) if data.class == Hash
20
+
21
+ recursion(data, condition)
22
+ end
23
+
24
+ protected
25
+
26
+ def recursion(values, condition)
27
+ return values unless values.class == Array
28
+ [].tap do |result|
29
+ values.each do |data|
30
+ case data
31
+ when Array
32
+ result << recursion(data, condition)
33
+ when Hash
34
+ result << extraction(data, condition)
35
+ else
36
+ cli_error(MSG_NO_DATA)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ def extraction(data, condition)
43
+ check_extraction(data, condition)
44
+ {}.tap do |result|
45
+ condition.split(',').each do |key|
46
+ next if key.empty?
47
+
48
+ val = data[key]
49
+ if @options[:table_flag]
50
+ result[key] = [Array, Hash].include?(val.class) ? val.to_s : val
51
+ next
52
+ end
53
+ result[key] = val
54
+ end
55
+ end
56
+ end
57
+
58
+ def check_extraction(data, condition)
59
+ no_targets = []
60
+ condition.split(',').each do |key|
61
+ next if key.empty?
62
+ no_targets << key unless data.key?(key)
63
+ end
64
+
65
+ return nil if no_targets.empty?
66
+ cli_error(MSG_NO_TARGETS % no_targets.join(','))
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,30 @@
1
+ require_relative './base'
2
+ require 'jsonpath'
3
+ module Idcf
4
+ module Cli
5
+ module Lib
6
+ module Convert
7
+ module Filter
8
+ # filter json path
9
+ class JsonPathFilter < Base
10
+ # filter
11
+ #
12
+ # @param data [Hash]
13
+ # @param condition [String]
14
+ # @return Hash
15
+ def filter(data, condition)
16
+ unless [Array, Hash].include?(data.class)
17
+ cli_error(MSG_NO_DATA) unless condition.empty?
18
+ return data
19
+ end
20
+ path = JsonPath.new(condition)
21
+ path.on(data.to_json)
22
+ rescue => e
23
+ cli_error("[json-path]#{e.message}")
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,27 @@
1
+ module Idcf
2
+ module Cli
3
+ module Lib
4
+ module Include
5
+ # Recurring calling
6
+ module RecurringCalling
7
+ # recurring calling
8
+ #
9
+ # @param call_name [String]
10
+ # @param args [Array]
11
+ # @param max [int] loop_count
12
+ # @param sleep_offset [int]
13
+ # @param &block [Proc] check return value
14
+ # @return Mixed
15
+ def recurring_calling(call_name, args, max = 20, sleep_offset = 2)
16
+ (1..max).each do |n|
17
+ res = __send__(call_name.to_sym, *args)
18
+ return res if yield(res)
19
+ sleep sleep_offset * n
20
+ end
21
+ raise Idcf::Cli::Error::CliError, 'Authentication time out
'
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ module Idcf
2
+ module Cli
3
+ module Lib
4
+ module Util
5
+ # cli file
6
+ class CliFile
7
+ class << self
8
+ # mkdir
9
+ #
10
+ # @param path [String]
11
+ # @raise
12
+ def mkdir(path)
13
+ target = file?(path) ? File.dirname(path) : path
14
+ FileUtils.mkdir_p(target, mode: 0o755)
15
+ rescue => e
16
+ raise Idcf::Cli::Error::CliError, e.message
17
+ end
18
+
19
+ # writable
20
+ #
21
+ # @param path [String]
22
+ # @raise
23
+ def writable(path)
24
+ msg = "Permission error (#{path})"
25
+ raise Idcf::Cli::Error::CliError, msg unless File.writable?(path)
26
+ end
27
+
28
+ protected
29
+
30
+ def file?(path)
31
+ return false if Dir.exist?(path)
32
+ last_path = path.split('/').pop
33
+ last_path.split('.').size > 1
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,95 @@
1
+ require 'logger'
2
+ require 'idcf/cli/error/init'
3
+ require 'fileutils'
4
+ require 'idcf/cli/lib/configure'
5
+ require_relative 'cli_file'
6
+ module Idcf
7
+ module Cli
8
+ module Lib
9
+ module Util
10
+ # logger
11
+ # level: shwo LOG_METHODS
12
+ class CliLogger
13
+ class << self
14
+ attr_reader :logger, :current_path
15
+ LOG_METHODS = %w(debug error fatal info unknown warn).freeze
16
+
17
+ def log_instance
18
+ return nil unless output_log?
19
+ return logger unless logger.nil?
20
+ path = log_path
21
+ @current_path = path
22
+ Idcf::Cli::Lib::Util::CliFile.mkdir(path)
23
+
24
+ Idcf::Cli::Lib::Util::CliFile.writable(path) if File.exist?(path)
25
+ @logger = Logger.new(path)
26
+ logger.level = Idcf::Cli::Conf::Const::LOG_LEVEL
27
+ logger
28
+ end
29
+
30
+ # open file delete
31
+ def delete
32
+ return nil unless output_log?
33
+ path = log_path
34
+ return nil unless File.exist?(path)
35
+ File.unlink(path)
36
+ end
37
+
38
+ # logrotate file delete
39
+ def cleaning(o)
40
+ paths = log_paths
41
+ log_limit = Idcf::Cli::Lib::Configure.get_code_conf('log_limit', o).to_i
42
+ return unless paths.size > log_limit
43
+ paths.reverse[log_limit, paths.size].each do |f|
44
+ File.unlink(f)
45
+ end
46
+ end
47
+
48
+ def log_paths
49
+ dir_path = File.expand_path('..', log_path)
50
+ Dir.glob("#{dir_path}/#{Idcf::Cli::Conf::Const::LOG_FILE_PREFIX}*")
51
+ end
52
+
53
+ def respond_to_missing?(symbol, _include_prvate)
54
+ LOG_METHODS.index(symbol.to_s) ? true : false
55
+ end
56
+
57
+ def method_missing(name, *args)
58
+ return super unless LOG_METHODS.index(name.to_s)
59
+ arg = [args[0]]
60
+ arg << args[1] unless args[1].nil?
61
+ add(name, *arg)
62
+ end
63
+
64
+ protected
65
+
66
+ def output_log?
67
+ conf = Idcf::Cli::Lib::Configure
68
+ return false unless conf.get_user_conf('output_log').casecmp('y').zero?
69
+ path = conf.get_user_conf('log_path')
70
+ path.present?
71
+ rescue => _e
72
+ false
73
+ end
74
+
75
+ def log_path
76
+ base_path = Idcf::Cli::Lib::Configure.get_user_conf('log_path')
77
+
78
+ path = "#{base_path}/#{Idcf::Cli::Conf::Const::LOG_FILE_NAME}"
79
+ File.expand_path(path)
80
+ rescue => _e
81
+ nil
82
+ end
83
+
84
+ def add(severity_name, data)
85
+ return nil unless output_log?
86
+ severity = "Logger::Severity::#{severity_name.upcase}".constantize
87
+ log = log_instance
88
+ log.add(severity, data.to_s)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,41 @@
1
+ module Idcf
2
+ module Cli
3
+ module Lib
4
+ module Util
5
+ # input
6
+ class Input
7
+ class << self
8
+ def qa(title, setting, nd = '')
9
+ loop do
10
+ v = setting.class == Hash ? setting[:list] : nil
11
+ v = v.nil? ? [] : v
12
+ set_s = v.empty? ? '' : "(#{v.join('/')})"
13
+ puts "#{title}#{set_s}[#{nd.empty? ? 'NONE' : nd}]"
14
+ result = qa_answer_input(v, nd)
15
+ return result unless result.empty?
16
+ end
17
+ end
18
+
19
+ def qa_answer_input(list, nd = '')
20
+ loop do
21
+ res = STDIN.gets.strip
22
+ result = res.empty? ? nd : res
23
+ return result if qa_answer?(result, list)
24
+ puts "from this [#{list.join('/')}]"
25
+ ''
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def qa_answer?(val, list)
32
+ return true if list.nil? || list.empty?
33
+ return true if Regexp.new("\\A(#{list.join('|')})\\Z") =~ val
34
+ false
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+ module Idcf
3
+ module Cli
4
+ module Lib
5
+ module Util
6
+ # name
7
+ class Name
8
+ class << self
9
+ def namespace(cls_name)
10
+ class_names = cls_name.split('::')
11
+ class_names.pop
12
+ class_names.join('::')
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,46 @@
1
+ require_relative '../base'
2
+
3
+ module Idcf
4
+ module Cli
5
+ module Service
6
+ module Ilb
7
+ # check_job
8
+ class CheckJob < Idcf::Cli::Service::Base
9
+ attr_reader :api
10
+
11
+ class << self
12
+ def description
13
+ 'Check job result'
14
+ end
15
+ end
16
+
17
+ # do
18
+ #
19
+ # @param api [Idcf::Ilb::Lib::Api]
20
+ # @param _o [Hash] options
21
+ # @param job_id [String]
22
+ def do(api, _o, job_id)
23
+ @api = api
24
+ job = recurring_calling(:find, [job_id], &:present?)
25
+ return nil if job['method'].casecmp('delete').zero?
26
+ raise Idcf::Cli::Error::ApiError.new(@api.raw), 'Job Timeout.' if job.nil?
27
+ true
28
+ end
29
+
30
+ protected
31
+
32
+ def find(id)
33
+ res = @api.do(:get_job, id)
34
+ case res['job_status'].downcase
35
+ when 'success'
36
+ return res
37
+ when 'failed'
38
+ raise Idcf::Cli::Error::ApiError.new(@api.raw), 'API Failed.'
39
+ end
40
+ nil
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end