govuk-connect 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5a31cd142ccad0489230d52b607a835569f375fa70512443fef37b07d09faec
4
- data.tar.gz: 1df85edae1c9bc3c16af1c870be0834b06996c12ec874059ff06b7f3859bce29
3
+ metadata.gz: 716cf50c2125d2a12c992fec40538575fd7a6c40390e4e09739a2de1bd47e984
4
+ data.tar.gz: 687de70081e82f05e8d5e0bc0f7f6152942dfb6b53bdf740b21952bdd533e1b1
5
5
  SHA512:
6
- metadata.gz: 3a9d2ee8908abaa9ecf68eebac54744d45d95927c83aba9675fba8a88a344c729cff47e9e7eafb9da3557659275501af7b6408ba42ba7f2b48d9bf8b2e4ea1bd
7
- data.tar.gz: 48b1fe78c0fd719b39c93dbb47e0cbb57f7bac07647032bff796ea2f130c1a8adf2d03e473bb55d7082f10486f40da3749babdabe32e7d0e515e02ecb9dcd174
6
+ metadata.gz: 729380dae3704692181f5cac981d9fd9b40501f5ffc5a32432f8081d34c82cc1f65fc93071491a10a9b0830551ce23d6e0efb62048c51e9a2ac487f32a81a549
7
+ data.tar.gz: efc411138a7ed5bfca695f6d5a5232643c2f3afea1d5c4b37ae7618c0276b4cfd7f7f1599d4708ae4ebb689c8d04453a7ffd153d0894028703b1715f1847207f
@@ -20,6 +20,10 @@ class GovukConnect::CLI
20
20
  EXAMPLES = <<-EXAMPLES.freeze
21
21
  govuk-connect ssh --environment integration backend
22
22
 
23
+ govuk-connect scp-push --environment integration backend filename.txt /tmp/
24
+
25
+ govuk-connect scp-pull --environment integration backend /tmp/filename.txt ~/Downloads/
26
+
23
27
  govuk-connect app-console --environment staging publishing-api
24
28
 
25
29
  govuk-connect app-dbconsole -e integration whitehall_backend/whitehall
@@ -30,7 +34,7 @@ class GovukConnect::CLI
30
34
  EXAMPLES
31
35
 
32
36
  MACHINE_TARGET_DESCRIPTION = <<-DOCS.freeze
33
- The ssh, rabbitmq and sidekiq-monitoring connection types target
37
+ The ssh, scp-*, rabbitmq and sidekiq-monitoring connection types target
34
38
  machines.
35
39
 
36
40
  The machine can be specified by name, for example:
@@ -565,71 +569,7 @@ class GovukConnect::CLI
565
569
  )
566
570
  log "debug: ssh to #{target} in #{environment}"
567
571
 
568
- # Split something like aws/backend:2 in to :aws, 'backend', 2
569
- hosting, name, number = parse_hosting_name_and_number(target)
570
-
571
- if name.end_with? ".internal"
572
- ssh_target = name
573
- hosting = :aws
574
- elsif name.end_with? ".gov.uk"
575
- ssh_target = name
576
- hosting = :carrenza
577
- else
578
- # The hosting might not have been provided, so check if necessary
579
- hosting ||= hosting_for_target_and_environment(target, environment)
580
-
581
- domains = get_domains_for_node_class(
582
- name,
583
- environment,
584
- hosting,
585
- ssh_username,
586
- )
587
-
588
- if domains.length.zero?
589
- error "error: couldn't find #{name} in #{hosting}/#{environment}"
590
-
591
- node_types = govuk_node_list_classes(environment, hosting)
592
-
593
- similar_node_types = strings_similar_to(name, node_types)
594
-
595
- if similar_node_types.any?
596
- info "\ndid you mean:"
597
- similar_node_types.each { |s| info " - #{s}" }
598
- else
599
- info "\nall node types:"
600
- node_types.each { |s| info " - #{s}" }
601
- end
602
-
603
- exit 1
604
- elsif domains.length == 1
605
- ssh_target = domains.first
606
-
607
- info "There is #{bold('one machine')} to connect to"
608
- else
609
- n_machines = bold("#{domains.length} machines")
610
- info "There are #{n_machines} of this class"
611
-
612
- if number
613
- unless number.positive?
614
- print_empty_line
615
- error "error: invalid machine number '#{number}', it must be > 0"
616
- exit 1
617
- end
618
-
619
- unless number <= domains.length
620
- print_empty_line
621
- error "error: cannot connect to machine number: #{number}"
622
- exit 1
623
- end
624
-
625
- ssh_target = domains[number - 1]
626
- info "Connecting to number #{number}"
627
- else
628
- ssh_target = domains.sample
629
- info "Connecting to a random machine (number #{domains.find_index(ssh_target) + 1})"
630
- end
631
- end
632
- end
572
+ target, hosting = ssh_target(target, environment)
633
573
 
