dtk-client 0.10.5 → 0.10.6
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 +13 -5
- data/.gitignore +1 -0
- data/bin/dtk-puppet +38 -0
- data/lib/cli/command/module/delete_from_remote.rb +3 -4
- data/lib/cli/command/module/pull_dtkn.rb +3 -1
- data/lib/cli/command/module/uninstall.rb +2 -2
- data/lib/cli/command/service/uninstall.rb +3 -3
- data/lib/cli/command/token.rb +1 -1
- data/lib/cli/version.rb +1 -1
- data/lib/client/error/subclasses.rb +7 -0
- data/lib/client/git_repo/adapter/git_gem.rb +38 -5
- data/lib/client/git_repo.rb +8 -3
- data/lib/client/load_source/component_info.rb +1 -4
- data/lib/client/load_source/service_info.rb +5 -7
- data/lib/client/load_source.rb +62 -10
- data/lib/client/module_ref.rb +2 -0
- data/lib/client/operation/client_module_dir/git_repo/internal/dtkn.rb +6 -1
- data/lib/client/operation/client_module_dir/git_repo/internal.rb +8 -2
- data/lib/client/operation/client_module_dir/git_repo.rb +13 -4
- data/lib/client/operation/module/delete_from_remote.rb +2 -2
- data/lib/client/operation/module/install/common_module.rb +1 -1
- data/lib/client/operation/module/list.rb +1 -1
- data/lib/client/operation/module/publish.rb +1 -0
- data/lib/client/operation/module/pull_dtkn.rb +4 -3
- data/lib/client/operation/module/push_dtkn/convert_source.rb +18 -5
- data/lib/client/operation/module/push_dtkn.rb +1 -1
- data/lib/client/operation/module/stage.rb +1 -1
- data/lib/client/operation/module/uninstall.rb +53 -29
- data/lib/client/operation/service/converge.rb +1 -1
- data/lib/client/operation/service/delete.rb +13 -2
- data/lib/client/operation/service/exec.rb +2 -2
- data/lib/client/operation/service/uninstall.rb +11 -8
- data/lib/client/render/view/table/processor.rb +7 -0
- data/lib/client/render.rb +1 -0
- data/lib/client/response/render_helper.rb +5 -2
- data/lib/client/service_and_component_info/transform_from/info/component.rb +1 -1
- data/lib/client/util/os_util.rb +25 -0
- data/lib/dtk_puppet/parse_structure.rb +180 -0
- data/lib/dtk_puppet/parser.rb +92 -0
- data/lib/dtk_puppet.rb +24 -0
- metadata +16 -11
@@ -54,21 +54,24 @@ module DTK::Client; class Operation::Module
|
|
54
54
|
|
55
55
|
create_and_checkout_branch?(current_branch, target_repo_dir, "remotes/dtkn/master") do |repo|
|
56
56
|
FileUtils.mkdir_p("#{target_repo_dir}/assemblies") unless File.exists?("#{target_repo_dir}/assemblies")
|
57
|
-
|
57
|
+
|
58
58
|
args = [transform_helper, ServiceInfo.info_type, service_info['remote_repo_url'], parent]
|
59
59
|
service_file_path__content_array.each { |file| Operation::ClientModuleDir.create_file_with_content("#{service_file_path(target_repo_dir, file, *args)}", file[:content]) }
|
60
|
-
|
60
|
+
|
61
61
|
commit_and_push_to_remote(repo, target_repo_dir, "master", "dtkn")
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
def self.transform_component_info(target_repo_dir, parent, component_info, parsed_common_module, current_branch)
|
66
|
-
transform_helper
|
66
|
+
transform_helper = ServiceAndComponentInfo::TransformTo.new(target_repo_dir, parent.module_ref, parent.version, parsed_common_module)
|
67
67
|
component_file_path__content_array = ComponentInfo.transform_info(transform_helper, component_info['remote_repo_url'], parent)
|
68
|
+
component_info_remote = "remotes/dtkn-component-info/master"
|
68
69
|
|
69
|
-
create_and_checkout_branch?(current_branch, target_repo_dir,
|
70
|
-
|
70
|
+
create_and_checkout_branch?(current_branch, target_repo_dir, component_info_remote) do |repo|
|
71
|
+
# find deleted files from master branch and delete them in component info cached branch ("remotes/dtkn-component-info/master")
|
72
|
+
delete_diffs(repo, component_info_remote, current_branch, target_repo_dir)
|
71
73
|
|
74
|
+
component_file_path__content_array.each { |file| Operation::ClientModuleDir.create_file_with_content("#{file_path(target_repo_dir, file)}", file[:content]) }
|
72
75
|
commit_and_push_to_remote(repo, target_repo_dir, "master", "dtkn-component-info")
|
73
76
|
end
|
74
77
|
end
|
@@ -77,6 +80,16 @@ module DTK::Client; class Operation::Module
|
|
77
80
|
|
78
81
|
attr_reader :info_processor, :target_repo_dir, :parent
|
79
82
|
|
83
|
+
def self.delete_diffs(repo, component_info_remote, current_branch, target_repo_dir)
|
84
|
+
if diffs = repo.diff_name_status(component_info_remote, current_branch)
|
85
|
+
deletes_and_renames = diffs.select{ |k,v| v.eql?('D') || v.start_with?('R') }
|
86
|
+
unless deletes_and_renames.empty?
|
87
|
+
to_delete = deletes_and_renames.keys.select { |key| !key.include?('dtk.model.yaml') && !key.include?('module_refs.yaml') }
|
88
|
+
to_delete.each { |file| Operation::ClientModuleDir.rm_f("#{target_repo_dir}/#{file}") }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
80
93
|
def self.write_output_path_text_pairs(transform_helper, target_repo_dir, info_types_processed)
|
81
94
|
end
|
82
95
|
|
@@ -52,7 +52,7 @@ module DTK::Client
|
|
52
52
|
end
|
53
53
|
|
54
54
|
error_msg = "To allow push-dtkn to go through, invoke 'dtk push' to push the changes to server before invoking push-dtkn again"
|
55
|
-
GitRepo.modified_with_diff?(@target_repo_dir, { :error_msg => error_msg })
|
55
|
+
GitRepo.modified_with_diff?(@target_repo_dir, { :error_msg => error_msg, :command => 'push-dtkn' })
|
56
56
|
|
57
57
|
query_string_hash = QueryStringHash.new(
|
58
58
|
:module_name => @module_ref.module_name,
|
@@ -36,7 +36,7 @@ module DTK::Client
|
|
36
36
|
)
|
37
37
|
|
38
38
|
error_msg = "To allow stage to go through, invoke 'dtk push' to push the changes to server before invoking stage again"
|
39
|
-
GitRepo.modified_with_diff?(directory_path || module_ref.client_dir_path, { :error_msg => error_msg }) unless force
|
39
|
+
GitRepo.modified_with_diff?(directory_path || module_ref.client_dir_path, { :error_msg => error_msg, :command => 'stage' }) unless force
|
40
40
|
service_name ||= rest_post("#{BaseRoute}/generate_service_name", post_body).data
|
41
41
|
base_path = ClientModuleDir.ret_base_path(:service, service_name)
|
42
42
|
|
@@ -23,8 +23,7 @@ module DTK::Client
|
|
23
23
|
module_ref = args.required(:module_ref)
|
24
24
|
name = args.required(:name)
|
25
25
|
version = args.required(:version)
|
26
|
-
|
27
|
-
|
26
|
+
|
28
27
|
unless name.nil?
|
29
28
|
query_string_hash = QueryStringHash.new(
|
30
29
|
:detail_to_include => ['remotes', 'versions']
|
@@ -32,44 +31,69 @@ module DTK::Client
|
|
32
31
|
response = rest_get("#{BaseRoute}/list", query_string_hash)
|
33
32
|
installed_modules = response.data
|
34
33
|
|
35
|
-
|
36
|
-
installed_modules.each do |module_val|
|
37
|
-
if module_val["display_name"].eql? name
|
38
|
-
val = name.split(":")
|
39
|
-
if version.nil?
|
40
|
-
versions = module_val["versions"].split(",").map(&:strip)
|
41
|
-
if versions.size > 1
|
42
|
-
version = Console.version_prompt(versions, "Select which module version to uninstall: ", { :add_all => true})
|
43
|
-
module_val["versions"] if version.eql? "all"
|
44
|
-
else
|
45
|
-
version = module_val["versions"]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
module_opts = {
|
50
|
-
:module_name => val[1],
|
51
|
-
:namespace => val[0],
|
52
|
-
:version => version
|
53
|
-
}
|
54
|
-
module_ref = ModuleRef.new(module_opts)
|
55
|
-
end
|
56
|
-
end
|
34
|
+
module_ref = process_module_ref(installed_modules, name, version)
|
57
35
|
end
|
58
|
-
|
36
|
+
|
59
37
|
raise Error::Usage, "Invalid module name." if module_ref.nil?
|
60
38
|
|
39
|
+
delete_versions = module_ref.version
|
40
|
+
|
61
41
|
unless args[:skip_prompt]
|
62
|
-
|
42
|
+
if delete_versions && delete_versions.is_a?(Array)
|
43
|
+
return false unless Console.prompt_yes_no("Are you sure you want to uninstall all module versions for '#{module_ref.namespace}/#{module_ref.module_name}' from the DTK Server?", :add_options => true)
|
44
|
+
else
|
45
|
+
return false unless Console.prompt_yes_no("Are you sure you want to uninstall module '#{module_ref.pretty_print}' from the DTK Server?", :add_options => true)
|
46
|
+
end
|
47
|
+
|
63
48
|
end
|
64
49
|
|
65
50
|
post_body = module_ref_post_body(module_ref)
|
66
|
-
post_body.merge!(:versions => versions) if versions
|
67
|
-
|
68
51
|
rest_post("#{BaseRoute}/delete", post_body)
|
69
|
-
|
52
|
+
|
53
|
+
error_msg =
|
54
|
+
if delete_versions && delete_versions.is_a?(Array) && delete_versions.size > 1
|
55
|
+
"All versions of dtk module '#{module_ref.namespace}/#{module_ref.module_name}' have been uninstalled."
|
56
|
+
else
|
57
|
+
"DTK module '#{module_ref.pretty_print}' has been uninstalled successfully."
|
58
|
+
end
|
59
|
+
|
60
|
+
OsUtil.print_info(error_msg)
|
70
61
|
nil
|
71
62
|
end
|
72
63
|
end
|
64
|
+
|
65
|
+
def self.process_module_ref(installed_modules, name, version)
|
66
|
+
name.gsub!('/', ':')
|
67
|
+
module_ref = nil
|
68
|
+
|
69
|
+
installed_modules.each do |module_val|
|
70
|
+
if module_val["display_name"].eql? name
|
71
|
+
val = name.split(":")
|
72
|
+
if version.nil?
|
73
|
+
versions = module_val["versions"].split(",").map(&:strip)
|
74
|
+
versions.each { |value| value.tr!('*', '') }
|
75
|
+
|
76
|
+
if versions.size > 1
|
77
|
+
version = Console.version_prompt(versions, "Select which module version to uninstall: ", { :add_all => true})
|
78
|
+
version = versions if version.eql? "all"
|
79
|
+
else
|
80
|
+
version = module_val["versions"]
|
81
|
+
version.tr!('*', '') if version.include?('*')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
module_opts = {
|
86
|
+
:module_name => val[1],
|
87
|
+
:namespace => val[0],
|
88
|
+
:version => version
|
89
|
+
}
|
90
|
+
|
91
|
+
module_ref = ModuleRef.new(module_opts)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
module_ref
|
96
|
+
end
|
73
97
|
|
74
98
|
end
|
75
99
|
end
|
@@ -29,7 +29,7 @@ module DTK::Client
|
|
29
29
|
)
|
30
30
|
|
31
31
|
error_msg = "To allow converge to go through, invoke 'dtk push' to push the changes to server before invoking converge again"
|
32
|
-
GitRepo.modified_with_diff?(module_dir, { :error_msg => error_msg }) unless force
|
32
|
+
GitRepo.modified_with_diff?(module_dir, { :error_msg => error_msg, :command => 'converge' }) unless force
|
33
33
|
violations = find_violations(service_instance)
|
34
34
|
return violations if violations
|
35
35
|
|
@@ -30,14 +30,25 @@ module DTK::Client
|
|
30
30
|
end
|
31
31
|
|
32
32
|
error_msg = "To allow delete to go through, invoke 'dtk push' to push the changes to server before invoking delete again"
|
33
|
-
GitRepo.modified_with_diff?(directory_path || @module_ref.client_dir_path, { :error_msg => error_msg }) unless force
|
33
|
+
GitRepo.modified_with_diff?(directory_path || @module_ref.client_dir_path, { :error_msg => error_msg, :command => 'delete' }) unless force
|
34
34
|
post_body = PostBody.new(
|
35
35
|
:service_instance => service_instance,
|
36
36
|
:recursive? => recursive
|
37
37
|
)
|
38
|
-
rest_post("#{BaseRoute}/delete", post_body)
|
38
|
+
response = rest_post("#{BaseRoute}/delete", post_body)
|
39
39
|
|
40
40
|
OsUtil.print_info("Delete procedure started. For more information use 'dtk task-status'.")
|
41
|
+
display_node_info(response.data)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.display_node_info(nodes, message = '')
|
46
|
+
if nodes.size > 0
|
47
|
+
nodes.each do |node|
|
48
|
+
return if node['admin_op_status'] == 'pending' || node['external_ref']["instance_id"].nil?
|
49
|
+
message += "#{node["display_name"]} - #{ node["external_ref"]["instance_id"]}\n" unless node["display_name"].eql?("node") && node["dtk_client_type"].eql?("node_group")
|
50
|
+
end
|
51
|
+
OsUtil.print("Nodes that will be deleted: \n" + message)
|
41
52
|
end
|
42
53
|
end
|
43
54
|
|
@@ -35,8 +35,8 @@ module DTK::Client
|
|
35
35
|
end
|
36
36
|
|
37
37
|
error_msg = "To allow #{args[:command]} to go through, invoke 'dtk push' to push the changes to server before invoking #{args[:command]} again"
|
38
|
-
GitRepo.modified_with_diff?(directory_path, { :error_msg => error_msg })
|
39
|
-
|
38
|
+
GitRepo.modified_with_diff?(directory_path, { :error_msg => error_msg, :command => 'exec'})
|
39
|
+
|
40
40
|
post_body = PostBody.new(
|
41
41
|
:task_params? => task_params
|
42
42
|
)
|
@@ -22,7 +22,9 @@ module DTK::Client
|
|
22
22
|
wrap_operation(args) do |args|
|
23
23
|
service_instance = args.required(:service_instance)
|
24
24
|
recursive = args.required(:recursive)
|
25
|
-
delete
|
25
|
+
delete = args.required(:delete)
|
26
|
+
path = args[:directory_path]
|
27
|
+
node = []
|
26
28
|
|
27
29
|
unless args[:skip_prompt]
|
28
30
|
return false unless Console.prompt_yes_no("Are you sure you want to uninstall the infrastructure associated with '#{service_instance}' and delete this service instance from the server?", :add_options => true)
|
@@ -30,19 +32,20 @@ module DTK::Client
|
|
30
32
|
|
31
33
|
post_body = PostBody.new(
|
32
34
|
:service_instance => service_instance,
|
33
|
-
:recursive?
|
35
|
+
:recursive? => recursive,
|
34
36
|
:delete => delete
|
35
37
|
)
|
36
|
-
rest_post("#{BaseRoute}/uninstall", post_body)
|
38
|
+
response = rest_post("#{BaseRoute}/uninstall", post_body)
|
37
39
|
|
38
|
-
ClientModuleDir.rm_f(
|
40
|
+
ClientModuleDir.rm_f(path) if args[:purge]
|
39
41
|
|
40
|
-
|
42
|
+
info = "DTK module '#{service_instance}' has been uninstalled successfully."
|
43
|
+
OsUtil.print_info(info)
|
44
|
+
Delete.display_node_info(response.data) if delete
|
41
45
|
end
|
42
46
|
end
|
43
47
|
|
48
|
+
|
44
49
|
end
|
45
50
|
end
|
46
|
-
end
|
47
|
-
|
48
|
-
|
51
|
+
end
|
@@ -45,6 +45,7 @@ module DTK::Client
|
|
45
45
|
@evaluated_data = []
|
46
46
|
@error_data = []
|
47
47
|
@action_data = []
|
48
|
+
@footnote = nil
|
48
49
|
end
|
49
50
|
private :initialize
|
50
51
|
|
@@ -61,6 +62,7 @@ module DTK::Client
|
|
61
62
|
data = [data] unless data.kind_of?(Array)
|
62
63
|
|
63
64
|
print_error_table = opts[:print_error_table]
|
65
|
+
@footnote = opts[:footnote]
|
64
66
|
|
65
67
|
|
66
68
|
data.each do |data_element|
|
@@ -158,6 +160,11 @@ module DTK::Client
|
|
158
160
|
printed << message
|
159
161
|
end
|
160
162
|
end
|
163
|
+
|
164
|
+
if @footnote
|
165
|
+
printf " \n"
|
166
|
+
printf "%15s %s\n", "INFO:".colorize(:yellow), @footnote.colorize(:yellow)
|
167
|
+
end
|
161
168
|
end
|
162
169
|
|
163
170
|
|
data/lib/client/render.rb
CHANGED
@@ -25,6 +25,7 @@ module DTK::Client
|
|
25
25
|
@semantic_datatype = nil
|
26
26
|
@skip_render = false
|
27
27
|
@render_type = Render::Type::DEFAULT
|
28
|
+
@footnote = nil
|
28
29
|
end
|
29
30
|
private :render_attributes_init!
|
30
31
|
|
@@ -36,12 +37,13 @@ module DTK::Client
|
|
36
37
|
render_opts = {
|
37
38
|
:render_type => @render_type,
|
38
39
|
:semantic_datatype => @semantic_datatype,
|
39
|
-
:print_error_table => @print_error_table
|
40
|
+
:print_error_table => @print_error_table,
|
41
|
+
:footnote => @footnote
|
40
42
|
}
|
41
43
|
Render.render(data, render_opts)
|
42
44
|
end
|
43
45
|
|
44
|
-
def set_render_as_table!(semantic_datatype = nil)
|
46
|
+
def set_render_as_table!(semantic_datatype = nil, footnote = nil)
|
45
47
|
return self unless ok?
|
46
48
|
|
47
49
|
unless semantic_datatype ||= semantic_datatype_in_payload
|
@@ -53,6 +55,7 @@ module DTK::Client
|
|
53
55
|
end
|
54
56
|
@semantic_datatype = normalize_semantic_datatype(semantic_datatype)
|
55
57
|
@render_type = Render::Type::TABLE
|
58
|
+
@footnote = footnote
|
56
59
|
self
|
57
60
|
end
|
58
61
|
|
@@ -44,7 +44,7 @@ module DTK::Client
|
|
44
44
|
|
45
45
|
def component_dsl_path
|
46
46
|
matches = directory_file_paths.select { |path| component_dsl_input_files_processor.match?(path) }
|
47
|
-
raise Error, "Unexpected that there is not a unique component dsl file" if matches.size != 1
|
47
|
+
raise Error::MissingDslFile, "Unexpected that there is not a unique component dsl file" if matches.size != 1
|
48
48
|
matches.first
|
49
49
|
end
|
50
50
|
|
data/lib/client/util/os_util.rb
CHANGED
@@ -96,6 +96,31 @@ module DTK::Client
|
|
96
96
|
nil
|
97
97
|
end
|
98
98
|
|
99
|
+
def self.gem_list
|
100
|
+
`gem list`.split("\n")
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.gem_names_versions_hash
|
104
|
+
name_version_hash = {}
|
105
|
+
gem_list.each do |gem|
|
106
|
+
if gem_match = gem.match(/(^.*)\((.*)\)/)
|
107
|
+
name = gem_match[1].strip
|
108
|
+
versions = (gem_match[2]||'').split(',')
|
109
|
+
name_version_hash.merge!(name => versions)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
name_version_hash
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.gem_installed?(gem_name, gem_version = nil)
|
116
|
+
gems_hash = gem_names_versions_hash
|
117
|
+
if gem_version
|
118
|
+
(gems_hash[gem_name]||[]).include?(gem_version)
|
119
|
+
else
|
120
|
+
gems_hash.keys.include?(gem_name)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
99
124
|
private
|
100
125
|
|
101
126
|
def self.genv(name)
|
@@ -0,0 +1,180 @@
|
|
1
|
+
module DTK::Puppet
|
2
|
+
class ParseStructure < Hash
|
3
|
+
def initialize(ast_item = nil, _opts = {})
|
4
|
+
return super() if ast_item.nil?
|
5
|
+
end
|
6
|
+
|
7
|
+
#### used in generate_meta
|
8
|
+
def config_agent_type
|
9
|
+
:puppet
|
10
|
+
end
|
11
|
+
|
12
|
+
def render_hash_form(module_name)
|
13
|
+
rendered_hash = {}
|
14
|
+
|
15
|
+
self[:children].each do |child|
|
16
|
+
name = child['name'].gsub("#{module_name}::", '')
|
17
|
+
type = child['type']
|
18
|
+
type_name = child['name']
|
19
|
+
attributes = nil
|
20
|
+
|
21
|
+
attributes = process_attributes(child['attributes']) if child['attributes']
|
22
|
+
actions = calculate_action(type, type_name)
|
23
|
+
|
24
|
+
child_name = name.gsub('::', '_')
|
25
|
+
child_hash = { child_name => {} }
|
26
|
+
|
27
|
+
child_hash[child_name].merge!('attributes' => attributes) if attributes
|
28
|
+
child_hash[child_name].merge!('actions' => actions)
|
29
|
+
|
30
|
+
rendered_hash.merge!(child_hash)
|
31
|
+
end
|
32
|
+
|
33
|
+
rendered_hash
|
34
|
+
end
|
35
|
+
|
36
|
+
def process_attributes(attributes)
|
37
|
+
processed_atttibutes = {}
|
38
|
+
attributes.each do |attr|
|
39
|
+
attr_name = attr['name']
|
40
|
+
attr_type = attr['type']
|
41
|
+
attr_hash = { attr_name => { 'type' => attr_type } }
|
42
|
+
|
43
|
+
if required = attr['required']
|
44
|
+
attr_hash[attr_name].merge!('required' => required)
|
45
|
+
end
|
46
|
+
|
47
|
+
processed_atttibutes.merge!(attr_hash)
|
48
|
+
end
|
49
|
+
|
50
|
+
processed_atttibutes
|
51
|
+
end
|
52
|
+
|
53
|
+
def remove_quotations(str)
|
54
|
+
if str.starts_with?('"')
|
55
|
+
str = str.slice(1..-1)
|
56
|
+
end
|
57
|
+
if str.ends_with?('"')
|
58
|
+
str = str.slice(0..-2)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def calculate_action(type, type_name)
|
63
|
+
{ 'create' => { "puppet_#{type}" => type_name } }
|
64
|
+
end
|
65
|
+
|
66
|
+
def string_to_boolean(string)
|
67
|
+
if string.to_s == 'true'
|
68
|
+
true
|
69
|
+
elsif string.to_s == 'false'
|
70
|
+
false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.create(ast_obj, opts = {})
|
75
|
+
new(ast_obj, opts)
|
76
|
+
end
|
77
|
+
|
78
|
+
TPS = [:hostclass, :definition]
|
79
|
+
class TopPS < self
|
80
|
+
def initialize(ast_array = nil, opts = {})
|
81
|
+
self[:children] = []
|
82
|
+
add_children(ast_array, opts)
|
83
|
+
super
|
84
|
+
end
|
85
|
+
|
86
|
+
def add_children(ast_array, opts = {})
|
87
|
+
return unless ast_array
|
88
|
+
|
89
|
+
ast_array.instantiate('').each do |ast_item|
|
90
|
+
ast_item_type = ast_item.type
|
91
|
+
child =
|
92
|
+
if TPS.include?(ast_item_type)
|
93
|
+
ComponentPS.create(ast_item, opts)
|
94
|
+
else
|
95
|
+
fail DTK::Client::Error.new("Unexpected top level ast type (#{ast_item.class})")
|
96
|
+
end
|
97
|
+
self[:children] << child if child
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class ComponentPS < self
|
103
|
+
def initialize(ast_item, opts = {})
|
104
|
+
ast_item_type = ast_item.type
|
105
|
+
type =
|
106
|
+
case ast_item_type
|
107
|
+
when :hostclass
|
108
|
+
'class'
|
109
|
+
when :definition
|
110
|
+
'definition'
|
111
|
+
else
|
112
|
+
fail DTK::Client::Error.new('unexpected type for ast_item')
|
113
|
+
end
|
114
|
+
|
115
|
+
self['type'] = type
|
116
|
+
self['name'] = ast_item.name
|
117
|
+
attributes = []
|
118
|
+
|
119
|
+
attributes << AttributePS.create_name_attribute if ast_item_type == :definition
|
120
|
+
(ast_item.arguments || []).each { |arg| attributes << AttributePS.create(arg, opts) }
|
121
|
+
|
122
|
+
self['attributes'] = attributes unless attributes.empty?
|
123
|
+
super
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
AttrTypes = {
|
128
|
+
Puppet::Pops::Model::LiteralHash => 'hash',
|
129
|
+
Puppet::Pops::Model::VariableExpression => 'string',
|
130
|
+
Puppet::Pops::Model::LiteralUndef => 'string',
|
131
|
+
Puppet::Pops::Model::LiteralBoolean => 'boolean',
|
132
|
+
Puppet::Pops::Model::LiteralString => 'string',
|
133
|
+
Puppet::Pops::Model::LiteralInteger => 'integer',
|
134
|
+
Puppet::Pops::Model::LiteralList => 'array',
|
135
|
+
Puppet::Pops::Model::ConcatenatedString => 'string',
|
136
|
+
Puppet::Pops::Model::QualifiedName => 'string'
|
137
|
+
}
|
138
|
+
class AttributePS < self
|
139
|
+
def initialize(arg, opts = {})
|
140
|
+
self['name'] = arg[0]
|
141
|
+
|
142
|
+
if arg_1 = arg[1]
|
143
|
+
self['type'] = type?(arg_1)
|
144
|
+
self['required'] = opts[:required] if opts.key?(:required)
|
145
|
+
|
146
|
+
unless def_value(arg_1)
|
147
|
+
self['required'] ||= true
|
148
|
+
end
|
149
|
+
else
|
150
|
+
self['type'] = 'string'
|
151
|
+
self['required'] = true
|
152
|
+
end
|
153
|
+
|
154
|
+
super
|
155
|
+
end
|
156
|
+
|
157
|
+
def type?(arg)
|
158
|
+
if arg_value = arg.value
|
159
|
+
AttrTypes[arg_value.class] || 'string'
|
160
|
+
else
|
161
|
+
'string'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def def_value(default_ast_obj)
|
166
|
+
# if arg_value = default_ast_obj.value
|
167
|
+
# default_ast_obj.source_text unless IgnoreValues.include?(arg_value.class)
|
168
|
+
# else
|
169
|
+
default_ast_obj.source_text
|
170
|
+
# end
|
171
|
+
end
|
172
|
+
# IgnoreValues = [Puppet::Pops::Model::VariableExpression]
|
173
|
+
|
174
|
+
def self.create_name_attribute
|
175
|
+
new(['name'], 'required' => true)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2010-2016 dtk contributors
|
3
|
+
#
|
4
|
+
# This file is part of the dtk project.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
module DTK
|
19
|
+
module Puppet
|
20
|
+
class Parser
|
21
|
+
def self.parse(argv)
|
22
|
+
parse_puppet_module_directory
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.parse_puppet_module_directory
|
26
|
+
current_dir = Client::OsUtil.current_dir
|
27
|
+
dir_content = Dir.glob("#{current_dir}/**/*")
|
28
|
+
|
29
|
+
if module_yaml_file = dir_content.find { |path| path =~ /dtk.module.yaml$/ }
|
30
|
+
fail DTK::Client::Error::Usage.new("Dtk module file 'dtk.module.yaml' exists already. Please delete it first and execute puppet scaffolding again.")
|
31
|
+
end
|
32
|
+
|
33
|
+
metadata_file = dir_content.find { |path| path =~ /metadata.json$/ }
|
34
|
+
file_content = File.read(metadata_file)
|
35
|
+
metadata_hash = JSON.parse(file_content)
|
36
|
+
|
37
|
+
full_module_name = metadata_hash['name'].gsub('-', '/')
|
38
|
+
module_version = metadata_hash['version']
|
39
|
+
dependencies = process_metadata_dependencies(metadata_hash['dependencies'])
|
40
|
+
|
41
|
+
module_hash = {
|
42
|
+
'module' => full_module_name,
|
43
|
+
'version' => module_version
|
44
|
+
}
|
45
|
+
module_hash.merge!('dependencies' => dependencies) unless dependencies.empty?
|
46
|
+
|
47
|
+
all_files = dir_content.select { |path| path =~ /manifests.+\.pp$/ }
|
48
|
+
if all_files.empty?
|
49
|
+
all_files = dir_content.select { |path| path =~ /puppet\/manifests.+\.pp$/ }
|
50
|
+
end
|
51
|
+
|
52
|
+
namespace, module_name = full_module_name.split('/')
|
53
|
+
|
54
|
+
component_defs = process_manifest_files(all_files, module_name)
|
55
|
+
module_hash['component_defs'] = component_defs
|
56
|
+
|
57
|
+
File.open("#{current_dir}/dtk.module.yaml", 'wb') { |file| file.write(module_hash.to_yaml) }
|
58
|
+
DTK::Client::OsUtil.print_info("'dtk.module.yaml' file has been created successfully.")
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.process_manifest_files(files, module_name)
|
62
|
+
ret = ParseStructure::TopPS.new()
|
63
|
+
parser = ::Puppet::Parser::ParserFactory.parser
|
64
|
+
|
65
|
+
files.each do |file|
|
66
|
+
parser.file = file
|
67
|
+
initial_import = parser.parse
|
68
|
+
|
69
|
+
known_resource_types = ::Puppet::Resource::TypeCollection.new('production')
|
70
|
+
known_resource_types.import_ast(initial_import, '')
|
71
|
+
krt_code = known_resource_types.hostclass('').code
|
72
|
+
|
73
|
+
ret.add_children(krt_code)
|
74
|
+
end
|
75
|
+
|
76
|
+
ret.render_hash_form(module_name)
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.process_metadata_dependencies(dependencies)
|
80
|
+
dependency_hash = {}
|
81
|
+
|
82
|
+
if dependencies
|
83
|
+
dependencies.each do |dependency|
|
84
|
+
dependency_hash.merge!(dependency['name'] => 'master')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
dependency_hash
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/dtk_puppet.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2010-2016 dtk contributors
|
3
|
+
#
|
4
|
+
# This file is part of the dtk project.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
module DTK
|
19
|
+
module Puppet
|
20
|
+
require_relative('dtk_puppet/parser')
|
21
|
+
require_relative('dtk_puppet/parse_structure')
|
22
|
+
require_relative('client/error')
|
23
|
+
end
|
24
|
+
end
|