diff --git a/CHANGES.md b/CHANGES.md index ad0d21d47..ae13acbad 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ ---------- - Increase lower bound on OCaml to 4.08. https://github.com/inhabitedtype/ocaml-aws/pull/104 - Migrate CI to github actions https://github.com/inhabitedtype/ocaml-aws/pull/104 +- Add STS `assume_role` token support https://github.com/inhabitedtype/ocaml-aws/pull/117 1.2: (24-01-2020) ---------- diff --git a/Makefile b/Makefile index 687a8b883..1aa0e2f24 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ clean: rm -rf _build *.install fmt: - dune build @fmt --auto-promote + dune build @fmt --auto-promote || echo "format has errors, ignoring" .PHONY: endpoints @@ -26,9 +26,11 @@ endpoints: aws-ec2: dune exec aws-gen -- --is-ec2 -i input/ec2/latest/service-2.json -r input/ec2/overrides.json -e input/errors.json -o libraries +aws-autoscaling: + dune exec aws-gen -- -i input/autoscaling/latest/service-2.json -r input/autoscaling/overrides.json -e input/errors.json -o libraries --optional-libs=aws-ec2 + # NOTE: This does not include aws-ec2, which is special-cased. LIBRARIES := \ - aws-autoscaling \ aws-cloudformation \ aws-cloudtrail \ aws-cloudwatch \ @@ -45,7 +47,7 @@ LIBRARIES := \ $(LIBRARIES): aws-%: dune exec aws-gen -- -i input/$*/latest/service-2.json -r input/$*/overrides.json -e input/errors.json -o libraries -gen: build aws-ec2 $(LIBRARIES) +gen: build aws-ec2 aws-autoscaling $(LIBRARIES) fmt update-version: VERSION=$(shell cat CHANGES.md | grep -E '^[0-9]' | head -n 1 | cut -f1 -d':' ) update-version: diff --git a/async/runtime.ml b/async/runtime.ml index 748fb65ba..c35b68e01 100644 --- a/async/runtime.ml +++ b/async/runtime.ml @@ -44,6 +44,7 @@ let run_request ~region ~access_key ~secret_key + ?token (module M : Aws.Call with type input = input and type output = output @@ -55,6 +56,7 @@ let run_request Aws.Signing.sign_request ~access_key ~secret_key + ?token ~service:M.service ~region (M.to_http M.service region inp) @@ -62,6 +64,7 @@ let run_request Aws.Signing.sign_v2_request ~access_key ~secret_key + ?token ~service:M.service ~region (M.to_http M.service region inp) diff --git a/async/runtime.mli b/async/runtime.mli index 579d4c9dc..f6a4fe18a 100644 --- a/async/runtime.mli +++ b/async/runtime.mli @@ -35,7 +35,9 @@ val run_request : region:string -> access_key:string -> secret_key:string + -> ?token:string -> ('input, 'output, 'error) Aws.call -> 'input -> [ `Ok of 'output | `Error of 'error Aws.Error.t ] Async.Deferred.t -(** Run an AWS request, in the [region] with [access_key] and [secret_key]. *) +(** Run an AWS request, in the [region] with [access_key] and [secret_key]. + * An STS assume_role [token] can be optionally used to sign the request. *) diff --git a/aws-autoscaling.opam b/aws-autoscaling.opam index 3b3e5012e..f9857a1b7 100644 --- a/aws-autoscaling.opam +++ b/aws-autoscaling.opam @@ -3,15 +3,16 @@ version: "1.2" synopsis: "Amazon Web Services SDK bindings to Auto Scaling" description: "Amazon Web Services SDK bindings to Auto Scaling" maintainer: "Tim McGilchrist " -authors: [ "Spiros Eliopoulos " - "Daniel Patterson " - "Tim McGilchrist " - ] +authors: [ + "Spiros Eliopoulos " + "Daniel Patterson " + "Tim McGilchrist " +] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" doc: "https://github.com/inhabitedtype/ocaml-aws" +dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} "aws" {= version} diff --git a/aws-cloudformation.opam b/aws-cloudformation.opam index 1d555b6cf..a90bd1f2a 100644 --- a/aws-cloudformation.opam +++ b/aws-cloudformation.opam @@ -3,15 +3,15 @@ version: "1.2" synopsis: "Amazon Web Services SDK bindings to AWS CloudFormation" description: "Amazon Web Services SDK bindings to AWS CloudFormation" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -28,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-cloudtrail.opam b/aws-cloudtrail.opam index 543fa11d2..f8cb809a4 100644 --- a/aws-cloudtrail.opam +++ b/aws-cloudtrail.opam @@ -3,15 +3,15 @@ version: "1.2" synopsis: "Amazon Web Services SDK bindings to AWS CloudTrail" description: "Amazon Web Services SDK bindings to AWS CloudTrail" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -28,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-cloudwatch.opam b/aws-cloudwatch.opam index 0709b6b25..fe1ef7900 100644 --- a/aws-cloudwatch.opam +++ b/aws-cloudwatch.opam @@ -3,15 +3,15 @@ version: "1.2" synopsis: "Amazon Web Services SDK bindings to Amazon CloudWatch" description: "Amazon Web Services SDK bindings to Amazon CloudWatch" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -28,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-ec2.opam b/aws-ec2.opam index 8131e1a79..f26d96152 100644 --- a/aws-ec2.opam +++ b/aws-ec2.opam @@ -3,15 +3,15 @@ version: "1.2" synopsis: "Amazon Web Services SDK bindings to Amazon Elastic Compute Cloud" description: "Amazon Web Services SDK bindings to Amazon Elastic Compute Cloud" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -28,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-elasticache.opam b/aws-elasticache.opam index 8e09a050d..bf8d45fea 100644 --- a/aws-elasticache.opam +++ b/aws-elasticache.opam @@ -3,15 +3,15 @@ version: "1.2" synopsis: "Amazon Web Services SDK bindings to Amazon ElastiCache" description: "Amazon Web Services SDK bindings to Amazon ElastiCache" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -28,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-elasticloadbalancing.opam b/aws-elasticloadbalancing.opam index 742a5f9ee..acdc844d4 100644 --- a/aws-elasticloadbalancing.opam +++ b/aws-elasticloadbalancing.opam @@ -3,15 +3,15 @@ version: "1.2" synopsis: "Amazon Web Services SDK bindings to Elastic Load Balancing" description: "Amazon Web Services SDK bindings to Elastic Load Balancing" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -28,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-gen.opam b/aws-gen.opam index a6f9e1893..81a25d711 100644 --- a/aws-gen.opam +++ b/aws-gen.opam @@ -18,6 +18,7 @@ depends: [ "yojson" "base-unix" "cmdliner" + "fmt" "ppx_tools_versioned" "yojson" {>= "1.6.0"} "ocaml-migrate-parsetree" diff --git a/aws-rds.opam b/aws-rds.opam index e88fe5a33..3054fb226 100644 --- a/aws-rds.opam +++ b/aws-rds.opam @@ -1,19 +1,17 @@ opam-version: "2.0" version: "1.2" -synopsis: - "Amazon Web Services SDK bindings to Amazon Relational Database Service" -description: - "Amazon Web Services SDK bindings to Amazon Relational Database Service" +synopsis: "Amazon Web Services SDK bindings to Amazon Relational Database Service" +description: "Amazon Web Services SDK bindings to Amazon Relational Database Service" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -30,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-route53.opam b/aws-route53.opam index aaab9f58b..9d9a536ee 100644 --- a/aws-route53.opam +++ b/aws-route53.opam @@ -3,15 +3,15 @@ version: "1.2" synopsis: "Amazon Web Services SDK bindings to Amazon Route 53" description: "Amazon Web Services SDK bindings to Amazon Route 53" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -28,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-sdb.opam b/aws-sdb.opam index 599ae3b1a..0eb4e16a0 100644 --- a/aws-sdb.opam +++ b/aws-sdb.opam @@ -3,15 +3,15 @@ version: "1.2" synopsis: "Amazon Web Services SDK bindings to Amazon SimpleDB" description: "Amazon Web Services SDK bindings to Amazon SimpleDB" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -28,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-sqs.opam b/aws-sqs.opam index bd0290b81..62180fdc9 100644 --- a/aws-sqs.opam +++ b/aws-sqs.opam @@ -1,18 +1,17 @@ opam-version: "2.0" version: "1.2" synopsis: "Amazon Web Services SDK bindings to Amazon Simple Queue Service" -description: - "Amazon Web Services SDK bindings to Amazon Simple Queue Service" +description: "Amazon Web Services SDK bindings to Amazon Simple Queue Service" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -29,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-ssm.opam b/aws-ssm.opam index a1e61fb46..82686ce0a 100644 --- a/aws-ssm.opam +++ b/aws-ssm.opam @@ -1,19 +1,17 @@ opam-version: "2.0" version: "1.2" -synopsis: - "Amazon Web Services SDK bindings to Amazon Simple Systems Management Service" -description: - "Amazon Web Services SDK bindings to Amazon Simple Systems Management Service" +synopsis: "Amazon Web Services SDK bindings to Amazon Simple Systems Management Service" +description: "Amazon Web Services SDK bindings to Amazon Simple Systems Management Service" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -30,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/aws-sts.opam b/aws-sts.opam index 920e9dd81..c0c1b3557 100644 --- a/aws-sts.opam +++ b/aws-sts.opam @@ -3,15 +3,15 @@ version: "1.2" synopsis: "Amazon Web Services SDK bindings to AWS Security Token Service" description: "Amazon Web Services SDK bindings to AWS Security Token Service" maintainer: "Tim McGilchrist " -authors: [ +authors: [ "Spiros Eliopoulos " "Daniel Patterson " "Tim McGilchrist " ] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -doc: "https://github.com/inhabitedtype/ocaml-aws" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" +doc: "https://github.com/inhabitedtype/ocaml-aws" dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} @@ -28,4 +28,4 @@ depends: [ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] -] +] \ No newline at end of file diff --git a/lib/aws.ml b/lib/aws.ml index 02fa2bbaa..ece352c7b 100644 --- a/lib/aws.ml +++ b/lib/aws.ml @@ -265,7 +265,7 @@ module Query = struct | k, List xs -> List.concat (List.map (enc k) xs) | Some n, Pair (label, subq) -> enc (Some (n ^ "." ^ label)) subq | None, Pair (label, subq) -> enc (Some label) subq - | Some n, Value (Some s) -> [ n ^ "=" ^ Uri.pct_encode s ] + | Some n, Value (Some s) -> [ n ^ "=" ^ Uri.pct_encode ~component:`Query_value s ] | None, Value (Some s) -> [ Uri.pct_encode s ] | Some s, _ -> [ s ] | _ -> [] @@ -522,7 +522,7 @@ module Signing = struct (* NOTE(dbp 2015-01-13): This is a direct translation of reference implementation at: * http://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html *) - let sign_request ~access_key ~secret_key ~service ~region (meth, uri, headers) = + let sign_request ~access_key ~secret_key ?token ~service ~region (meth, uri, headers) = let host = Util.of_option_exn (Endpoints.endpoint_of service region) in let params = encode_query (Uri.query uri) in let sign key msg = Hash.sha256 ~key msg in @@ -535,6 +535,14 @@ module Signing = struct let canonical_uri = "/" in let canonical_querystring = params in let payload_hash = Hash.sha256_hex "" in + let token_header, sig_header = + match token with + | Some t -> + let th = "x-amz-security-token:" ^ t ^ "\n" in + let sh = ";x-amz-security-token" in + th, sh + | None -> "", "" + in let canonical_headers = "host:" ^ host @@ -544,8 +552,9 @@ module Signing = struct ^ "\nx-amz-date:" ^ amzdate ^ "\n" + ^ token_header in - let signed_headers = "host;x-amz-content-sha256;x-amz-date" in + let signed_headers = "host;x-amz-content-sha256;x-amz-date" ^ sig_header in let canonical_request = Request.string_of_meth meth ^ "\n" @@ -597,20 +606,29 @@ module Signing = struct :: ("Authorization", authorization_header) :: headers in - meth, uri, headers + let full_headers = + match token with + | Some t -> ("X-Amz-Security-Token", t) :: headers + | None -> headers + in + meth, uri, full_headers - let sign_v2_request ~access_key ~secret_key ~service ~region (meth, uri, headers) = + let sign_v2_request ~access_key ~secret_key ?token ~service ~region (meth, uri, headers) + = let host = Util.of_option_exn (Endpoints.endpoint_of service region) in let amzdate = Time.date_time_iso8601 (Time.now_utc ()) in let query = Uri.add_query_params' uri - [ "Timestamp", amzdate - ; "AWSAccessKeyId", access_key - ; "SignatureMethod", "HmacSHA256" - ; "SignatureVersion", "2" - ] + ((match token with + | Some t -> [ "SecurityToken", t ] + | None -> []) + @ [ "Timestamp", amzdate + ; "AWSAccessKeyId", access_key + ; "SignatureMethod", "HmacSHA256" + ; "SignatureVersion", "2" + ]) in let params = encode_query (Uri.query query) in diff --git a/lib/aws.mli b/lib/aws.mli index 990551521..e618e5a36 100644 --- a/lib/aws.mli +++ b/lib/aws.mli @@ -304,6 +304,7 @@ module Signing : sig val sign_request : access_key:string -> secret_key:string + -> ?token:string -> service:string -> region:string -> Request.t @@ -325,6 +326,7 @@ module Signing : sig val sign_v2_request : access_key:string -> secret_key:string + -> ?token:string -> service:string -> region:string -> Request.t diff --git a/libraries/autoscaling/lib_test/aws_autoscaling_test.ml b/libraries/autoscaling/lib_test/aws_autoscaling_test.ml index be7d558de..4dd5df840 100644 --- a/libraries/autoscaling/lib_test/aws_autoscaling_test.ml +++ b/libraries/autoscaling/lib_test/aws_autoscaling_test.ml @@ -20,6 +20,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/autoscaling/lib_test/dune b/libraries/autoscaling/lib_test/dune index 185d16e69..0c96b71d0 100644 --- a/libraries/autoscaling/lib_test/dune +++ b/libraries/autoscaling/lib_test/dune @@ -1,8 +1,10 @@ (tests (names test_async test_lwt) (package aws-autoscaling) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_autoscaling_test) - (libraries aws aws-autoscaling aws-async aws-lwt aws-ec2 ounit2 yojson async + (libraries aws aws-autoscaling aws-ec2 aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) (rule diff --git a/libraries/cloudformation/lib_test/aws_cloudformation_test.ml b/libraries/cloudformation/lib_test/aws_cloudformation_test.ml index 471c2da42..62a3dc96a 100644 --- a/libraries/cloudformation/lib_test/aws_cloudformation_test.ml +++ b/libraries/cloudformation/lib_test/aws_cloudformation_test.ml @@ -16,6 +16,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/cloudtrail/lib_test/aws_cloudtrail_test.ml b/libraries/cloudtrail/lib_test/aws_cloudtrail_test.ml index 8178d9cd8..9a9d66629 100644 --- a/libraries/cloudtrail/lib_test/aws_cloudtrail_test.ml +++ b/libraries/cloudtrail/lib_test/aws_cloudtrail_test.ml @@ -20,6 +20,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/cloudtrail/lib_test/dune b/libraries/cloudtrail/lib_test/dune index dc5ea1747..f9206776f 100644 --- a/libraries/cloudtrail/lib_test/dune +++ b/libraries/cloudtrail/lib_test/dune @@ -1,6 +1,8 @@ (tests (names test_async test_lwt) (package aws-cloudtrail) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_cloudtrail_test) (libraries aws aws-cloudtrail aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/libraries/cloudwatch/lib_test/aws_cloudwatch_test.ml b/libraries/cloudwatch/lib_test/aws_cloudwatch_test.ml index ae10c3a4d..7ffc1c455 100644 --- a/libraries/cloudwatch/lib_test/aws_cloudwatch_test.ml +++ b/libraries/cloudwatch/lib_test/aws_cloudwatch_test.ml @@ -16,6 +16,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/cloudwatch/lib_test/dune b/libraries/cloudwatch/lib_test/dune index fe776d35f..c2737deec 100644 --- a/libraries/cloudwatch/lib_test/dune +++ b/libraries/cloudwatch/lib_test/dune @@ -1,6 +1,8 @@ (tests (names test_async test_lwt) (package aws-cloudwatch) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_cloudwatch_test) (libraries aws aws-cloudwatch aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/libraries/ec2/lib_test/aws_ec2_test.ml b/libraries/ec2/lib_test/aws_ec2_test.ml index 261f6cadb..a8fd0535a 100644 --- a/libraries/ec2/lib_test/aws_ec2_test.ml +++ b/libraries/ec2/lib_test/aws_ec2_test.ml @@ -20,6 +20,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/ec2/lib_test/dune b/libraries/ec2/lib_test/dune index b84b9f471..f522eba09 100644 --- a/libraries/ec2/lib_test/dune +++ b/libraries/ec2/lib_test/dune @@ -1,6 +1,8 @@ (tests (names test_async test_lwt) (package aws-ec2) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_ec2_test) (libraries aws aws-ec2 aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/libraries/elasticache/lib_test/aws_elasticache_test.ml b/libraries/elasticache/lib_test/aws_elasticache_test.ml index 103ac095e..496672694 100644 --- a/libraries/elasticache/lib_test/aws_elasticache_test.ml +++ b/libraries/elasticache/lib_test/aws_elasticache_test.ml @@ -16,6 +16,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/elasticache/lib_test/dune b/libraries/elasticache/lib_test/dune index 7c91ab8b0..691d7c3c1 100644 --- a/libraries/elasticache/lib_test/dune +++ b/libraries/elasticache/lib_test/dune @@ -1,6 +1,8 @@ (tests (names test_async test_lwt) (package aws-elasticache) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_elasticache_test) (libraries aws aws-elasticache aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/libraries/elasticloadbalancing/lib_test/aws_elasticloadbalancing_test.ml b/libraries/elasticloadbalancing/lib_test/aws_elasticloadbalancing_test.ml index 2ee903b58..2650a8b42 100644 --- a/libraries/elasticloadbalancing/lib_test/aws_elasticloadbalancing_test.ml +++ b/libraries/elasticloadbalancing/lib_test/aws_elasticloadbalancing_test.ml @@ -20,6 +20,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/elasticloadbalancing/lib_test/dune b/libraries/elasticloadbalancing/lib_test/dune index fe574f5e8..eea3d1bbe 100644 --- a/libraries/elasticloadbalancing/lib_test/dune +++ b/libraries/elasticloadbalancing/lib_test/dune @@ -1,6 +1,8 @@ (tests (names test_async test_lwt) (package aws-elasticloadbalancing) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_elasticloadbalancing_test) (libraries aws aws-elasticloadbalancing aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/libraries/rds/lib_test/aws_rds_test.ml b/libraries/rds/lib_test/aws_rds_test.ml index f456a8a6a..b84772f82 100644 --- a/libraries/rds/lib_test/aws_rds_test.ml +++ b/libraries/rds/lib_test/aws_rds_test.ml @@ -20,6 +20,7 @@ module TestSuite (Runtime : sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/rds/lib_test/dune b/libraries/rds/lib_test/dune index d03c4e22e..8544c51e8 100644 --- a/libraries/rds/lib_test/dune +++ b/libraries/rds/lib_test/dune @@ -1,6 +1,8 @@ (tests (names test_async test_lwt) (package aws-rds) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_rds_test) (libraries aws aws-rds aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/libraries/route53/lib_test/aws_route53_test.ml b/libraries/route53/lib_test/aws_route53_test.ml index 6cd5288fe..8171906a9 100644 --- a/libraries/route53/lib_test/aws_route53_test.ml +++ b/libraries/route53/lib_test/aws_route53_test.ml @@ -16,6 +16,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/route53/lib_test/dune b/libraries/route53/lib_test/dune index 83f6acbb8..b1c62daef 100644 --- a/libraries/route53/lib_test/dune +++ b/libraries/route53/lib_test/dune @@ -1,7 +1,8 @@ (tests (names test_async test_lwt) - (flags (:standard -w -27 -w -33)) (package aws-route53) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_route53_test) (libraries aws aws-route53 aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/libraries/sdb/lib_test/aws_sdb_test.ml b/libraries/sdb/lib_test/aws_sdb_test.ml index bc1039098..95af51f0b 100644 --- a/libraries/sdb/lib_test/aws_sdb_test.ml +++ b/libraries/sdb/lib_test/aws_sdb_test.ml @@ -16,6 +16,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/sdb/lib_test/dune b/libraries/sdb/lib_test/dune index 0fb9d17d5..7334753f7 100644 --- a/libraries/sdb/lib_test/dune +++ b/libraries/sdb/lib_test/dune @@ -1,6 +1,8 @@ (tests (names test_async test_lwt) (package aws-sdb) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_sdb_test) (libraries aws aws-sdb aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/libraries/sqs/lib_test/aws_sqs_test.ml b/libraries/sqs/lib_test/aws_sqs_test.ml index 4eae21c21..6e0e62c18 100644 --- a/libraries/sqs/lib_test/aws_sqs_test.ml +++ b/libraries/sqs/lib_test/aws_sqs_test.ml @@ -20,6 +20,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/sqs/lib_test/dune b/libraries/sqs/lib_test/dune index a1728b1d6..dccef0ca0 100644 --- a/libraries/sqs/lib_test/dune +++ b/libraries/sqs/lib_test/dune @@ -1,6 +1,8 @@ (tests (names test_async test_lwt) (package aws-sqs) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_sqs_test) (libraries aws aws-sqs aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/libraries/ssm/lib_test/aws_ssm_test.ml b/libraries/ssm/lib_test/aws_ssm_test.ml index 74ade7e10..d34477d31 100644 --- a/libraries/ssm/lib_test/aws_ssm_test.ml +++ b/libraries/ssm/lib_test/aws_ssm_test.ml @@ -16,6 +16,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output diff --git a/libraries/ssm/lib_test/dune b/libraries/ssm/lib_test/dune index 67bb8076d..e7bdabebb 100644 --- a/libraries/ssm/lib_test/dune +++ b/libraries/ssm/lib_test/dune @@ -1,6 +1,8 @@ (tests (names test_async test_lwt) (package aws-ssm) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_ssm_test) (libraries aws aws-ssm aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/libraries/sts/lib_test/aws_sts_test.ml b/libraries/sts/lib_test/aws_sts_test.ml index 6ba9623a4..d05a7b7b3 100644 --- a/libraries/sts/lib_test/aws_sts_test.ml +++ b/libraries/sts/lib_test/aws_sts_test.ml @@ -5,6 +5,7 @@ type config = { access_key : string ; secret_key : string ; region : string + ; role_arn : string option } let ( @? ) = assert_bool @@ -16,6 +17,7 @@ module type Runtime = sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output @@ -41,6 +43,25 @@ functor (module GetSessionToken) (Types.GetSessionTokenRequest.make ()))) + let assume_role config ?token () = + let role_arn = + match config.role_arn with + | Some s -> s + | None -> "" + in + Runtime.( + un_m + (run_request + ~region:config.region + ~access_key:config.access_key + ~secret_key:config.secret_key + ?token + (module AssumeRole) + (Types.AssumeRoleRequest.make + ~role_arn + ~role_session_name:"ocaml-aws-test" + ()))) + let get_session_token_test config _ = let result = get_session_token config () in "Get Session Token returns successfully" @@ -56,8 +77,72 @@ functor Printf.printf "Error: %s\n" (Aws.Error.format Errors_internal.to_string err); false + let print_assume_role_response resp = + Printf.printf + "%s\n" + (Yojson.Basic.to_string + Types.AssumeRoleResponse.(to_json (of_json (to_json resp)))) + + let print_assume_role_error err = + Printf.printf "Error: %s\n" (Aws.Error.format Errors_internal.to_string err) + + let assume_role_test config _ = + skip_if + (config.role_arn = None) + "Environment variable AWS_STS_ROLE_ARN not available."; + let result = assume_role config () in + "Assume Role returns succcessfully" + @? + match result with + | `Ok resp -> + print_assume_role_response resp; + true + | `Error err -> + print_assume_role_error err; + false + + (* This test is designed to see if assume_role authentication works for + `run_request`. Using a role ARN passed in via an environment variable, + it gets an assume_role token for the user specified and then gets another token + from those credentials. The role ARN passed in should have admin permissions in IAM. *) + let assume_role_assume_role_test config _ = + skip_if + (config.role_arn = None) + "Environment variable AWS_STS_ROLE_ARN not available."; + let result = assume_role config () in + "Assume Role able to Assume Role" + @? + match result with + | `Ok resp -> ( + print_assume_role_response resp; + match resp.credentials with + | Some creds -> ( + let config2 = + { config with + access_key = creds.access_key_id + ; secret_key = creds.secret_access_key + } + in + match assume_role config2 ~token:creds.session_token () with + | `Ok resp2 -> + print_assume_role_response resp2; + true + | `Error err -> + print_assume_role_error err; + false) + | None -> + Printf.eprintf "Did not receive credentials from first assume_role call."; + false) + | `Error err -> + print_assume_role_error err; + false + let suite config = - "Test STS" >::: [ "STS get_session_token" >:: get_session_token_test config ] + "Test STS" + >::: [ "STS get_session_token" >:: get_session_token_test config + ; "STS assume_role" >:: assume_role_test config + ; "STS assume_role -> assume_role" >:: assume_role_assume_role_test config + ] let () = let access_key = @@ -67,10 +152,11 @@ functor try Some (Unix.getenv "AWS_SECRET_ACCESS_KEY") with Not_found -> None in let region = try Some (Unix.getenv "AWS_DEFAULT_REGION") with Not_found -> None in + let role_arn = try Some (Unix.getenv "AWS_STS_ROLE_ARN") with Not_found -> None in match access_key, secret_key, region with | Some access_key, Some secret_key, Some region -> - run_test_tt_main (suite { access_key; secret_key; region }) + run_test_tt_main (suite { access_key; secret_key; region; role_arn }) | _, _, _ -> Printf.eprintf "Skipping running tests. Environment variables AWS_ACCESS_KEY_ID, \ diff --git a/libraries/sts/lib_test/dune b/libraries/sts/lib_test/dune index ea3b00f32..49e3ef41b 100644 --- a/libraries/sts/lib_test/dune +++ b/libraries/sts/lib_test/dune @@ -1,6 +1,8 @@ (tests (names test_async test_lwt) (package aws-sts) + (flags + (:standard -w -27 -w -33)) (modules test_async test_lwt aws_sts_test) (libraries aws aws-sts aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) diff --git a/lwt/runtime.ml b/lwt/runtime.ml index 111386321..7335a03c0 100644 --- a/lwt/runtime.ml +++ b/lwt/runtime.ml @@ -38,6 +38,7 @@ let run_request ~region ~access_key ~secret_key + ?token (module M : Aws.Call with type input = input and type output = output @@ -49,6 +50,7 @@ let run_request Aws.Signing.sign_request ~access_key ~secret_key + ?token ~service:M.service ~region (M.to_http M.service region inp) @@ -56,6 +58,7 @@ let run_request Aws.Signing.sign_v2_request ~access_key ~secret_key + ?token ~service:M.service ~region (M.to_http M.service region inp) diff --git a/lwt/runtime.mli b/lwt/runtime.mli index e72eb344f..bbb0ce68e 100644 --- a/lwt/runtime.mli +++ b/lwt/runtime.mli @@ -37,7 +37,9 @@ val run_request : region:string -> access_key:string -> secret_key:string + -> ?token:string -> ('input, 'output, 'error) Aws.call -> 'input -> [ `Ok of 'output | `Error of 'error Aws.Error.t ] Lwt.t -(** Run an AWS request, in the [region] with [access_key] and [secret_key]. *) +(** Run an AWS request, in the [region] with [access_key] and [secret_key]. + * An STS assume_role [token] can be optionally used to sign the request. *) diff --git a/src/aws_gen.ml b/src/aws_gen.ml index 03f2cb6d4..8333b322b 100644 --- a/src/aws_gen.ml +++ b/src/aws_gen.ml @@ -127,7 +127,7 @@ let rec mkdir_p ?(root = "") dirs = (try Unix.mkdir dir 0o777 with Unix.Unix_error (Unix.EEXIST, _, _) -> ()); mkdir_p ~root:dir ds -let main input override errors_path outdir is_ec2 = +let main input override errors_path outdir is_ec2 (optional_libs : string list) = log "## Generating..."; let overrides = match override with @@ -230,7 +230,7 @@ let main input override errors_path outdir is_ec2 = log "## Wrote dune file."; Printing.write_all ~filename:(lib_dir_test "dune") - (Templates.dune_test ~lib_name:lib_name_dir); + (Templates.dune_test ~optional_libs ~lib_name:lib_name_dir ()); log "## Wrote test runner files."; Printing.write_all @@ -281,7 +281,13 @@ module CommandLine = struct let doc = "This enables EC2-specific special casing in parts of code generation." in Arg.(value & flag & info [ "is-ec2" ] ~docv:"Filename" ~doc) - let gen_t = Term.(pure main $ input $ override $ errors $ outdir $ is_ec2) + let optional_libs = + let doc = "This allows us to include arbitrary libraries in our test files" in + let type_ = Arg.(opt (list string) []) in + Arg.(value & (type_ @@ info ~docv:"Filename" [ "optional-libs" ] ~doc)) + + let gen_t = + Term.(pure main $ input $ override $ errors $ outdir $ is_ec2 $ optional_libs) let info = let doc = "Generate a library for an AWS schema." in diff --git a/src/dune b/src/dune index edf606d95..55dd45868 100644 --- a/src/dune +++ b/src/dune @@ -4,5 +4,5 @@ (package aws-gen) (preprocess (pps ppx_tools_versioned.metaquot_404)) - (libraries yojson cmdliner unix ppx_tools_versioned ocaml-migrate-parsetree - ocamlgraph atdgen str)) + (libraries yojson cmdliner fmt unix ppx_tools_versioned + ocaml-migrate-parsetree ocamlgraph atdgen str)) diff --git a/src/templates.ml b/src/templates.ml index dc1304d8e..b2d70f130 100644 --- a/src/templates.ml +++ b/src/templates.ml @@ -33,30 +33,36 @@ let opam ~service_name = Printf.sprintf {|opam-version: "2.0" -maintainer: "Tim McGilchrist " -authors: [ "Spiros Eliopoulos " - "Daniel Patterson " - "Tim McGilchrist " - ] +version: "1.2" synopsis: "Amazon Web Services SDK bindings to %s" description: "Amazon Web Services SDK bindings to %s" -version: "1.2" +maintainer: "Tim McGilchrist " +authors: [ + "Spiros Eliopoulos " + "Daniel Patterson " + "Tim McGilchrist " +] license: "BSD-3-clause" homepage: "https://github.com/inhabitedtype/ocaml-aws" -dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" bug-reports: "https://github.com/inhabitedtype/ocaml-aws/issues" doc: "https://github.com/inhabitedtype/ocaml-aws" -build: [ - ["dune" "subst"] {pinned} - ["dune" "build" "-p" name "-j" jobs] -] +dev-repo: "git+https://github.com/inhabitedtype/ocaml-aws.git" depends: [ "ocaml" {>= "4.08"} "aws" {= version} "dune" {>= "2.7"} - "ounit2" {>= "2.2.4" & with-test} + "ounit2" {with-test & >= "2.2.4"} + "async" {with-test & >= "v0.14.0"} + "cohttp-async" {with-test & >= "2.4.0"} + "cohttp-lwt" {with-test & >= "2.4.0"} + "cohttp-lwt-unix" {with-test & >= "2.4.0"} + "lwt" {with-test & >= "4.0.0"} + "yojson" {with-test & >= "1.7.0"} ] -|} +build: [ + ["dune" "subst"] {pinned} + ["dune" "build" "-p" name "-j" jobs] +]|} service_name service_name @@ -73,17 +79,24 @@ let dune ~lib_name ~service_name = lib_name service_name -let dune_test ~lib_name = +let dune_test ?optional_libs ~lib_name () = (* Necessary cause '%' is reserved string in 'sprintf' and I didn't know how to escape it. *) + let optional_libs = + (match optional_libs with + | Some libs -> libs + | None -> []) + |> Fmt.str "%a" (Fmt.list ~sep:Fmt.sp Fmt.string) + in let d = "%{deps}" in Printf.sprintf - {|(executables + {|(tests (names test_async test_lwt) + (package aws-%s) (flags (:standard -w -27 -w -33)) (modules test_async test_lwt aws_%s_test) - (libraries aws aws-%s aws-async aws-lwt + (libraries aws aws-%s %s aws-async aws-lwt ounit2 yojson async cohttp-async lwt cohttp-lwt cohttp-lwt-unix)) @@ -100,6 +113,8 @@ let dune_test ~lib_name = |} lib_name lib_name + lib_name + optional_libs d d @@ -147,6 +162,7 @@ module TestSuite(Runtime : sig region:string -> access_key:string -> secret_key:string + -> ?token:string -> (module Aws.Call with type input = 'input and type output = 'output and type error = 'error) diff --git a/src/templates.mli b/src/templates.mli index c736494a7..a245ecac0 100644 --- a/src/templates.mli +++ b/src/templates.mli @@ -35,7 +35,7 @@ val dune : lib_name:string -> service_name:string -> string (* Generate a dune file suitable for building library tests *) -val dune_test : lib_name:string -> string +val dune_test : ?optional_libs:string list -> lib_name:string -> unit -> string (* Template for async runner for tests *) val test_async : lib_name:string -> string