634
574
  ssh_command = [
635
575
  "ssh",
@@ -641,7 +581,7 @@ class GovukConnect::CLI
641
581
  ),
642
582
  user_at_host(
643
583
  ssh_username,
644
- ssh_target,
584
+ target,
645
585
  ),
646
586
  ]
647
587
 
@@ -669,6 +609,44 @@ class GovukConnect::CLI
669
609
  exec(*ssh_command)
670
610
  end
671
611
 
612
+ def scp(
613
+ target,
614
+ environment,
615
+ files,
616
+ push: false,
617
+ additional_arguments: []
618
+ )
619
+ log "debug: scp #{push ? 'push' : 'pull'} to #{target} in #{environment}"
620
+
621
+ target, hosting = ssh_target(target, environment)
622
+
623
+ sources = files[0, files.length - 1]
624
+ destination = files[-1]
625
+
626
+ if push
627
+ destination = "#{target}:#{destination}"
628
+ else
629
+ sources = sources.map { |source| "#{target}:#{source}" }
630
+ end
631
+
632
+ scp_command = [
633
+ "scp",
634
+ *ssh_identity_arguments,
635
+ "-o",
636
+ "ProxyJump=#{user_at_host(ssh_username, jumpbox_for_environment_and_hosting(environment, hosting))}",
637
+ "-o",
638
+ "User=#{ssh_username}",
639
+ *additional_arguments,
640
+ "--",
641
+ *sources,
642
+ destination,
643
+ ]
644
+
645
+ info "\n#{bold('Running command:')} #{scp_command.join(' ')}\n\n"
646
+
647
+ exec(*scp_command)
648
+ end
649
+
672
650
  def rabbitmq_root_password_command(hosting, environment)
