cortexapps-cli 0.24.3__tar.gz → 0.26.0__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cortexapps-cli
3
- Version: 0.24.3
3
+ Version: 0.26.0
4
4
  Summary: Command Line Interface for cortexapps
5
5
  License: MIT
6
6
  Author: Cortex Apps
@@ -62,6 +62,14 @@ homebrew
62
62
  brew tap cortexapps/tap
63
63
  brew install cortexapps-cli
64
64
 
65
+ ----------------------
66
+ docker
67
+ ----------------------
68
+
69
+ .. code:: bash
70
+
71
+ docker run -e CORTEX_API_KEY=<your API key> cortexapp/cli <Cortex CLI arguments>
72
+
65
73
  ===================
66
74
  Usage
67
75
  ===================
@@ -41,6 +41,14 @@ homebrew
41
41
  brew tap cortexapps/tap
42
42
  brew install cortexapps-cli
43
43
 
44
+ ----------------------
45
+ docker
46
+ ----------------------
47
+
48
+ .. code:: bash
49
+
50
+ docker run -e CORTEX_API_KEY=<your API key> cortexapp/cli <Cortex CLI arguments>
51
+
44
52
  ===================
45
53
  Usage
46
54
  ===================
@@ -522,13 +522,13 @@ def add_argument_type(subparser, option="-t", help_text='The resource type.', re
522
522
  metavar=''
523
523
  )
524
524
 
525
- def add_argument_types(subparser, option="-t", help_text='Comma-separated list of entity types.', required=True):
525
+ def add_argument_types(subparser, option="-t", help_text='Comma-separated list of entity types.', required=True, default=argparse.SUPPRESS):
526
526
  subparser.add_argument(
527
527
  option,
528
528
  '--types',
529
529
  help=help_text,
530
530
  required=required,
531
- default=argparse.SUPPRESS,
531
+ default=default,
532
532
  metavar=''
533
533
  )
534
534
 
@@ -711,6 +711,8 @@ def subparser_backup_opts(subparsers):
711
711
  def subparser_backup_export(subparser):
712
712
  sp = subparser.add_parser('export', help='Export tenant')
713
713
  add_argument_export_directory(sp)
714
+ add_argument_types(sp, required=False, default="ALL", help_text="Entity types to export. In addition to Cortex x-cortex-type values, this can include scorecard and ip-allowlist. Defaults to all types.")
715
+ add_argument_page_size(sp, help_text="Number of entities to return in each catalog API call, defaults to 50.")
714
716
  sp.set_defaults(func=export)
715
717
 
716
718
  def export(args):
@@ -744,8 +746,7 @@ def export(args):
744
746
  resource_types_list = []
745
747
  for t in data['definitions']:
746
748
  resource_types_list.append(t['type'])
747
-
748
- resource_types="service,domain"
749
+
749
750
  for resource_type in sorted(resource_types_list):
750
751
  print("--> " + resource_type)
751
752
  resource_file=resource_definitions_directory + "/" + resource_type + ".json"
@@ -756,99 +757,104 @@ def export(args):
756
757
  with open(resource_file, 'w') as f:
757
758
  f.write(resource_definition_output.getvalue())
758
759
  f.close()
759
- if "type" in args:
760
- delattr(args, 'type')
761
760
 
762
761
  print("Getting catalog entities")
763
- catalog_json=json_directory + "/catalog.json"
764
- catalog_output = io.StringIO()
765
- with redirect_stdout(catalog_output):
766
- catalog_list(args)
767
- with open(catalog_json, 'w') as f:
762
+ this_page = 0
763
+ total_pages = -1
764
+ args.yaml = True
765
+
766
+ while not this_page == total_pages:
767
+ descriptors=json_directory + "/descriptors-" + str(this_page) + ".json"
768
+ catalog_output = io.StringIO()
769
+ with redirect_stdout(catalog_output):
770
+ save_types = args.types
771
+ if args.types == "ALL":
772
+ delattr(args, 'types')
773
+ catalog_list_descriptors(args)
774
+ args.types = save_types
775
+
776
+ with open(descriptors, 'w') as f:
768
777
  f.write(catalog_output.getvalue())
