scout-camp 0.1.1

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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.vimproject +81 -0
  3. data/LICENSE +20 -0
  4. data/README.md +26 -0
  5. data/Rakefile +70 -0
  6. data/VERSION +1 -0
  7. data/bin/scout-camp +5 -0
  8. data/lib/scout/aws/s3.rb +157 -0
  9. data/lib/scout/offsite/exceptions.rb +9 -0
  10. data/lib/scout/offsite/ssh.rb +175 -0
  11. data/lib/scout/offsite/step.rb +100 -0
  12. data/lib/scout/offsite/sync.rb +55 -0
  13. data/lib/scout/offsite.rb +3 -0
  14. data/lib/scout/terraform_dsl/deployment.rb +285 -0
  15. data/lib/scout/terraform_dsl/util.rb +100 -0
  16. data/lib/scout/terraform_dsl.rb +317 -0
  17. data/lib/scout-camp.rb +6 -0
  18. data/scout_commands/offsite +30 -0
  19. data/scout_commands/terraform/add +78 -0
  20. data/scout_commands/terraform/apply +31 -0
  21. data/scout_commands/terraform/destroy +31 -0
  22. data/scout_commands/terraform/list +36 -0
  23. data/scout_commands/terraform/remove +39 -0
  24. data/scout_commands/terraform/status +33 -0
  25. data/share/terraform/aws/bucket/main.tf +8 -0
  26. data/share/terraform/aws/bucket/output.tf +3 -0
  27. data/share/terraform/aws/bucket/variables.tf +4 -0
  28. data/share/terraform/aws/cluster/main.tf +66 -0
  29. data/share/terraform/aws/cluster/output.tf +9 -0
  30. data/share/terraform/aws/cluster/variables.tf +49 -0
  31. data/share/terraform/aws/host/locals.tf +15 -0
  32. data/share/terraform/aws/host/main.tf +22 -0
  33. data/share/terraform/aws/host/output.tf +9 -0
  34. data/share/terraform/aws/host/variables.tf +67 -0
  35. data/share/terraform/aws/lambda/main.tf +40 -0
  36. data/share/terraform/aws/lambda/variables.tf +23 -0
  37. data/share/terraform/aws/provider/data.tf +35 -0
  38. data/share/terraform/aws/provider/output.tf +16 -0
  39. data/test/scout/aws/test_s3.rb +82 -0
  40. data/test/scout/offsite/test_ssh.rb +15 -0
  41. data/test/scout/offsite/test_step.rb +33 -0
  42. data/test/scout/offsite/test_sync.rb +36 -0
  43. data/test/scout/test_terraform_dsl.rb +519 -0
  44. data/test/test_helper.rb +19 -0
  45. metadata +99 -0