673
651
  hieradata_directory = {
674
652
  aws: "puppet_aws",
@@ -829,6 +807,94 @@ class GovukConnect::CLI
829
807
  [node_class, app_name, number]
830
808
  end
831
809
 
810
+ def target_from_options(target, options)
811
+ if options.key? :hosting
812
+ hosting, name, number = parse_hosting_name_and_number(target)
813
+ if hosting
814
+ error "error: hosting specified twice"
815
+ exit 1
816
+ end
817
+
818
+ {
819
+ hosting: options[:hosting],
820
+ name: name,
821
+ number: number,
822
+ }
823
+ else
824
+ target
825
+ end
826
+ end
827
+
828
+ def ssh_target(target, environment)
829
+ # Split something like aws/backend:2 in to :aws, 'backend', 2
830
+ hosting, name, number = parse_hosting_name_and_number(target)
831
+
832
+ if name.end_with? ".internal"
833
+ target = name
834
+ hosting = :aws
835
+ elsif name.end_with? ".gov.uk"
836
+ target = name
837
+ hosting = :carrenza
838
+ else
839
+ # The hosting might not have been provided, so check if necessary
840
+ hosting ||= hosting_for_target_and_environment(target, environment)
841
+
842
+ domains = get_domains_for_node_class(
843
+ name,
844
+ environment,
845
+ hosting,
846
+ ssh_username,
847
+ )
848
+
849
+ if domains.length.zero?
850
+ error "error: couldn't find #{name} in #{hosting}/#{environment}"
851
+
852
+ node_types = govuk_node_list_classes(environment, hosting)
853
+
854
+ similar_node_types = strings_similar_to(name, node_types)
855
+
856
+ if similar_node_types.any?
857
+ info "\ndid you mean:"
858
+ similar_node_types.each { |s| info " - #{s}" }
859
+ else
860
+ info "\nall node types:"
861
+ node_types.each { |s| info " - #{s}" }
862
+ end
863
+
864
+ exit 1
865
+ elsif domains.length == 1
866
+ target = domains.first
867
+
868
+ info "There is #{bold('one machine')} to connect to"
869
+ else
870
+ n_machines = bold("#{domains.length} machines")
871
+ info "There are #{n_machines} of this class"
872
+
873
+ if number
874
+ unless number.positive?
875
+ print_empty_line
876
+ error "error: invalid machine number '#{number}', it must be > 0"
877
+ exit 1
878
+ end
879
+
880
+ unless number <= domains.length
881
+ print_empty_line
882
+ error "error: cannot connect to machine number: #{number}"
883
+ exit 1
884
+ end
885
+
886
+ target = domains[number - 1]
887
+ info "Connecting to number #{number}"
888
+ else
889
+ target = domains.sample
890
+ info "Connecting to a random machine (number #{domains.find_index(target) + 1})"
891
+ end
892
+ end
893
+ end
894
+
895
+ [target, hosting]
896
+ end
897
+
832
898
  def check_for_target(target)
833
899
  unless target
834
900
  error "error: you must specify the target\n"
@@ -848,20 +914,23 @@ class GovukConnect::CLI
848
914
 
849
915
  def types
850
916
  @types ||= {
851
- "app-console" => proc do |target, environment, args, _options|
917
+ "app-console" => proc do |target, environment, args, extra_args, _options|
852
918
  check_for_target(target)
853
919
  check_for_additional_arguments("app-console", args)
920
+ check_for_additional_arguments("app-console", extra_args)
854
921
  govuk_app_command(target, environment, "console")
855
922
  end,
856
923
 
857
- "app-dbconsole" => proc do |target, environment, args, _options|
924
+ "app-dbconsole" => proc do |target, environment, args, extra_args, _options|
858
925
  check_for_target(target)
859
926
  check_for_additional_arguments("app-dbconsole", args)
927
+ check_for_additional_arguments("app-dbconsole", extra_args)
860
928
  govuk_app_command(target, environment, "dbconsole")
861
929
  end,
862
930
 
863
- "rabbitmq" => proc do |target, environment, args, _options|
931
+ "rabbitmq" => proc do |target, environment, args, extra_args, _options|
864
932
  check_for_additional_arguments("rabbitmq", args)
933
+ check_for_additional_arguments("rabbitmq", extra_args)
865
934
 
866
935
  target ||= "rabbitmq"
867
936
 
@@ -882,8 +951,9 @@ class GovukConnect::CLI
882
951
  )
883
952
  end,
884
953
 
885
- "sidekiq-monitoring" => proc do |target, environment, args, _options|
954
+ "sidekiq-monitoring" => proc do |target, environment, args, extra_args, _options|
886
955
  check_for_additional_arguments("sidekiq-monitoring", args)
956
+ check_for_additional_arguments("sidekiq-monitoring", extra_args)
887
957
  ssh(
888
958
  target || "backend",
889
959
  environment,
@@ -891,28 +961,50 @@ class GovukConnect::CLI
891
961
  )
892
962
  end,
893
963
 
894
- "ssh" => proc do |target, environment, args, options|
964
+ "ssh" => proc do |target, environment, args, extra_args, options|
895
965
  check_for_target(target)
966
+ target = target_from_options(target, options)
896
967
 
897
- if options.key? :hosting
898
- hosting, name, number = parse_hosting_name_and_number(target)
899
- if hosting
900
- error "error: hosting specified twice"
901
- exit 1
902
- end
968
+ ssh(
969
+ target,
970
+ environment,
971
+ port_forward: options[:port_forward],
972
+ additional_arguments: [args, extra_args].flatten,
973
+ )
974
+ end,
975
+
976
+ "scp-pull" => proc do |target, environment, args, extra_args, options|
977
+ check_for_target(target)
978
+ target = target_from_options(target, options)
903
979
 
904
- target = {
905
- hosting: options[:hosting],
906
- name: name,
907
- number: number,
908
- }
980
+ if args.length < 2
981
+ error "error: need at least two filenames"
982
+ exit 1
909
983
  end
910
984
 
911
- ssh(
985
+ scp(
912
986
  target,
913
987
  environment,
914
- port_forward: options[:port_forward],
915
- additional_arguments: args,
988
+ args,
989
+ additional_arguments: extra_args,
990
+ )
991
+ end,
992
+
993
+ "scp-push" => proc do |target, environment, args, extra_args, options|
994
+ check_for_target(target)
995
+ target = target_from_options(target, options)
996
+
997
+ if args.length < 2
998
+ error "error: need at least two filenames"
999
+ exit 1
1000
+ end
1001
+
1002
+ scp(
1003
+ target,
1004
+ environment,
1005
+ args,
1006
+ push: true,
1007
+ additional_arguments: extra_args,
916
1008
  )
917
1009
  end,
918
1010
  }
@@ -921,23 +1013,21 @@ class GovukConnect::CLI
921
1013
  def main(argv)
922
1014
  check_ruby_version_greater_than(required_major: 2, required_minor: 0)
923
1015
 
1016
+ extra_arguments_after_double_dash = []
1017
+
924
1018
  double_dash_index = argv.index "--"
925
1019
  if double_dash_index
926
- # This is used in the case of passing extra options to ssh, the --
927
- # acts as a separator, so to avoid optparse interpreting those
928
- # options, split argv around -- before parsing the options
929
- rest = argv[double_dash_index + 1, argv.length]
1020
+ # This is used in the case of passing extra options to ssh and
1021
+ # scp, the -- acts as a separator, so to avoid optparse
1022
+ # interpreting those as options, split argv around -- before
1023
+ # parsing the options
1024
+ extra_arguments_after_double_dash = argv[double_dash_index + 1, argv.length]
930
1025
  argv = argv[0, double_dash_index]
931
-
932
- options = parse_options(argv)
933
-
934
- type, target = argv
935
- else
936
- options = parse_options(argv)
937
-
938
- type, target, *rest = argv
939
1026
  end
940
1027
 
1028
+ govuk_connect_options = parse_options(argv)
1029
+ type, target, *extra_arguments_before_double_dash = argv
1030
+
941
1031
  unless type
942
1032
  error "error: you must specify the connection type\n"
943
1033
 
@@ -970,7 +1060,7 @@ class GovukConnect::CLI
970
1060
  exit 1
971
1061
  end
972
1062
 
973
- environment = options[:environment]&.to_sym
1063
+ environment = govuk_connect_options[:environment]&.to_sym
974
1064
 
975
1065
  unless environment
976
1066
  error "error: you must specify the environment\n"
@@ -986,7 +1076,13 @@ class GovukConnect::CLI
986
1076
  exit 1
987
1077
  end
988
1078
 
989
- handler.call(target, environment, rest, options)
1079
+ handler.call(
1080
+ target,
1081
+ environment,
1082
+ extra_arguments_before_double_dash,
1083
+ extra_arguments_after_double_dash,
1084
+ govuk_connect_options,
1085
+ )
990
1086
  rescue Interrupt
991
1087
  # Handle SIGTERM without printing a stacktrace
992
1088
  exit 1
@@ -1,3 +1,3 @@
1
1
  module GovukConnect
2
- VERSION = "0.2.1".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk-connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Government Digital Service
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-15 00:00:00.000000000 Z
11
+ date: 2020-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control