769
- data = json.loads(catalog_output.getvalue())
770
-
771
- # Can't sort json keys, so need to create a list first so it can be sorted.
772
- entity_list = []
773
- for entity in data['entities']:
774
- entity_list.append(entity['tag'])
775
-
776
- for tag in sorted(entity_list):
777
- print("--> " + tag)
778
- # Can't create a file with '/' in the tag because it is interpreted as a subdirectory
779
- # for the filename.
780
- output_tag = tag.replace("/", "-")
781
- entity_file=catalog_directory + "/" + output_tag + ".yaml"
782
- args.tag = tag
783
- args.yaml = True
784
- entity_output = io.StringIO()
785
- with redirect_stdout(entity_output):
786
- catalog_descriptor(args)
787
- with open(entity_file, 'w') as f:
788
- f.write(entity_output.getvalue())
789
-
790
- print("Getting IP Allowlist definitions")
791
- ip_allowlist_json=json_directory + "/ip-allowlist.json"
792
- ip_allowlist_output = io.StringIO()
793
- with redirect_stdout(ip_allowlist_output):
794
- ip_allowlist_get(args)
795
- with open(ip_allowlist_json, 'w') as f:
796
- f.write(ip_allowlist_output.getvalue())
797
-
798
- print("Getting scorecards")
799
- scorecards_json=json_directory + "/scorecards.json"
800
- scorecards_output = io.StringIO()
801
- with redirect_stdout(scorecards_output):
802
- scorecards_list(args)
803
- with open(scorecards_json, 'w') as f:
804
- f.write(scorecards_output.getvalue())
805
-
806
- data = json.loads(scorecards_output.getvalue())
807
-
808
- # Can't sort json keys, so need to create a list first so it can be sorted.
809
- scorecard_list = []
810
- for scorecard in data['scorecards']:
811
- scorecard_list.append(scorecard['tag'])
812
-
813
- for tag in sorted(scorecard_list):
814
- print("--> " + tag)
815
- scorecard_file=scorecard_directory + "/" + tag + ".yaml"
816
- args.tag=tag
817
- scorecards_descriptor_output = io.StringIO()
818
- with redirect_stdout(scorecards_descriptor_output):
819
- scorecards_descriptor(args)
820
- with open(scorecard_file, 'w') as f:
821
- f.write(scorecards_descriptor_output.getvalue())
822
- delattr(args, 'tag')
778
+ data = json.loads(catalog_output.getvalue())
779
+ total_pages = data['totalPages']
780
+ this_page = this_page + 1
781
+ args.page = this_page
782
+
783
+ for descriptor in data['descriptors']:
784
+ y = yaml.safe_load(str(descriptor))
785
+ tag = y['info']['x-cortex-tag']
786
+ # Slash will be interpreted as a sub-directory
787
+ output_tag = tag.replace("/", "-")
788
+ print("--> " + tag)
789
+ f1 = open(catalog_directory + "/" + output_tag + ".yaml", 'w')
790
+ f1.write(str(descriptor) + "\n")
791
+
792
+ if any(export_type == "ALL" or export_type == "ip-allowlist" for export_type in args.types.split()):
793
+ print("Getting IP Allowlist definitions")
794
+ ip_allowlist_json=json_directory + "/ip-allowlist.json"
795
+ ip_allowlist_output = io.StringIO()
796
+ with redirect_stdout(ip_allowlist_output):
797
+ ip_allowlist_get(args)
798
+ with open(ip_allowlist_json, 'w') as f:
799
+ f.write(ip_allowlist_output.getvalue())
800
+
801
+ if any(export_type == "ALL" or export_type == "scorecard" for export_type in args.types.split()):
802
+ print("Getting scorecards")
803
+ scorecards_json=json_directory + "/scorecards.json"
804
+ scorecards_output = io.StringIO()
805
+ with redirect_stdout(scorecards_output):
806
+ scorecards_list(args)
807
+ with open(scorecards_json, 'w') as f:
808
+ f.write(scorecards_output.getvalue())
809
+
810
+ data = json.loads(scorecards_output.getvalue())
811
+
812
+ # Can't sort json keys, so need to create a list first so it can be sorted.
813
+ scorecard_list = []
814
+ for scorecard in data['scorecards']:
815
+ scorecard_list.append(scorecard['tag'])
816
+
817
+ for tag in sorted(scorecard_list):
818
+ print("--> " + tag)
819
+ scorecard_file=scorecard_directory + "/" + tag + ".yaml"
820
+ args.tag=tag
821
+ scorecards_descriptor_output = io.StringIO()
822
+ with redirect_stdout(scorecards_descriptor_output):
823
+ scorecards_descriptor(args)
824
+ with open(scorecard_file, 'w') as f:
825
+ f.write(scorecards_descriptor_output.getvalue())
826
+ delattr(args, 'tag')
823
827
 
