tefoji 1.0.8 → 1.0.9
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 +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 +2 -2
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
|