lib/terraspace_bundler/mod/registry.rb in terraspace-bundler-0.3.4 vs lib/terraspace_bundler/mod/registry.rb in terraspace-bundler-0.4.0
- old
+ new
@@ -1,16 +1,71 @@
-require 'net/http'
-require 'open-uri'
-
class TerraspaceBundler::Mod
class Registry
include TB::Util::Logging
+ include Http::Concern
def initialize(source, version)
@source, @version = source, version
end
+ def github_url
+ if @source.split('/').size > 3 # IE: app.terraform.io/demo-qa/s3-webapp/aws
+ private_github_url
+ else # assume size is 3. IE: terraform-aws-modules/security-group/aws
+ public_github_url
+ end
+ end
+
+ # https://www.terraform.io/docs/cloud/api/modules.html#get-a-module
+ # GET /organizations/:organization_name/registry-modules/:registry_name/:namespace/:name/:provider
+ # GET /organizations/demo-qa/registry-modules/private/demo-qa/s3-webapp/aws
+ #
+ # :organization_name The name of the organization the module belongs to.
+ # :namespace The namespace of the module. For private modules this is the name of the organization that owns the module.
+ # :name The module name.
+ # :provider The module provider.
+ # :registry-name Either public or private.
+ #
+ # Example: app.terraform.io/demo-qa/s3-webapp/aws
+ #
+ # domain: app.terraform.io (private registry indicator)
+ # org: demo-qa
+ # module: s3-webapp
+ # provider: aws
+ #
+ def private_github_url
+ domain, org, name, provider = @source.split('/')
+ registry_name = 'private'
+ namespace = org
+
+ base_site = "https://#{domain}" # IE: domain = 'app.terraform.io'
+ base_url = "#{base_site}/api/v2"
+ api_url = "#{base_url}/organizations/#{org}/registry-modules/#{registry_name}/#{namespace}/#{name}/#{provider}"
+
+ resp = http_request(api_url, auth_domain: domain)
+
+ repo_url = case resp.code.to_i
+ when 200
+ result = JSON.load(resp.body)
+ result['data']['attributes']['vcs-repo']['repository-http-url'] # repo_url
+ when 401
+ auth_error_exit!(resp)
+ else
+ logger.error "ERROR: Unable to lookup up module in Terraform Registry: #{@source}".color(:red)
+ puts "resp.code #{resp.code}"
+ pp resp
+ exit 1
+ end
+
+ clone_with = 'git' # TODO: make configurable
+ unless clone_with == 'https'
+ repo_url.sub!('https://github.com/', 'git@github.com:')
+ end
+
+ repo_url
+ end
+
# Terrafile example
#
# mod "sg", source: "terraform-aws-modules/security-group/aws", version: "3.10.0"
#
# Resources: https://www.terraform.io/docs/registry/api.html
@@ -25,16 +80,16 @@
# Specific version:
#
# https://registry.terraform.io/v1/modules/terraform-aws-modules/sqs/aws/download
#
# The specific version returns an 204 and then we grab the download url info form the x-terraform-get header.
- def github_url
+ def public_github_url
base_site = "https://registry.terraform.io"
base_url = "#{base_site}/v1/modules"
-
version = @version.sub(/^v/,'') if @version # v1.0 => 1.0
api_url = [base_url, @source, version, "download"].compact.join('/')
+
resp = http_request(api_url)
case resp.code.to_i
when 204
download_url = resp.header["x-terraform-get"]
@@ -42,36 +97,35 @@
next_url = "#{base_site}#{resp.header["location"]}"
resp = http_request(next_url)
download_url = resp.header["x-terraform-get"]
else
logger.error "ERROR: Unable to lookup up module in Terraform Registry: #{@source}".color(:red)
+ puts "resp.code #{resp.code}"
+ pp resp
exit 1
end
url = download_url.sub(%r{/archive/.*},'')
# IE: git::https://github.com/terraform-aws-modules/terraform-aws-security-group?ref=v3.10.0
url.sub(/^git::/,'').sub(/\?.*/,'')
end
private
- def http_request(url)
- uri = URI(url)
- http = Net::HTTP.new(uri.host, uri.port)
- http.use_ssl = uri.scheme == "https"
- # Total time will be 40s = 20 x 2
- http.max_retries = 1 # Default is already 1, just being explicit
- http.read_timeout = 20 # Sites that dont return in 20 seconds are considered down
- request = Net::HTTP::Get.new(uri)
- begin
- http.request(request) # response
- rescue Net::OpenTimeout => e # internal ELB but VPC is not configured for Lambda function
- http_request_error_message(e)
- puts "The Lambda Function does not seem to have network access to the url. It might not be configured with a VpcConfig. Please double check that the related vpc variables are configured: @subnet_ids, @vpc_id, @security_group_ingress"
- rescue Exception => e
- # Net::ReadTimeout - too slow
- # Errno::ECONNREFUSED - completely down
- # SocketError - improper url "dsfjsl" instead of example.com
- http_request_error_message(e)
+ def auth_error_exit!(resp=nil, domain=nil)
+ logger.error <<~EOL.color(:red)
+ ERROR: Unauthorized. Unable to lookup up module in Terraform Registry:
+
+ #{@source}
+
+ Try logging in with:
+
+ terraform login #{domain}
+
+ EOL
+ if resp
+ puts "resp.code #{resp.code}"
+ pp resp
end
+ exit 1
end
end
end