@@ -0,0 +1,49 @@
1
+ variable "cidr_block_base" {
2
+ description = "CIDR block base IP to use in the vpc (e.g. 10.0.0.0)"
3
+ type = string
4
+ default = "10.0.0.0"
5
+ }
6
+
7
+ variable "cidr_block_mask" {
8
+ description = "CIDR block mask to use in the vpc (e.g. 16)"
9
+ type = string
10
+ default = "16"
11
+ }
12
+
13
+ variable "map_public_ip_on_launch" {
14
+ description = "Map the publich ip on launch"
15
+ type = bool
16
+ default = true
17
+ }
18
+
19
+ variable "availability_zone" {
20
+ description = "Availability zone for cluster"
21
+ type = string
22
+ default = null
23
+ }
24
+
25
+ # NAMETAGS
26
+
27
+ variable "cidr_nametag" {
28
+ description = "Name tag to assign the aws CIDR"
29
+ type = string
30
+ default = "one-provision-aws_CIDR"
31
+ }
32
+
33
+ variable "subnet_nametag" {
34
+ description = "Name tag to assign the aws subnet"
35
+ type = string
36
+ default = "one-provision-aws_subnet"
37
+ }
38
+
39
+ variable "gateway_nametag" {
40
+ description = "Name tag to assign the aws gateway"
41
+ type = string
42
+ default = "one-provision-aws_gateway"
43
+ }
44
+
45
+ variable "security_group_nametag" {
46
+ description = "Name tag to assign the aws security group"
47
+ type = string
48
+ default = "one-provision-aws_security_group"
49
+ }
@@ -0,0 +1,15 @@
1
+ locals {
2
+
3
+ ssh_key_list = var.ssh_key != null ? [var.ssh_key] : (var.ssh_keys == null ? [] : var.ssh_keys)
4
+
5
+ ssh_key_txt = "- ${join("\n- ",local.ssh_key_list)} "
6
+
7
+ cloud_config =<<EOF
8
+ #cloud-config
9
+ ssh_authorized_keys:
10
+ ${local.ssh_key_txt}
11
+ EOF
12
+
13
+ user_data = var.user_data != null ? var.user_data : base64encode(local.cloud_config)
14
+ }
15
+
@@ -0,0 +1,22 @@
1
+ resource "aws_instance" "this" {
2
+ ami = var.ami
3
+ instance_type = var.instance_type
4
+
5
+ private_ip = var.private_ip
6
+ subnet_id = var.subnet_id
7
+
8
+ vpc_security_group_ids = var.vpc_security_group_ids
9
+
10
+ user_data = local.user_data
11
+
12
+ availability_zone = var.availability_zone
13
+
14
+ root_block_device {
15
+ volume_size = var.volume_size
16
+ }
17
+
18
+ tags = {
19
+ Name = var.host_nametag
20
+ }
21
+ }
22
+
@@ -0,0 +1,9 @@
1
+ output "aws_instance_id" {
2
+ description = "Code that identifies the AWS instance"
3
+ value = aws_instance.this.id
4
+ }
5
+
6
+ output "aws_instance_ip" {
7
+ description = "Public IP address of the AWS instance"
8
+ value = aws_instance.this.public_ip
9
+ }
@@ -0,0 +1,67 @@
1
+
2
+ variable "ami" {
3
+ description = "AMI id for host"
4
+ type = string
5
+ }
6
+
7
+ variable "instance_type" {
8
+ description = "Type of AWS instance"
9
+ type = string
10
+ default = "t2.micro"
11
+ }
12
+
13
+ variable "volume_size" {
14
+ description = "Size of volumes"
15
+ type = number
16
+ default = 512
17
+ }
18
+
19
+ variable "private_ip" {
20
+ description = "Host private IP"
21
+ type = string
22
+ default = null
23
+ }
24
+
25
+ variable "user_data" {
26
+ description = "User data for host"
27
+ type = string
28
+ default = null
29
+ }
30
+
31
+ variable "ssh_key" {
32
+ description = "SSH key"
33
+ type = string
34
+ default = null
35
+ }
36
+
37
+ variable "ssh_keys" {
38
+ description = "List of SSH key"
39
+ type = list(string)
40
+ default = null
41
+ }
42
+
43
+ variable "availability_zone" {
44
+ description = "Availability zone for host"
45
+ type = string
46
+ default = null
47
+ }
48
+
49
+
50
+ variable "subnet_id" {
51
+ description = "Cluster subnet id"
52
+ type = string
53
+ default = null
54
+ }
55
+
56
+ variable "vpc_security_group_ids" {
57
+ description = "List of security group ids"
58
+ type = list(string)
59
+ default = null
60
+ }
61
+
62
+ variable "host_nametag" {
63
+ description = "Name tag to assign the AWS instance"
64
+ type = string
65
+ default = "one-provision-aws_instance"
66
+ }
67
+
@@ -0,0 +1,40 @@
1
+ provider "aws" {
2
+ region = "eu-west-2"
3
+ }
4
+
5
+ resource "aws_lambda_function" "this" {
6
+ function_name = var.function_name
7
+ role = aws_iam_role.lambda_role.arn
8
+ handler = "lambda_function.lambda_handler"
9
+ runtime = var.runtime
10
+ filename = var.filename
11
+ source_code_hash = filebase64sha256(var.filename)
12
+ timeout = var.timeout
13
+
14
+ environment {
15
+ variables = var.environment_variables
16
+ }
17
+ }
18
+
19
+ resource "aws_iam_role" "lambda_role" {
20
+ name = "lambda_execution_role"
21
+
22
+ assume_role_policy = jsonencode({
23
+ Version = "2012-10-17"
24
+ Statement = [
25
+ {
26
+ Action = "sts:AssumeRole"
27
+ Effect = "Allow"
28
+ Principal = {
29
+ Service = "lambda.amazonaws.com"
30
+ }
31
+ }
32
+ ]
33
+ })
34
+ }
35
+
36
+ resource "aws_iam_policy_attachment" "lambda_basic" {
37
+ name = "lambda_basic"
38
+ roles = [aws_iam_role.lambda_role.name]
39
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
40
+ }
@@ -0,0 +1,23 @@
1
+ variable "function_name" {
2
+ description = "Lambda function name"
3
+ type = string
4
+ }
5
+ variable "runtime" {
6
+ description = "Ruby runtime"
7
+ type = string
8
+ default = "ruby3.2"
9
+ }
10
+ variable "filename" {
11
+ description = "ZIP filename with lambda handler"
12
+ type = string
13
+ }
14
+ variable "timeout" {
15
+ description = "Timeout for call"
16
+ type = number
17
+ default = 30
18
+ }
19
+ variable "environment_variables" {
20
+ type = map(string)
21
+ description = "A map of environment variables to pass to the resource"
22
+ default = {}
23
+ }
@@ -0,0 +1,35 @@
1
+ data "aws_availability_zones" "available" {}
2
+
3
+ data "aws_ec2_instance_type_offerings" "available" {
4
+
5
+ for_each=toset(data.aws_availability_zones.available.names)
6
+
7
+ filter {
8
+ name = "instance-type"
9
+ values = ["c5.metal"]
10
+ }
11
+
12
+ filter {
13
+ name = "location"
14
+ values = [each.key]
15
+ }
16
+
17
+ location_type = "availability-zone"
18
+ }
19
+
20
+ data "aws_ami" "ubuntu2004" {
21
+
22
+ most_recent = true
23
+
24
+ filter {
25
+ name = "name"
26
+ values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
27
+ }
28
+
29
+ filter {
30
+ name = "virtualization-type"
31
+ values = ["hvm"]
32
+ }
33
+
34
+ owners = ["099720109477"]
35
+ }
@@ -0,0 +1,16 @@
1
+ output "available_aws_offerings" {
2
+ value = data.aws_ec2_instance_type_offerings.available
3
+ }
4
+
5
+ output "default_ami" {
6
+ value = data.aws_ami.ubuntu2004.id
7
+ }
8
+
9
+ output "my_zones" {
10
+ value = keys({ for az, details in data.aws_ec2_instance_type_offerings.available :
11
+ az => details.instance_types if length(details.instance_types) != 0 })
12
+ }
13
+
14
+ output "ipam" {
15
+ value = "aws"
16
+ }
@@ -0,0 +1,82 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ require 'scout/workflow'
5
+ class TestS3 < Test::Unit::TestCase
6
+ def test_list
7
+ file = "s3://herlab/tmp/foo.txt"
8
+
9
+ Open::S3.write file, "TEST"
10
+
11
+ dir = "s3://herlab/tmp"
12
+
13
+ assert_include Open::S3.glob(dir, "**/*"), file
14
+ end
15
+
16
+ def test_write
17
+ uri = "s3://herlab/tmp/foo.txt"
18
+
19
+ Open.write uri, "TEST"
20
+ assert_equal "TEST", Open.read(uri)
21
+ Open.rm uri
22
+ end
23
+
24
+ def test_write_io
25
+ uri = "s3://herlab/tmp/foo.txt"
26
+
27
+ Open::S3.write uri, "TEST"
28
+ io = Open::S3.get_stream uri
29
+ assert_equal "TEST", io.read
30
+ Open::S3.rm uri
31
+ end
32
+
33
+ def test_write_block
34
+ uri = "s3://herlab/tmp/foo.txt"
35
+
36
+ Open::S3.write uri do |sin|
37
+ sin.write "TEST"
38
+ end
39
+ io = Open::S3.get_stream uri
40
+ assert_equal "TEST", io.read
41
+ Open::S3.rm uri
42
+ end
43
+
44
+ def test_step
45
+ s = Step.new "s3://herlab/var/jobs/Baking/bake_muffin_tray/Default"
46
+ assert_include s.load, "baking"
47
+ end
48
+
49
+ def test_tmpfile
50
+ require 'rbbt-util'
51
+
52
+ TmpFile.tmpdir = Path.setup("s3://herlab/tmp")
53
+
54
+ TmpFile.with_path "TEST" do |file|
55
+ assert Open::S3.is_s3? file
56
+ assert_equal "TEST", file.read
57
+ end
58
+ end
59
+
60
+ def test_workflow
61
+ m = Module.new do
62
+ extend Workflow
63
+ name = "TestWF"
64
+
65
+ task :step1 => :string do
66
+ file('foo').write('bar')
67
+ "Step 1"
68
+ end
69
+
70
+ dep :step1
71
+ task :step2 => :string do
72
+ step(:step1).file('foo').read
73
+ end
74
+ end
75
+
76
+ m.directory = Path.setup("s3://herlab/var/jobs/TestWF")
77
+
78
+ m.job(:step2).run
79
+ assert_include m.job(:step2).step(:step1).files, 'foo'
80
+ end
81
+ end
82
+
@@ -0,0 +1,15 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ class TestSSH < Test::Unit::TestCase
5
+ def test_marshal
6
+ return unless SSHLine.reach?
7
+
8
+ assert TrueClass === SSHLine.scout(:default, 'true')
9
+ end
10
+
11
+ def test_localhost
12
+ assert SSHLine.scout('localhost', 'true')
13
+ end
14
+ end
15
+
@@ -0,0 +1,33 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ class TestOffsiteStep < Test::Unit::TestCase
5
+ def __test_offsite_task
6
+ workflow_code =<<-EOF
7
+ module TestWF
8
+ extend Workflow
9
+
10
+ input :string, :string, "String", "string"
11
+ task :string => :string do |string| string end
12
+ end
13
+
14
+ TestWF.directory = Path.setup("#{tmpdir.offsite.TestWF}")
15
+ EOF
16
+
17
+ sss 0
18
+ TmpFile.with_file workflow_code, :extension => 'rb' do |wffile|
19
+ wf = Workflow.require_workflow wffile
20
+
21
+ job = wf.job(:string)
22
+
23
+ off = OffsiteStep.setup job, server: 'localhost', workflow_name: wffile
24
+
25
+ refute off.done?
26
+ assert_equal 'string', off.run
27
+
28
+ assert off.done?
29
+ assert_equal 'string', off.run
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,36 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ class TestSync < Test::Unit::TestCase
5
+ def test_sync
6
+ TmpFile.with_path do |tmpdir|
7
+ tmpdir = Scout.tmp.tmpdir_sync
8
+ tmpdir.dir1.foo.write("FOO")
9
+ tmpdir.dir1.bar.write("BAR")
10
+
11
+ TmpFile.with_path do |tmpdir2|
12
+ Misc.in_dir tmpdir2 do
13
+ SSHLine.sync([tmpdir.dir1], map: :current)
14
+
15
+ assert tmpdir2.glob("**/*").select{|f| f.include?('foo') }.any?
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ def test_sync_dir_map
22
+ TmpFile.with_path do |tmpdir|
23
+ tmpdir = Scout.tmp.tmpdir_sync
24
+ tmpdir.dir1.foo.write("FOO")
25
+ tmpdir.dir1.bar.write("BAR")
26
+
27
+ TmpFile.with_path do |tmpdir2|
28
+ SSHLine.sync([tmpdir.dir1], map: tmpdir2)
29
+ Misc.in_dir tmpdir2 do
30
+ assert tmpdir2.glob("**/*").select{|f| f.include?('foo') }.any?
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+