824
828
  # CORTEX teams; will not try to import IDP-backed teams. Those would get re-imported after re-establishing the IDP integration.
825
- print("Getting teams")
826
- teams_json=json_directory + "/teams.json"
827
- teams_output = io.StringIO()
828
- with redirect_stdout(teams_output):
829
- teams_list(args)
830
- with open(teams_json, 'w') as f:
831
- f.write(teams_output.getvalue())
832
-
833
- data = json.loads(teams_output.getvalue())
834
-
835
- # Can't sort json keys, so need to create a list first so it can be sorted.
836
- # Has to be a dictionary because we also need to know about the type of team.
837
- team_list = dict()
838
- for team in data['teams']:
839
- team_list[team['teamTag']] = team['type']
840
-
841
- for team_tag, type in OrderedDict(sorted(team_list.items())).items():
842
- if type != "CORTEX":
843
- continue
844
- print("--> " + team_tag)
845
- team_file=teams_directory + "/" + team_tag + ".json"
846
- args.teamTag=team_tag
847
- team_output = io.StringIO()
848
- with redirect_stdout(team_output):
849
- teams_get(args)
850
- with open(team_file, 'w') as f:
851
- f.write(team_output.getvalue())
829
+ # 2024-05-06 Will already have teams as entitites from catalog export, so should be no need to also export teams.
830
+ # print("Getting teams")
831
+ # teams_json=json_directory + "/teams.json"
832
+ # teams_output = io.StringIO()
833
+ # with redirect_stdout(teams_output):
834
+ # teams_list(args)
835
+ # with open(teams_json, 'w') as f:
836
+ # f.write(teams_output.getvalue())
837
+ #
838
+ # data = json.loads(teams_output.getvalue())
839
+ #
840
+ # # Can't sort json keys, so need to create a list first so it can be sorted.
841
+ # # Has to be a dictionary because we also need to know about the type of team.
842
+ # team_list = dict()
843
+ # for team in data['teams']:
844
+ # team_list[team['teamTag']] = team['type']
845
+ #
846
+ # for team_tag, type in OrderedDict(sorted(team_list.items())).items():
847
+ # if type != "CORTEX":
848
+ # continue
849
+ # print("--> " + team_tag)
850
+ # output_tag = team_tag.replace("/", "-")
851
+ # team_file=teams_directory + "/" + output_tag + ".json"
852
+ # args.teamTag=team_tag
853
+ # team_output = io.StringIO()
854
+ # with redirect_stdout(team_output):
855
+ # teams_get(args)
856
+ # with open(team_file, 'w') as f:
857
+ # f.write(team_output.getvalue())
852
858
 
853
859
  print("\nExport complete!")
854
860
  print("Contents available in " + args.directory)
@@ -1011,13 +1017,13 @@ def subparser_catalog_list(subparser):
1011
1017
  'list',
1012
1018
  help='List all entities across the Service, Resource and Domain Catalogs.\n This API returns summary data for each entity, so refer to the retrieve entity method to lookup more details for a single entity.'
1013
1019
  )
1014
- add_argument_groups(sp)
1015
1020
  sp.add_argument(
1016
- '-o',
1017
- '--owners',
1018
- help='Filter based on owner group names, which correspond to the x-cortex-owners field in the Catalog Descriptor. Accepts a comma-delimited list of owner group names',
1019
- default=argparse.SUPPRESS,
1020
- metavar=''
1021
+ '-a',
1022
+ '--includeArchived',
1023
+ help='Whether to include archived entities in the response, default to false',
1024
+ default=False,
1025
+ action='store_true',
1026
+ required=False
1021
1027
  )
