1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
require 'base64'
require_relative '../http_helper'
module Action
class Custom
include HTTPHelper
class BaseError < StandardError; end
class MissingPayloadError < BaseError; end
class MissingAPIEndpointsError < BaseError; end
class MissingDataError < BaseError; end
class UnsuccessfulError < BaseError; end
NO_MESSAGE_TEXT = 'No message'.freeze
DEFAULT_HEADERS = { 'Content-Type' => CONTENT_TYPE_JSON }.freeze
def initialize(gl_id, payload)
@gl_id = gl_id
@payload = payload
end
def execute
validate!
inform_client(info_message) if info_message
process_api_endpoints!
end
private
attr_reader :gl_id, :payload
def process_api_endpoints!
output = ''
resp = nil
data_with_gl_id = data.merge('gl_id' => gl_id)
api_endpoints.each do |endpoint|
url = "#{base_url}#{endpoint}"
json = { 'data' => data_with_gl_id, 'output' => output }
resp = post(url, {}, headers: DEFAULT_HEADERS, options: { json: json })
# Net::HTTPSuccess is the parent of Net::HTTPOK, Net::HTTPCreated etc.
case resp
when Net::HTTPSuccess, Net::HTTPMultipleChoices
true
else
raise_unsuccessful!(resp)
end
begin
body = JSON.parse(resp.body)
rescue JSON::ParserError
raise UnsuccessfulError, 'Response was not valid JSON'
end
print_flush(body['result'])
# In the context of the git push sequence of events, it's necessary to read
# stdin in order to capture output to pass onto subsequent commands
output = read_stdin
end
resp
end
def base_url
config.gitlab_url
end
def data
@data ||= payload['data']
end
def api_endpoints
data['api_endpoints']
end
def info_message
data['info_message']
end
def config
@config ||= GitlabConfig.new
end
def api
@api ||= GitlabNet.new
end
def read_stdin
Base64.encode64($stdin.read)
end
def print_flush(str)
return false unless str
$stdout.print(Base64.decode64(str))
$stdout.flush
end
def inform_client(str)
$stderr.puts(format_gitlab_output(str))
end
def format_gitlab_output(str)
str.split("\n").map { |line| "> GitLab: #{line}" }.join("\n")
end
def validate!
validate_payload!
validate_data!
validate_api_endpoints!
end
def validate_payload!
raise MissingPayloadError if !payload.is_a?(Hash) || payload.empty?
end
def validate_data!
raise MissingDataError unless data.is_a?(Hash)
end
def validate_api_endpoints!
raise MissingAPIEndpointsError if !api_endpoints.is_a?(Array) ||
api_endpoints.empty?
end
def raise_unsuccessful!(result)
message = "#{exception_message_for(result.body)} (#{result.code})"
raise UnsuccessfulError, format_gitlab_output(message)
end
def exception_message_for(body)
body = JSON.parse(body)
return body['message'] unless body['message'].to_s.empty?
body['result'].to_s.empty? ? NO_MESSAGE_TEXT : Base64.decode64(body['result'])
rescue JSON::ParserError
NO_MESSAGE_TEXT
end
end
end
|