#!/usr/bin/ruby
module OpenSecret
# This Jenkins use case handles the to and fro integration of secrets and sensitive information # between the safe database under management and a Jenkins service pinpointed by an incoming # host url parameter. # # This Jenkins use case injects for example the AWS IAM user access key, secret key and region key # into a running Jenkins CI (Continuous Integration) service at the specified (url) location. # # safe jenkins post <<[ aws | docker | git ]>> <<jenkins-host-url>> class Jenkins < UseCase attr_writer :command, :service, :url JENKINS_URL_POSTFIX = "credentials/store/system/domain/_/createCredentials" JENKINS_URL_PATH = "/credentials/store/system/domain/_/createCredentials" REQUEST_CONTENT_TYPE = 'application/json;charset=UTF-8' DATA_DICTIONARY = { "scope" => "GLOBAL", "id" => "safe.aws.region.key", "secret" => "blahblahblah", "description" => "The AWS region key for example eu-west-1 for Dublin in Ireland.", "$class" => "org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl" }
### DICTIONARY_TO_POST = { “” => “0”, “credentials” => DATA_DICTIONARY }
DICTIONARY_TO_POST = { "credentials" => DATA_DICTIONARY } def json_api_post_request_2 require 'net/http' require 'json' http = Net::HTTP.new( "localhost", "8080" )
########### service_url = File.join( @url, JENKINS_URL_POSTFIX )
request = Net::HTTP::Post.new( JENKINS_URL_PATH ) uri_encoded_json = URI::encode( DICTIONARY_TO_POST.to_json ) request.body = uri_encoded_json request.content_type = REQUEST_CONTENT_TYPE response = http.request( request )
### uri = URI.parse( “#{service_url}” ) ### req = Net::HTTP::Post.new(uri) ### req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')
### res = Net::HTTP.start(uri.hostname, uri.port) do |http| ### http.request(req) ### end
puts response.body end def json_api_post_request_1 require 'net/http' require 'json' begin service_url = File.join( @url, JENKINS_URL_POSTFIX ) puts "" puts "The service_url is #{service_url}" uri = URI( service_url ) puts "The simple URI hostname is #{uri.host}" puts "Data will be sent via the URI port numbered [#{uri.port}]" puts "The URI path string is #{uri.path}" http = Net::HTTP.new(uri.host, uri.port)
#### req = Net::HTTP::Post.new(uri.path, {'Content-Type' =>'application/json',
#### 'Authorization' => 'XXXXXXXXXXXXXXXX'})
### our_request = Net::HTTP::Post.new( uri.path, { 'Content-Type' =>'application/json' } ) ############## our_request.body = {“pizza_type” => “Margherita”, “pizza_no” => “2”}.to_json
jenkins_inner_dictionary = { "scope" => "GLOBAL", "id" => "safe.aws.region.key", "secret" => "blahblahblah", "description" => "The AWS region key for example eu-west-1 for Dublin in Ireland.", "$class" => "org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl" } jenkins_outer_dictionary = { "" => "0", "credentials" => jenkins_inner_dictionary } our_request = Net::HTTP::Post.new( uri.path ) our_request.set_form_data( jenkins_outer_dictionary.to_json )
##### our_request.set_form_data( jenkins_inner_dictionary )
#### jenkins_jason_dictionary = jenkins_outer_dictionary.to_json #### our_request.body = jenkins_jason_dictionary
## http = Net::HTTP.new(“api.restsite.com”)
## request = Net::HTTP::Post.new(“/users”) ## request.set_form_data({“users” => “quentin”}) ## response = http.request(request)
## DELETE ME ## DELETE ME ## DELETE ME
puts "The [[[ SENSITIVE ]] JSON request body is this.\n\n #{our_request.body}" puts "" res = http.request( our_request ) puts res.body
##### puts JSON.parse(res.body)
rescue => e puts "failed #{e}" end end def execute return unless ops_key_exists? master_db = get_master_database() return if unopened_envelope?( master_db ) # Get the open chapter identifier (id). # Decide whether chapter already exists. # Then get (or instantiate) the chapter's hash data structure chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ] verse_id = master_db[ KEY_PATH ] chapter_exists = OpenKey::KeyApi.db_envelope_exists?( master_db[ chapter_id ] ) # Unlock the chapter data structure by supplying # key/value mini-dictionary breadcrumbs sitting # within the master database at the section labelled # envelope@<<actual_chapter_id>>. chapter_data = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( master_db[ chapter_id ] ) ) # Now read the three AWS IAM credentials @access.key, @secret.key and region.key # into the 3 environment variables terraform expects to find. # ----------------------------------------------------------------------------------------------------- # # ----------------------------------------------------------------------------------------------------- # # -- # -- Reading material for CUrl like activities using net/http core ruby library # -- # -- ssl/https/rest => http://www.rubyinside.com/nethttp-cheat-sheet-2940.html # -- official docs => https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP.html # -- => # -- => # -- => # -- => # -- # ----------------------------------------------------------------------------------------------------- # # ----------------------------------------------------------------------------------------------------- # json_api_post_request_2 puts "" puts "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" puts "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" puts ""
begin¶ ↑
ENV[ "AWS_ACCESS_KEY_ID" ] = chapter_data[ verse_id ][ "@access.key" ] ENV[ "AWS_SECRET_ACCESS_KEY" ] = chapter_data[ verse_id ][ "@secret.key" ] ENV[ "AWS_DEFAULT_REGION" ] = chapter_data[ verse_id ][ "region.key" ] auto_approve = @command && @command.eql?( "plan" ) ? "" : "-auto-approve" command_name = @command ? @command : "apply" puts "" puts "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" puts "" system "terraform #{command_name} #{auto_approve}" puts "" puts "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" puts ""
end¶ ↑
# ############## | ############################################################ # @todo refactor | ############################################################ # -------------- | 000000000000000000000000000000000000000000000000000000000000 # export-then-execute # ------------------- # Refactor all this code into a generic export-then-execute use case # Then you pass in a Key/Value Dictionary # # { "AWS_ACCESS_KEY_ID" => "@access_key", # "AWS_SECRET_ACCESS_KEY" => "@secret_key", # "AWS_DEFAULT_REGION" => "region_key" # } # # And pass in a command array [ "terraform #{command_name} #{auto_approve}", "terraform graph ..." ] # # Validation is done by the generic use case (which loops checking that every value exists # as a key at the opened location. # # If all good the generic use case exports the ENV vars and runs each command in the list. # PS - configure map in INI not code file # # The extra power will speed up generation of environment variable use cases including # ansible, s3 bucket operations, git interactions and more. # # ############## | ############################################################ # ############## | ############################################################ end end
end