tefoji 1.0.7 → 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mixins/logging.rb +1 -1
- data/lib/mixins/user_functions.rb +3 -3
- data/lib/tefoji/cli.rb +1 -1
- data/lib/tefoji/jira_api.rb +8 -5
- data/lib/tefoji.rb +129 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8279bb8ebda1af1e674da5c4d16932b790e69210a5c163563746a80d44aca92b
|
4
|
+
data.tar.gz: f17bbc221ed1ec7c4fde90d2e64caddb45078ee0ee2d5cb59e7226d90df14317
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d790551fe749db5eea41ce6889479c3f23e8278ad94744b8be4561d0cceadb33b609949c612224e49bbc21587b8b3cf50501a6eeef1e2d3059c860420e583c15
|
7
|
+
data.tar.gz: a0b4bd8875027f141a87f2bc960c43143813500db372e0764df428896fc04f34fd3f5b91d3a4d4ca305e9949b88dd3329f4363a1981905f6b4b7d7fe6c7b9fe9
|
data/lib/mixins/logging.rb
CHANGED
@@ -48,7 +48,7 @@ module UserFunctions
|
|
48
48
|
MODULES: 'MODULES',
|
49
49
|
MODULES_INTERNAL: 'FM',
|
50
50
|
OPERATIONS: 'OPS',
|
51
|
-
PDK: '
|
51
|
+
PDK: 'CONT',
|
52
52
|
PE_INTERNAL: 'PE',
|
53
53
|
PROJECT_CENTRAL: 'PC',
|
54
54
|
PUPPETDB: 'PDB',
|
@@ -89,12 +89,12 @@ module UserFunctions
|
|
89
89
|
CD4PE: 'CD4PE',
|
90
90
|
CODE_MANAGEMENT: 'Dumpling',
|
91
91
|
DUMPLING: 'Dumpling',
|
92
|
-
FACTER:
|
92
|
+
FACTER: 'Phoenix',
|
93
93
|
INSTALLER: 'Installer and Management',
|
94
94
|
NETWORKING: 'Network Automation',
|
95
95
|
OPERATIONS: 'Operations',
|
96
96
|
PE: 'Dumpling',
|
97
|
-
PLATFORM_OS:
|
97
|
+
PLATFORM_OS: 'Phoenix',
|
98
98
|
PUPPETDB: 'Dumpling',
|
99
99
|
PUPPETSERVER: 'Dumpling',
|
100
100
|
QE: 'Quality Engineering',
|
data/lib/tefoji/cli.rb
CHANGED
data/lib/tefoji/jira_api.rb
CHANGED
@@ -75,14 +75,15 @@ module Tefoji
|
|
75
75
|
# Do this so we can inform the user quickly that their credentials didn't work
|
76
76
|
# There may be a better test, but this is the one the original Winston uses
|
77
77
|
def test_authentication
|
78
|
-
get_username
|
78
|
+
get_username(@jira_username)
|
79
79
|
rescue RestClient::Forbidden
|
80
80
|
fatal 'Forbidden: either the authentication is incorrect or ' \
|
81
81
|
'Jira might be requiring a CAPTCHA response from the web interface.'
|
82
82
|
end
|
83
83
|
|
84
|
-
|
85
|
-
|
84
|
+
# Get information about user in Jira
|
85
|
+
def get_username(username, fail_if_not_found = true)
|
86
|
+
jira_get("user?username=#{username}", fail_if_not_found)
|
86
87
|
end
|
87
88
|
|
88
89
|
# Save authentication YAML to the a file for reuse.
|
@@ -167,7 +168,7 @@ module Tefoji
|
|
167
168
|
|
168
169
|
private
|
169
170
|
|
170
|
-
def jira_get(jira_request_path)
|
171
|
+
def jira_get(jira_request_path, fail_if_not_found = true)
|
171
172
|
# Jira likes to send complete URLs for responses. Handle
|
172
173
|
# the case where we've received a 'self' query from Jira with
|
173
174
|
# fully formed url
|
@@ -191,7 +192,9 @@ module Tefoji
|
|
191
192
|
rescue RestClient::NotFound,
|
192
193
|
SocketError,
|
193
194
|
Errno::ECONNREFUSED => e
|
194
|
-
|
195
|
+
# Return False if not found rather than fail to allow for checking the existence of users.
|
196
|
+
fatal "Cannot connect to #{@jira_base_rest_url}: #{e.message}" if fail_if_not_found
|
197
|
+
return false
|
195
198
|
end
|
196
199
|
|
197
200
|
return JSON.parse(response.body)
|
data/lib/tefoji.rb
CHANGED
@@ -74,6 +74,8 @@ module Tefoji
|
|
74
74
|
resolve_variables(main_template_data['declare'])
|
75
75
|
@logger.debug "Declarations: #{@declarations}"
|
76
76
|
|
77
|
+
check_assignees(main_template_data)
|
78
|
+
|
77
79
|
# Process 'before' templates
|
78
80
|
main_template.dig(:includes, :before)&.each do |before|
|
79
81
|
default_epic_saved = @default_target_epic
|
@@ -641,12 +643,17 @@ module Tefoji
|
|
641
643
|
def user_function_call(function_definition)
|
642
644
|
@logger.debug "function_definition is: #{function_definition}"
|
643
645
|
function_name = function_definition['name']
|
644
|
-
|
645
|
-
|
646
|
+
argument = function_definition['argument']
|
647
|
+
arguments = function_definition['arguments']
|
648
|
+
|
649
|
+
if argument.is_a?(Array) || arguments.is_a?(Array)
|
650
|
+
arguments = argument || function_definition['arguments']
|
651
|
+
function_arguments = arguments.map do |a|
|
646
652
|
expand_right_value(a).value
|
647
653
|
end
|
648
|
-
elsif
|
649
|
-
|
654
|
+
elsif argument.is_a?(String) || arguments.is_a?(String)
|
655
|
+
argument = function_definition['argument'] || function_definition['arguments']
|
656
|
+
function_arguments = [expand_right_value(argument).value]
|
650
657
|
else
|
651
658
|
fatal("No arguments supplied to function \"#{function_name}\"")
|
652
659
|
end
|
@@ -814,6 +821,124 @@ module Tefoji
|
|
814
821
|
return true
|
815
822
|
end
|
816
823
|
|
824
|
+
# Iterates through the assignees in a template and checks if they exist on jira. If any assignee in
|
825
|
+
# the template does not exist, it will fail, outputting a message saying which users failed and
|
826
|
+
# what epics/issues they are associated with.
|
827
|
+
# NOTE: This check does not guarantee a user is assignable, so there may be cases when a user passes
|
828
|
+
# the check but still fails when being assigned a ticket/epic. If we find a reasonable way to
|
829
|
+
# check assignability prior to the epic/issue being created, we should implement it in place of
|
830
|
+
# using the get_username method.
|
831
|
+
def check_assignees(main_template_data)
|
832
|
+
valid_users = []
|
833
|
+
|
834
|
+
invalid_users_to_features = {}
|
835
|
+
main_template_data['features']&.each do |feature|
|
836
|
+
next unless feature['assignee']
|
837
|
+
|
838
|
+
assignee_username = get_username_from_assignee(feature['assignee'])
|
839
|
+
next if valid_users.include?(assignee_username)
|
840
|
+
|
841
|
+
update_user_validity(assignee_username, feature['summary'], valid_users, invalid_users_to_features)
|
842
|
+
end
|
843
|
+
|
844
|
+
if main_template_data.dig('feature', 'assignee')
|
845
|
+
assignee_username = get_username_from_assignee(main_template_data['feature']['assignee'])
|
846
|
+
unless valid_users.include?(assignee_username)
|
847
|
+
update_user_validity(assignee_username, main_template_data['feature']['summary'], valid_users,
|
848
|
+
invalid_users_to_features)
|
849
|
+
end
|
850
|
+
end
|
851
|
+
|
852
|
+
invalid_users_to_epics = {}
|
853
|
+
main_template_data['epics']&.each do |epic|
|
854
|
+
next unless epic['assignee']
|
855
|
+
|
856
|
+
assignee_username = get_username_from_assignee(epic['assignee'])
|
857
|
+
next if valid_users.include?(assignee_username)
|
858
|
+
|
859
|
+
update_user_validity(assignee_username, epic['summary'], valid_users, invalid_users_to_epics)
|
860
|
+
end
|
861
|
+
|
862
|
+
if main_template_data.dig('epic', 'assignee')
|
863
|
+
assignee_username = get_username_from_assignee(main_template_data['epic']['assignee'])
|
864
|
+
unless valid_users.include?(assignee_username)
|
865
|
+
update_user_validity(assignee_username, main_template_data['epic']['summary'], valid_users,
|
866
|
+
invalid_users_to_epics)
|
867
|
+
end
|
868
|
+
end
|
869
|
+
|
870
|
+
invalid_users_to_issue_defaults = {}
|
871
|
+
if main_template_data.dig('issue_defaults', 'assignee')
|
872
|
+
assignee_username = get_username_from_assignee(main_template_data['issue_defaults']['assignee'])
|
873
|
+
unless valid_users.include?(assignee_username)
|
874
|
+
update_user_validity(assignee_username, 'issue_defaults', valid_users, invalid_users_to_issue_defaults)
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
invalid_users_to_issues = {}
|
879
|
+
main_template_data['issues'].each do |issue|
|
880
|
+
next unless issue['assignee']
|
881
|
+
|
882
|
+
assignee_username = get_username_from_assignee(issue['assignee'])
|
883
|
+
next if valid_users.include?(assignee_username)
|
884
|
+
|
885
|
+
update_user_validity(assignee_username, issue['summary'], valid_users, invalid_users_to_issues)
|
886
|
+
end
|
887
|
+
unless invalid_users_to_features.empty? &&
|
888
|
+
invalid_users_to_epics.empty? &&
|
889
|
+
invalid_users_to_issue_defaults.empty? &&
|
890
|
+
invalid_users_to_issues.empty?
|
891
|
+
invalid_user_message = "Invalid assignees:\n"
|
892
|
+
end
|
893
|
+
unless invalid_users_to_features.empty?
|
894
|
+
invalid_users_to_features.each do |assignee, feature|
|
895
|
+
invalid_user_message += "Assignee #{assignee} associated with features #{feature}\n"
|
896
|
+
end
|
897
|
+
end
|
898
|
+
unless invalid_users_to_epics.empty?
|
899
|
+
invalid_users_to_epics.each do |assignee, epic|
|
900
|
+
invalid_user_message += "Assignee #{assignee} associated with epics #{epic}\n"
|
901
|
+
end
|
902
|
+
end
|
903
|
+
unless invalid_users_to_issue_defaults.empty?
|
904
|
+
invalid_users_to_issue_defaults.each do |assignee, _|
|
905
|
+
invalid_user_message += "Assignee #{assignee} associated with issue_defaults\n"
|
906
|
+
end
|
907
|
+
end
|
908
|
+
unless invalid_users_to_issues.empty?
|
909
|
+
invalid_users_to_issues.each do |assignee, issues|
|
910
|
+
invalid_user_message += "Assignee #{assignee} associated with issues #{issues}\n"
|
911
|
+
end
|
912
|
+
end
|
913
|
+
fatal invalid_user_message if invalid_user_message
|
914
|
+
end
|
915
|
+
|
916
|
+
def get_username_from_assignee(assignee)
|
917
|
+
# Assignee is a variable or direct input
|
918
|
+
username = expand_string(assignee) if assignee.is_a?(String)
|
919
|
+
# Assignee is a function
|
920
|
+
if assignee.is_a?(Hash) && assignee.key?('function')
|
921
|
+
username = user_function_call(assignee['function'])
|
922
|
+
end
|
923
|
+
|
924
|
+
unless username
|
925
|
+
fatal "invalid assignee format for issue: #{issue['short_name']} failed: must be a function or a string"
|
926
|
+
end
|
927
|
+
|
928
|
+
username = username.value unless username.is_a?(String)
|
929
|
+
username
|
930
|
+
end
|
931
|
+
|
932
|
+
def update_user_validity(username, issue_name, valid_users, invalid_users)
|
933
|
+
if invalid_users.key?(username)
|
934
|
+
invalid_users[username] += [issue_name]
|
935
|
+
elsif @jira_api.get_username(username, false)
|
936
|
+
valid_users << username
|
937
|
+
else
|
938
|
+
invalid_users[username] = invalid_users.fetch(username, []) + [issue_name]
|
939
|
+
end
|
940
|
+
end
|
941
|
+
|
817
942
|
def logger_initialize(log_location)
|
818
943
|
logger = Logger.new(log_location, progname: 'tefoji', level: @log_level)
|
819
944
|
logger.formatter = proc do |severity, _, script_name, message|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tefoji
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet Labs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry-byebug
|
@@ -203,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
203
203
|
- !ruby/object:Gem::Version
|
204
204
|
version: '0'
|
205
205
|
requirements: []
|
206
|
-
rubygems_version: 3.
|
206
|
+
rubygems_version: 3.0.3
|
207
207
|
signing_key:
|
208
208
|
specification_version: 4
|
209
209
|
summary: Generate Jira issues from a YAML specification.
|