1022
1028
  sp.add_argument(
1023
1029
  '-d',
@@ -1026,13 +1032,7 @@ def subparser_catalog_list(subparser):
1026
1032
  default='full',
1027
1033
  metavar=''
1028
1034
  )
1029
- sp.add_argument(
1030
- '-r',
1031
- '--gitRepositories',
1032
- help='Supports only GitHub repositories in the org/repo format',
1033
- default=argparse.SUPPRESS,
1034
- metavar=''
1035
- )
1035
+ add_argument_groups(sp)
1036
1036
  sp.add_argument(
1037
1037
  '-i',
1038
1038
  '--includeHierarchyFields',
@@ -1042,24 +1042,17 @@ def subparser_catalog_list(subparser):
1042
1042
  required=False
1043
1043
  )
1044
1044
  sp.add_argument(
1045
- '-t',
1046
- '--types',
1047
- help='Filter the response to specific types of entities. By default, this includes services, resources, and domains. Corresponds to the x-cortex-type field in the Entity Descriptor.',
1045
+ '-in',
1046
+ '--includeNestedFields',
1047
+ help='List of sub fields to include for different types, for example team:members',
1048
1048
  default=argparse.SUPPRESS,
1049
- metavar=''
1050
- )
1051
- sp.add_argument(
1052
- '-a',
1053
- '--includeArchived',
1054
- help='Whether to include archived entities in the response, default to false',
1055
- default=False,
1056
- action='store_true',
1049
+ metavar='',
1057
1050
  required=False
1058
1051
  )
1059
1052
  sp.add_argument(
1060
- '-m',
1061
- '--includeMetadata',
1062
- help='Whether to include custom data for each entity in the response',
1053
+ '-io',
1054
+ '--includeOwners',
1055
+ help='Whether to include ownership information for each entity in the response',
1063
1056
  default=False,
1064
1057
  action='store_true',
1065
1058
  required=False
@@ -1073,21 +1066,36 @@ def subparser_catalog_list(subparser):
1073
1066
  required=False
1074
1067
  )
1075
1068
  sp.add_argument(
1076
- '-io',
1077
- '--includeOwners',
1078
- help='Whether to include ownership information for each entity in the response',
1069
+ '-m',
1070
+ '--includeMetadata',
1071
+ help='Whether to include custom data for each entity in the response',
1079
1072
  default=False,
1080
1073
  action='store_true',
1081
1074
  required=False
1082
1075
  )
1083
1076
  sp.add_argument(
1084
- '-in',
1085
- '--includeNestedFields',
1086
- help='List of sub fields to include for different types, for example team:members',
1077
+ '-o',
1078
+ '--owners',
1079
+ help='Filter based on owner group names, which correspond to the x-cortex-owners field in the Catalog Descriptor. Accepts a comma-delimited list of owner group names',
1087
1080
  default=argparse.SUPPRESS,
1088
- metavar='',
1089
- required=False
1081
+ metavar=''
1082
+ )
1083
+ add_argument_page(sp)
1084
+ sp.add_argument(
1085
+ '-r',
1086
+ '--gitRepositories',
1087
+ help='Supports only GitHub repositories in the org/repo format',
1088
+ default=argparse.SUPPRESS,
1089
+ metavar=''
1090
1090
  )
1091
+ sp.add_argument(
1092
+ '-t',
1093
+ '--types',
1094
+ help='Filter the response to specific types of entities. By default, this includes services, resources, and domains. Corresponds to the x-cortex-type field in the Entity Descriptor.',
1095
+ default=argparse.SUPPRESS,
1096
+ metavar=''
1097
+ )
1098
+ add_argument_page_size(sp)
1091
1099
  sp.set_defaults(func=catalog_list)
1092
1100
 
1093
1101
  def catalog_list(args):
@@ -1,7 +1,7 @@
1
1
  [tool.poetry]
2
2
  name = "cortexapps-cli"
3
3
  # version will be incremented via command line as part of github actions build
4
- version = "0.24.3"
4
+ version = "0.26.0"
5
5
  description = "Command Line Interface for cortexapps"
6
6
  license = "MIT"
7
7
  authors = [
File without changes