├── .gitignore
├── LICENSE
├── README.md
├── action templates
├── email
│ ├── diffs-details.liquid
│ ├── diffs.liquid
│ ├── file-diffs-html.liquid
│ ├── file-diffs.liquid
│ ├── group-diffs.liquid
│ ├── policy-failure-detailed.liquid
│ ├── policy-failure-simple.liquid
│ └── success-with-messages.liquid
├── jira
│ ├── file-diffs.liquid
│ ├── job-url.liquid
│ ├── node-url.liquid
│ ├── policy-failures-detailed.liquid
│ ├── policy-failures.liquid
│ └── policy-results.liquid
└── slack
│ ├── diffs.liquid
│ └── policy-failures.liquid
├── api
├── perl
│ ├── nodes-create-csv.pl
│ ├── nodes-create.pl
│ ├── nodes-lookup.pl
│ ├── os-families-index.pl
│ └── os-index.pl
├── powershell
│ ├── .keep
│ ├── Add-File-Scan-Option.ps1
│ ├── Add-GithubRepoNodes.ps1
│ ├── Aggregate-Diffs.ps1
│ ├── Get-JiraCloudNode.ps1
│ ├── Get-LastPassNode.ps1
│ ├── Get-PingdomNode.ps1
│ ├── List-Stale-Nodes.ps1
│ ├── Update-GithubRepoNodes.ps1
│ ├── add-nodes-via-api-from-csv-template.ps1
│ ├── adding-winrm-nodes.ps1
│ ├── azure_resource_node.ps1
│ ├── change_report.ps1
│ ├── ci-query.md
│ ├── ci-query.pdf
│ ├── ci-query.ps1
│ ├── custom-node-script-example-oracle.ps1
│ ├── custom_reporting_with_api.ps1
│ ├── enable-winrm-https-1-complete.ps1
│ ├── enable-winrm-https-1.ps1
│ ├── enable-winrm-https-2.ps1
│ ├── export-and-aggregate-diffs-to-csv.ps1
│ ├── export-diffs-to-csv.ps1
│ ├── extract-automation-snippets.ps1
│ ├── get-events-with-paging.ps1
│ ├── get-last-login-events.ps1
│ ├── get-node-last-scanned-dates.ps1
│ ├── get-used-space.ps1
│ ├── ignore_ssl_cert_check.ps1
│ ├── iis-site-logs-enabled.ps1
│ ├── list_nodes.ps1
│ ├── move-extinct-aws-nodes.ps1
│ ├── node-group-attach-policy.ps1
│ ├── node-scan.ps1
│ ├── node-update-alternate-password.ps1
│ ├── node-update-medium-hostname.ps1
│ ├── node-update-ssh-creds.ps1
│ ├── node_diff.ps1
│ ├── nodes-create-csv-ps2.ps1
│ ├── nodes-create-csv.ps1
│ ├── nodes-create.ps1
│ ├── nodes-lookup.ps1
│ ├── nodes.csv
│ ├── os-families-index.ps1
│ ├── os-index.ps1
│ ├── powershell-2-web-requests.ps1
│ ├── query_vuln_endpoint.ps1
│ ├── retrieve-backups.ps1
│ ├── scan-nodes-in-node-group.ps1
│ ├── set-hostname-to-display-name.ps1
│ ├── simple-email-for-policy-failure.ps1
│ ├── snippets
│ │ └── UpGuard-WebRequest.ps1
│ ├── start-scan-if-connected-and-required.ps1
│ ├── update-externalid-from-ad.ps1
│ ├── update-password-from-node-group.ps1
│ ├── upload-csv.ps1
│ └── using-winrm-without-admin-rights.ps1
├── python
│ ├── .keep
│ ├── auto_update_policies.py
│ ├── change-nodes-environment.py
│ ├── custom-node-remote.py
│ ├── custom-node.py
│ ├── delete-ec2-config-nodes-from-detected-page.py
│ ├── delete-stale-nodes.py
│ ├── find-environment-id-by-name.py
│ ├── find-nodes-without-external-id.py
│ ├── get-last-node-scan.py
│ ├── get_file_from_node.py
│ ├── list-environments.py
│ ├── list-operating-system-ids.py
│ ├── load-events.py
│ ├── move-extinct-aws-nodes.py
│ ├── node-membership-via-csv.py
│ ├── nodes-create-csv.py
│ ├── nodes-create.py
│ ├── nodes-lookup.py
│ ├── nodes.csv
│ ├── os-families-index.py
│ ├── os-index.py
│ ├── pull_data_into_splunk.py
│ ├── set-hostname-to-display-name.py
│ ├── snippets
│ │ ├── README.md
│ │ ├── requests
│ │ │ ├── README.md
│ │ │ ├── requirements.txt
│ │ │ ├── snippets.py
│ │ │ └── template.py
│ │ ├── requirements.txt
│ │ ├── snippets.py
│ │ └── template.py
│ ├── start_scan_if_connected_and_required.py
│ ├── sync-node-scan-history-to-dir.py
│ ├── util
│ │ ├── README.md
│ │ ├── compact.py
│ │ └── requirements.txt
│ └── yum-check-update.py
├── ruby
│ ├── .keep
│ ├── add_and_scan_node.rb
│ ├── aggregate_events_for_jira_actions.rb
│ ├── api-demo.rb
│ ├── custom-node-ms-sql.rb
│ ├── example-api-scripts.rb
│ ├── extact_nodes_to_csv.rb
│ ├── get_events_with_paging.rb
│ ├── latest-results.rb
│ ├── list_all_operating_system_ids.rb
│ ├── list_environment_nodes.rb
│ ├── list_environments.rb
│ ├── list_node_group_nodes.rb
│ ├── list_node_groups.rb
│ ├── list_nodes.rb
│ ├── node-change-environment.rb
│ ├── nodes-create-csv.rb
│ ├── nodes-create.rb
│ ├── nodes-index.rb
│ ├── nodes-lookup.rb
│ ├── os-families-index.rb
│ ├── os-index.rb
│ ├── policies-delete-v2.rb
│ ├── policies-delete.rb
│ └── upguard-tasks.rb
└── shell
│ ├── .keep
│ ├── create-event.sh
│ ├── create-legacy-event.sh
│ ├── node-scan.sh
│ ├── node-update-password.sh
│ ├── nodes-create.sh
│ └── retrieve-backup.sh
├── automation
├── ansible
│ ├── README.md
│ └── upguard_node
│ │ ├── library
│ │ └── upguard_node.py
│ │ ├── play.yml
│ │ └── requirements.txt
├── puppet
│ ├── upguard-async.rb
│ ├── upguard-cv.rb
│ ├── upguard.rb
│ ├── upguard.yaml
│ ├── upguard_rb.md
│ └── upguard_rb.pdf
└── vrealize-orchestrator
│ ├── UpGuard Node Registration.workflow
│ ├── UpGuard Nodes Create.workflow
│ ├── UpGuard Nodes List.workflow
│ ├── UpGuard Nodes Start_Scan.workflow
│ ├── readme.md
│ ├── vRO - Add a REST host.png
│ ├── vRO - REST Operation Start Scan.png
│ ├── vRO - REST Operation nodes create.png
│ ├── vRO - REST Operation nodes list.png
│ ├── vRO - Script Auth Header.png
│ ├── vRO - UpGuard Add and Scan SCRIPT.png
│ ├── vRO - UpGuard Node Reistration Workflow.png
│ ├── vRO - UpGuard Workflows.png
│ ├── vRO Login.png
│ ├── vRO Workflow - Error.png
│ ├── vRO Workflow - UpGuard Nodes.png
│ ├── vRO_upguard_node_lookup_persistent.js
│ ├── vRealize Orchestrator - Integration Guide.pdf
│ └── vro_upguard_node_lookup_transient.js
├── blueprints
├── netapp-cdot.js
├── perl
│ └── custom-devices
│ │ ├── cisco_call_manager.pl
│ │ ├── cisco_nam.pl
│ │ ├── cisco_source_fire.pl
│ │ ├── esxi.pl
│ │ ├── hp_onboard_administrator.pl
│ │ ├── lantronix.pl
│ │ ├── tripplite.pl
│ │ └── upguard_cisco_parser.pl
├── shell
│ └── blueprint-demo.sh
└── ssh-exec-example.js
├── policies
├── CyberRisk.json
├── MS_SQL_testing.txt
├── PCI_3_2_Audit_Check_Windows.json
├── PCI_3_2_MS-SQL_Windows.json
├── PCI_3_2_Password_Check_RHEL7.json
├── PCI_3_2_Password_Check_Windows.json
├── PCI_3_2_Server_Hardening_Windows.json
├── STIG-Windows-2012.json
├── aws_cis_access_analyzer_policy.json
├── aws_cis_cloudtrail_policy.json
├── aws_cis_config_service_policy.json
├── aws_cis_ebs_policy.json
├── aws_cis_iam_policy.json
├── aws_cis_kms_policy.json
├── aws_cis_rds_policy.json
├── aws_cis_s3_policy.json
├── aws_cis_vpc_policy.json
├── aws_iam_best_practice.json
├── azure_cis_activity_log_alerts_policy.json
├── azure_cis_app_service_policy.json
├── azure_cis_keyvault_policy.json
├── azure_cis_mysql_policy.json
├── azure_cis_postgresql_policy.json
├── azure_cis_security_group_policy.json
├── azure_cis_sql_policy.json
├── azure_cis_storage_policy.json
├── azure_cis_virtual_machine_policy.json
├── bluekeep-cve-check-policy.json
├── dchp_address_pool_utilization (1).json
├── dsc_base_resource_configuration.json
├── dsc_configuration_status.json
├── dsc_lcm_settings.json
├── dsc_package_upguard.json
├── gcp_cis_bigquery_policy.json
├── gcp_cis_clouddns_policy.json
├── gcp_cis_cloudlogging_policy.json
├── gcp_cis_cloudsql_policy.json
├── gcp_cis_gce_policy.json
├── gcp_cis_iam_policy.json
├── gcp_cis_kms_policy.json
├── github2FApolicy.json
├── githubPrivateRepoPolicy.json
├── githubRepoIsNotFork.json
├── githubUserFullNamePolicy.json
├── policy_ipv6_disabled_regkey.json
├── rhel_6_meltdown_spectre_kernel_version_policy
├── rhel_7_meltdown_spectre_kernel_version_check
├── s3_access_control_lists.json
├── s3_bucket_and_content_permission_check.json
├── sles_11.4_meltdown_spectre_kernel_version_check
└── windows-meltdown-spectre.json
├── scan-options
├── linux
│ └── bash
│ │ └── file-hash-by-extension.sh
└── windows
│ └── powershell
│ ├── active-directory-schema.ps1
│ ├── com-plus.ps1
│ ├── computers-in-active-directory.ps1
│ ├── dns-reverse-search.ps1
│ ├── file-hash-by-directory-with-excluded-directories.ps1
│ ├── file-hash-by-directory.ps1
│ ├── fim-scanner.ps1
│ ├── gac.md
│ ├── gac.ps1
│ ├── iis-app-pools-dynamic.ps1
│ ├── iis-app-pools-static.ps1
│ ├── iis-section.ps1
│ ├── iis-virtual-directories.ps1
│ ├── iis-website-information.ps1
│ ├── local-security-policies.ps1
│ ├── recursive-file-integrity-check.ps1
│ ├── share-permissions.ps1
│ ├── stored-procedures.ps1
│ ├── system-audit-policies.ps1
│ └── users-in-active-directory.ps1
└── setup and utilities
├── Backup.xml
├── WINRM PS Settings.htm
├── WinRM GPO Info.md
├── bat
└── wincm
│ └── check-service.bat
├── gpreport.xml
└── winrm_v1.zip
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Windows template
3 | # Windows image file caches
4 | Thumbs.db
5 | ehthumbs.db
6 |
7 | # Folder config file
8 | Desktop.ini
9 |
10 | # Recycle Bin used on file shares
11 | $RECYCLE.BIN/
12 |
13 | # Windows Installer files
14 | *.cab
15 | *.msi
16 | *.msm
17 | *.msp
18 |
19 | # Windows shortcuts
20 | *.lnk
21 |
22 |
23 | ### Vim template
24 | [._]*.s[a-w][a-z]
25 | [._]s[a-w][a-z]
26 | *.un~
27 | Session.vim
28 | .netrwhist
29 | *~
30 |
31 |
32 | ### OSX template
33 | .DS_Store
34 | .AppleDouble
35 | .LSOverride
36 |
37 | # Icon must end with two \r
38 | Icon
39 |
40 | # Thumbnails
41 | ._*
42 |
43 | # Files that might appear in the root of a volume
44 | .DocumentRevisions-V100
45 | .fseventsd
46 | .Spotlight-V100
47 | .TemporaryItems
48 | .Trashes
49 | .VolumeIcon.icns
50 |
51 | # Directories potentially created on remote AFP share
52 | .AppleDB
53 | .AppleDesktop
54 | Network Trash Folder
55 | Temporary Items
56 | .apdisk
57 |
58 | # JetBrains
59 | .idea
60 |
61 |
62 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cloudhouse Guardian Content
2 |
3 | Open source content available for use with [Guardian](https://cloudhouse.com/cloudhouse-guardian/).
4 |
5 | ## Code
6 |
7 | * Working API usage examples provided in Python, PowerShell, Ruby, Perl and Bash
8 | * Standard parameters that require updating include: `apikey`, `secretkey` and `hostname`
9 | * See the [Using the API](https://help.cloudhouse.com/upguard/using-the-api) support article for further details
10 |
11 | ## Contibuting
12 |
13 | * Issues, and Pull Requests are always welcome.
14 | * Questions and feeback can be sent to [helpdesk@cloudhouse.com](mailto:helpdesk@cloudhouse.com)
15 |
--------------------------------------------------------------------------------
/action templates/email/diffs-details.liquid:
--------------------------------------------------------------------------------
1 | {% for diff in diffs %}
2 | {% assign new = diff["new"] %}
3 |
4 | {% for val in diff["old"] %}
5 | {% assign attribute = val[0] %}
6 |
7 | {% assign old_val = val[1] %}
8 | {% assign new_val = new[attribute] %}
9 |
10 | {% if old_val != new_val %}
11 | Item: {{ diff["item"] }}
12 | Attribute: {{ attribute }}
13 | Old Value: {{ old_val }}
14 | New Value: {{ new_val }}
15 |
16 | {% endif %}
17 | {% endfor %}
18 | {% endfor %}
19 |
--------------------------------------------------------------------------------
/action templates/email/diffs.liquid:
--------------------------------------------------------------------------------
1 | {% for diff in diffs %}
2 | {{ diff['item'] }} - WAS: {{ diff['old'] }} NOW: {{ diff['new'] }}
3 | {% endfor %}
4 |
--------------------------------------------------------------------------------
/action templates/email/file-diffs-html.liquid:
--------------------------------------------------------------------------------
1 | {{ node }} File Differences
2 |
3 | {% for diff in file_diffs %}
4 | {{ diff['file_path'] }} |
5 |
6 | Change Type: |
7 | {{ diff['changed'] }} |
8 |
9 |
10 | Attributes Changed: |
11 | {{ diff['changed_attributes'] | join: ", " }} |
12 |
13 | |
14 | {% endfor %}
15 |
16 |
17 | Click here for full diff details.
18 |
--------------------------------------------------------------------------------
/action templates/email/file-diffs.liquid:
--------------------------------------------------------------------------------
1 | File Path, Changed Attributes, Owner, Change Type
2 | ---------------------------------------------------------------------------
3 | {% for diff in file_diffs %}{{ diff['file_path'] }}, {{ diff['changed_attributes'] | join: ":" }}, {{diff['owner'] }}, {{ diff['changed'] }}
4 | {% endfor %}
5 |
--------------------------------------------------------------------------------
/action templates/email/group-diffs.liquid:
--------------------------------------------------------------------------------
1 | {{ node_group_name }} Differences
2 |
For full results click here
3 |
4 | {% for ci in group_diffs %}
5 | {{ ci[0] | replace: ",", " > " }}
6 | {% for result in ci[1] %}
7 | Value on node(s): {% for node in result[1] %}{{ node }} {% endfor %}
8 | {{ result[0] }}
9 | {% endfor %}
10 |
11 |
12 | {% endfor %}
13 |
--------------------------------------------------------------------------------
/action templates/email/policy-failure-simple.liquid:
--------------------------------------------------------------------------------
1 | ###########################################################################################################
2 | # Description: Print out policy failure results. This will loop over affected nodes and construct a #
3 | # table detailing which policy checks have failed. #
4 | # Event variables required: scan_id OR (job_id AND policy_id) #
5 | # Example event: type=Policy Ran AND variables.success=false #
6 | # Website version required: >= v2.28.0 #
7 | ###########################################################################################################
8 |
9 | {% for f in failures %}
10 | Node name: {{ f[0] }}
11 |
12 |
13 | {% for c in f[1] %}
14 |
15 | Check: {{ c['name'] }} |
16 | Result: {{ c['result'] }} |
17 |
18 | {% for a in c['checks'] %}
19 | Attribute name | {{ a[0] }} |
20 | Expected | {{ a[1]['expected'] }} |
21 | Actual | {{ a[1]['actual'] }} |
22 | Result | {{ a[1]['result'] }} |
23 | {% endfor %}
24 | |
25 |
26 | {% endfor %}
27 |
28 | {% endfor %}
29 |
--------------------------------------------------------------------------------
/action templates/email/success-with-messages.liquid:
--------------------------------------------------------------------------------
1 | {% if warnings.size > 0 %}
2 |
3 | Messages for tasks:
4 |
5 | {% for warning in warnings %}
6 | {% if warning.messages.size > 0 %}
7 |
8 | Node: {{ warning.source_name }}
9 |
10 | {% for msg in warning.messages %}
11 | - {{ msg }}
12 | {% endfor %}
13 | {% endif %}
14 | {% endfor %}
15 | {% else %}
16 | No warnings were generated during this job
17 | {% endif %}
--------------------------------------------------------------------------------
/action templates/jira/file-diffs.liquid:
--------------------------------------------------------------------------------
1 | {noformat}
2 | File: {{ path }}
3 | Action: {{ subaction }}{% if new_name %}
4 | New Name: {{ new_name }}{% endif %}
5 | Username: {{ username }}
6 | Timestamp: {{ timestamp }}
7 | {noformat}
8 |
--------------------------------------------------------------------------------
/action templates/jira/job-url.liquid:
--------------------------------------------------------------------------------
1 | ###########################################################################################################
2 | # Description: Prints out a job URL. #
3 | # Event variables required: job_id #
4 | # Website version required: >= v2.28.0 #
5 | ###########################################################################################################
6 |
7 | *Job URL*
8 |
9 | {{job_url}}
10 |
--------------------------------------------------------------------------------
/action templates/jira/node-url.liquid:
--------------------------------------------------------------------------------
1 | ###########################################################################################################
2 | # Description: Prints out a node URL. #
3 | # Event variables required: node_id #
4 | # Website version required: >= v2.28.0 #
5 | ###########################################################################################################
6 |
7 | *Node URL*
8 |
9 | {{node_url}}
10 |
--------------------------------------------------------------------------------
/action templates/jira/policy-failures-detailed.liquid:
--------------------------------------------------------------------------------
1 | ###########################################################################################################
2 | # Description: Builds a table to display detailed policy failure results. #
3 | # Event variables required: node_id #
4 | # Website version required: >= v2.28.0 #
5 | ###########################################################################################################
6 |
7 | *Policy Failure Details*
8 |
9 | {% if node_policy_failures.size > 0 %}
10 | ||Check Path||Expected Value||Actual Value||Result||
11 | {% for f in node_policy_failures %}{% for c in f[1] %}|{{ f[0] }}, {{ c['name'] }}, {% for a in c['checks'] %}{{ a[0] }}|{% if a[1]['expected'] %}{{ a[1]['expected'] }}{% else %}Absent{% endif %}|{% if a[1]['actual'] %}{{ a[1]['actual'] }}{% else %}Absent{% endif %}|{% if a[1]['result'] == 'failure' %}{color:red}FAIL{color}{% else %}{color:#14892c}PASS{color}{% endif %}|
12 | {% endfor %}{% endfor %}{% endfor %}
13 | {% else %}
14 | No detailed policy results to display.
15 | {% endif %}
16 |
--------------------------------------------------------------------------------
/action templates/jira/policy-failures.liquid:
--------------------------------------------------------------------------------
1 | ###########################################################################################################
2 | # Description: Print out policy failure results. This will loop over affected nodes and construct a #
3 | # table detailing which policy checks have failed. #
4 | # Event variables required: scan_id OR (job_id AND policy_id) #
5 | # Example event: type=Policy Ran AND variables.success=false #
6 | # Website version required: >= v2.28.0 #
7 | ###########################################################################################################
8 |
9 | {% for f in failures %}
10 | *{{ f[0] }}*
11 | ||Check||Result||
12 | {% for p in f[1] %}|{{ p['name'] }}|{{ p['result'] }}|
13 | {% endfor %}
14 | {% endfor %}
15 |
16 | {{ job_url }}
17 |
--------------------------------------------------------------------------------
/action templates/jira/policy-results.liquid:
--------------------------------------------------------------------------------
1 | ###########################################################################################################
2 | # Description: Builds a table to display policy results (passing and failing). Color codes accordingly. #
3 | # Event variables required: Can only be used with the "Node First Scanned" event. #
4 | # Website version required: >= v2.28.0 #
5 | ###########################################################################################################
6 |
7 | *Policy Results*
8 |
9 | {% if policy_results.size > 0 %}
10 | ||Policy Name||Result||
11 | {% for p in policy_results %}|{{ p['policy'] }}|{% if p['passed'] == false %}{color:red}FAIL{color}{% else %}{color:#14892c}PASS{color}{% endif %}|
12 | {% endfor %}
13 | {% else %}
14 | No policy results to display.
15 | {% endif %}
16 |
--------------------------------------------------------------------------------
/action templates/slack/diffs.liquid:
--------------------------------------------------------------------------------
1 | {% for diff in diffs %}
2 | {{ diff['item'] }} {% if diff['old'] == nil %}Added{% elsif diff['new'] == nil %}Removed{% else %}Modified{% endif %}
3 | {% if diff['old'] != nil and diff['new'] != nil %}{% assign oldvalues = "" %}{% for att in diff['old'] %}{% assign oldvalues = oldvalues | append: att[0] | append: att[1] %}{% endfor %}{% for att in diff['new'] %}{% assign attstring = att[0] | append: att[1] %}{% unless oldvalues contains attstring %} - Attribute changed: {{ att[0] }} => {{ att[1] }}
4 | {% endunless %}{% endfor %}{% endif %}{% endfor %}
5 |
--------------------------------------------------------------------------------
/action templates/slack/policy-failures.liquid:
--------------------------------------------------------------------------------
1 | {{ policy }} failed on {% if ran_on == 'environment' %}environment <{{ instance_hostname }}/reports#/policy/{{ policy_id }}?environment={{ environment_id }}|{{ environment }}>{% elsif ran_on == 'group' %}group <{{ instance_hostname }}/reports#/policy/{{ policy_id }}?node_group={{ group_id }}|{{ group }}>{% else %}node <{{ node_url }}|{{ node }}>{% endif %}
2 |
--------------------------------------------------------------------------------
/api/perl/nodes-create-csv.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/perl
2 |
3 | use JSON::PP ("decode_json");
4 | use HTTP::Request;
5 | use LWP;
6 | use URI::URL;
7 |
8 | sub add_node {
9 | my (%args) = @_;
10 |
11 | my $body = new URI::URL;
12 | my %nodehash;
13 | foreach my $k (keys %args) {
14 | $nodehash{"node[$k]"} = $args{$k};
15 | }
16 |
17 | $body->query_form(\%nodehash);
18 | my $body_content = $body->as_string;
19 | $body_content =~ s/^.//;
20 |
21 | # NB: Swap in your custom URL below if you have a dedicated instance
22 | my $url = new URI::URL "https://guardrail.scriptrock.com" . "/api/v1/nodes.json";
23 | my $request = HTTP::Request->new(POST => $url,
24 | HTTP::Headers->new("Authorization" => "Token token=\"ABCD123456EF7890GH\"",
25 | "Accept" => "application/json"));
26 | $request->content($body_content);
27 | my $browser = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
28 |
29 | my $response = $browser->request($request);
30 | if ($response->is_success) {
31 | my $json = JSON::PP->new->decode($response->decoded_content);
32 | return $json;
33 | } else {
34 | print STDERR $response->status_line, "\n";
35 | return undef;
36 | }
37 | }
38 |
39 | my $file = $ARGV[0] or die "Need to get CSV file on the command line\n";
40 | open(my $data, '<', $file) or die "Could not open '$file' $!\n";
41 |
42 | while (my $line = <$data>) {
43 | chomp $line;
44 | my @fields = split "," , $line;
45 | if ($#fields == 5) {
46 | add_node(
47 | name => $fields[0],
48 | node_type => $fields[1],
49 | medium_type => $fields[2],
50 | medium_password => $fields[3],
51 | medium_username => $fields[4],
52 | connection_manager_group_id => $fields[5]
53 | );
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/api/perl/nodes-create.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/perl
2 |
3 | use JSON::PP ("decode_json");
4 | use HTTP::Request;
5 | use LWP;
6 | use URI::URL;
7 |
8 | my $node = {
9 | name => "host.com",
10 | node_type => "SV",
11 | medium_type => 3,
12 | medium_username => "username",
13 | medium_hostname => "hostname",
14 | connection_manager_group_id => 1
15 | }
16 |
17 | my $body = new URI::URL;
18 | $body->query_form(%node);
19 | my $body_content = $body->as_string;
20 | $body_content =~ s/^.//;
21 |
22 | # NB: Swap in your custom URL below if you have a dedicated instance
23 | my $url = new URI::URL "https://guardrail.scriptrock.com" .
24 | "/api/v1/nodes.json"
25 | my $request = HTTP::Request->new(GET => $url,
26 | HTTP::Headers->new("Authorization" => "Token token=\"AB123456CDEF7890GH\"",
27 | "Accept" => "application/json",
28 | "Content-Type" => "application/json"));
29 | $request->content($body_content);
30 | my $browser = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
31 |
32 | my $response = $browser->request($request);
33 | if ($response->is_success) {
34 | my $json = JSON::PP->new;
35 | $perl_scalar = $json->decode($response->decoded_content);
36 | $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing
37 | print $pretty_printed;
38 | } else {
39 | print STDERR $response->status_line, "\n";
40 | print undef;
41 | }
42 |
--------------------------------------------------------------------------------
/api/perl/nodes-lookup.pl:
--------------------------------------------------------------------------------
1 | use JSON::PP ("decode_json");
2 | use HTTP::Request;
3 | use LWP;
4 | use URI::URL;
5 |
6 | $api_key = 'api key here';
7 | $secret_key = 'secret key here';
8 | $url = 'appliance.url.here';
9 |
10 | my $url = new URI::URL $url .
11 | "/api/v1/nodes/42/add_to_node_group.json?node_group_id=23"
12 | my $request = HTTP::Request->new(GET => $url,
13 | HTTP::Headers->new("Authorization" => "Token token=\"" . $api_key . $secret_key . "\"",
14 | "Accept" => "application/json"));
15 | my $browser = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
16 |
17 | my $response = $browser->request($request);
18 | if ($response->is_success) {
19 | my $json = JSON::PP->new->decode($response->decoded_content);
20 | return $json;
21 | } else {
22 | print STDERR $response->status_line, "\n";
23 | return undef;
24 | }
--------------------------------------------------------------------------------
/api/perl/os-families-index.pl:
--------------------------------------------------------------------------------
1 | use JSON::PP ("decode_json");
2 | use HTTP::Request;
3 | use LWP;
4 | use URI::URL;
5 |
6 | my $url = new URI::URL "http://localhost:3000" .
7 | "/api/v1/operating_system_families.json";
8 | my $request = HTTP::Request->new(GET => $url,
9 | HTTP::Headers->new("Authorization" => "Token token=\"AB123456CDEF7890GH\"",
10 | "Accept" => "application/json"));
11 | my $browser = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
12 |
13 | my $response = $browser->request($request);
14 | if ($response->is_success) {
15 | my $json = JSON::PP->new;
16 | $perl_scalar = $json->decode($response->decoded_content);
17 | $pretty_printed = $json->pretty->encode($perl_scalar);
18 | print $pretty_printed;
19 | } else {
20 | print STDERR $response->status_line, "\n";
21 | print undef;
22 | }
23 |
--------------------------------------------------------------------------------
/api/perl/os-index.pl:
--------------------------------------------------------------------------------
1 | use JSON::PP ("decode_json");
2 | use HTTP::Request;
3 | use LWP;
4 | use URI::URL;
5 |
6 | my $url = new URI::URL "http://localhost:3000" .
7 | "/api/v1/operating_systems.json"
8 | my $request = HTTP::Request->new(GET => $url,
9 | HTTP::Headers->new("Authorization" => "Token token=\"AB123456CDEF7890GH\"",
10 | "Accept" => "application/json"));
11 | my $browser = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
12 |
13 | my $response = $browser->request($request);
14 | if ($response->is_success) {
15 | my $json = JSON::PP->new;
16 | $perl_scalar = $json->decode($response->decoded_content);
17 | $pretty_printed = $json->pretty->encode($perl_scalar);
18 | print $pretty_printed;
19 | } else {
20 | print STDERR $response->status_line, "\n";
21 | print undef;
22 | }
23 |
--------------------------------------------------------------------------------
/api/powershell/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudhousetech/content/84fda2a16d04f56def651abb4694c2afc0a3cce7/api/powershell/.keep
--------------------------------------------------------------------------------
/api/powershell/Add-File-Scan-Option.ps1:
--------------------------------------------------------------------------------
1 | param (
2 | [string]$URL = $env:GUARDIAN_URL,
3 | [string]$ApiKey = $env:GUARDIAN_API_KEY,
4 | [string]$SecretKey = $env:GUARDIAN_SECRET_KEY,
5 | [string]$NodeGroup,
6 | [string]$ScanOption,
7 | [switch]$Insecure = $(if ($env:GUARDIAN_INSECURE -eq "true") { $true } else { $false })
8 | )
9 | $Headers = @{'Authorization' = "Token token=""$($ApiKey)$($SecretKey)"""; 'Accept' = 'application/json'; 'Content-Type' = 'application/json'}
10 |
11 | # Get the ID for the node group
12 | $GroupID = (Invoke-WebRequest -Headers $Headers -Method "GET" -Uri "$($URL)/api/v2/node_groups/lookup.json?name=$($NodeGroup)" -SkipCertificateCheck:$Insecure|ConvertFrom-Json).node_group_id
13 | if (-not $GroupID) { Write-Output "Couldn't find node group '$($NodeGroup)'";return }
14 | Write-Output "$($NodeGroup) has ID $($GroupID)"
15 |
16 | # Get the current scan options for the node group
17 | $FileScanOptions = (Invoke-WebRequest -Headers $Headers -Method "GET" -Uri "$($URL)/api/v2/node_groups/$($GroupID)/node_group_configuration.json" -SkipCertificateCheck:$Insecure|ConvertFrom-Json).scan_options.scan_directory_options
18 | if ($FileScanOptions -eq $null) { $FileScanOptions = @() }
19 |
20 | if ($ScanOption -eq "") { Write-Output "Existing file scan options: $($FileScanOptions)"; return }
21 |
22 | # Add the new scan option to the file scan options
23 | $Exists = $false
24 | ForEach ($o in $FileScanOptions) { if ($o.path -eq $ScanOption) { $Exists = $true } }
25 | if (-not $Exists)
26 | {
27 | # Add the scan option
28 | Write-Output "Adding file scan option: $($ScanOption)"
29 | $FileScanOptions += @{ path = $ScanOption }
30 | $Body = @{ option_name = "scan_directory_options" ; scan_directory_options = $FileScanOptions }
31 | Write-Output (Invoke-WebRequest -Method "PUT" -Headers $Headers -Uri "$($URL)/api/v2/node_groups/$($GroupID)/set_scan_options.json" -Body (ConvertTo-Json $Body) -SkipCertificateCheck:$Insecure).Content
32 | } else { Write-Output "File scan option already exists: $($ScanOption)" }
33 |
34 | Write-Output "Done!"
35 |
--------------------------------------------------------------------------------
/api/powershell/Get-JiraCloudNode.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Scans Jira Cloud configuration for Guardian Script Path (Windows) node type
4 | .DESCRIPTION
5 | Gets application properties, advanced settings and configuration from Jira Cloud API using basic auth and returns it as JSON compatible for use in Guardian's Script Path (Windows) node type
6 | .PARAMETER JiraHostname
7 | Host name of Jira cloud you want to connect to. e.g. 'company.atlassian.net'
8 | .PARAMETER Username
9 | Your Jira username
10 | .PARAMETER ApiToken
11 | Your personal Jira ApiToken
12 | .EXAMPLE
13 | .\Get-JiraCloudNode.ps1 -JiraHostName 'company.atlassian.net' -Username you@company.com -ApiToken {{password}}
14 |
15 | Using this as the script path in Guardian node configuration will scan your Jira configuration
16 | #>
17 |
18 | param (
19 | [Parameter(Mandatory = $true)]
20 | [string]$JiraHostname,
21 | [Parameter(Mandatory = $true)]
22 | [string]$Username,
23 | [Parameter(Mandatory = $true)]
24 | [string]$ApiToken
25 | )
26 |
27 | Set-Variable JiraRestUri -Option Constant -Value ("https://$JiraHostname" + '/rest/api/3/')
28 | $headers = @{Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("${Username}:${ApiToken}")))" }
29 |
30 | $applicationProperties = Invoke-RestMethod ($JiraRestUri + 'application-properties') -Headers $headers
31 | $advancedSettings = Invoke-RestMethod ($JiraRestUri + 'application-properties/advanced-settings') -Headers $headers
32 | $configuration = Invoke-RestMethod ($JiraRestUri + 'configuration') -Headers $headers
33 |
34 | # convert property array into hash
35 | $appPropertyHash = @{}
36 | $applicationProperties | ForEach-Object {
37 | $property = $_
38 | $appPropertyHash[($property.key)] = $property
39 | }
40 |
41 | $advancedSettingsHash = @{}
42 | $advancedSettings | ForEach-Object {
43 | $setting = $_
44 | $advancedSettingsHash[($setting.key)] = $setting
45 | }
46 |
47 |
48 | ConvertTo-Json @{'Application Properties' = $appPropertyHash
49 | 'Advanced Settings' = $advancedSettingsHash
50 | 'Configuration' = @{'Configuration' = $configuration}
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/api/powershell/Get-LastPassNode.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Scans LastPass for Guardian Script Path (Windows) node type
4 |
5 | .DESCRIPTION
6 | Uses LastPass enterprise API to return user and shared folder information for display in Guardian
7 |
8 | .PARAMETER Cid
9 | Your lastpass company id - available from admin dashboard
10 |
11 | .PARAMETER ProvHash
12 | You provisioning hash from LastPass UI
13 |
14 | .EXAMPLE
15 | .\Get-LastPassNode.ps1 -cid yourcid -ProvHash {{password}}
16 |
17 | Using this as your script path in node configuration will scan LastPass user and shared folder data and present it as a Guardian node
18 | #>
19 |
20 | param (
21 | [Parameter(Mandatory = $true)]
22 | [string]$cid,
23 | [Parameter(Mandatory = $true)]
24 | [string]$provHash
25 | )
26 |
27 | $body = @{
28 | cid = $cid
29 | provhash = $provHash
30 | cmd = 'getuserdata'
31 | apiuser = 'guardian'
32 | }
33 |
34 |
35 |
36 | $response = Invoke-RestMethod 'https://lastpass.com/enterpriseapi.php' -Method POST -Body (ConvertTo-json $body)
37 |
38 | $users = @{}
39 | $response.Users | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name | ForEach-Object {
40 | $id = $_
41 | $user = $response.Users.$id
42 | $users.($user.Username) = $user
43 | }
44 |
45 | $results = @{Users=$users}
46 |
47 | $body.cmd = 'getsfdata'
48 |
49 | $response = Invoke-RestMethod 'https://lastpass.com/enterpriseapi.php' -Method 'POST' -Body (ConvertTo-json $body)
50 |
51 | $sharedFolders = @{}
52 | $response | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name | ForEach-Object {
53 | $id = $_
54 | $sf = $response.$id
55 | if ($sf.deleted -eq $true) {return}
56 | $sf | Add-Member -MemberType NoteProperty -Name 'Admins' -Value ($sf.users | Where-Object { $_.can_administer -eq 1} | Select-Object -ExpandProperty username)
57 | $sf | Add-Member -MemberType NoteProperty -Name 'Readonly' -Value ($sf.users | Where-Object { $_.readonly -eq 1} | Select-Object -ExpandProperty username)
58 | $sf | Add-Member -MemberType NoteProperty -Name 'Hide Password' -Value ($sf.users | Where-Object { $_.give -eq 0} | Select-Object -ExpandProperty username)
59 | $sf.Users = $sf.users | Select-Object -ExpandProperty username
60 | $sharedFolders.($sf.sharedfoldername) = $sf
61 | }
62 |
63 | $results['Shared Folders'] = $sharedFolders
64 |
65 | ConvertTo-Json -Depth 4 $results
--------------------------------------------------------------------------------
/api/powershell/Get-PingdomNode.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Scans checks in pingdom for Guardian Script Path (Windows) node type
4 |
5 | .PARAMETER APIToken
6 | Your token for access the pingdom api
7 |
8 | .EXAMPLE
9 | .\Get-PingdomNode.ps1 -APIToken {{password}}
10 |
11 | Using the above as the script path in the node configuration and setting the password field with your Pingdom api token will securely scan pingdom checks.
12 | #>
13 |
14 | param (
15 | [Parameter(Mandatory=$true)]
16 | [string]$APIToken
17 | )
18 |
19 | $headers = @{Authorization='Bearer ' + $APIToken}
20 | $response = Invoke-RestMethod 'https://api.pingdom.com/api/3.1/checks' -Headers $headers
21 |
22 | # grab parts of the resp
23 | $checksArray = $response.checks
24 | $counts = $response.counts
25 |
26 | # convert the array to hash using name as key
27 | $checks = @{}
28 | $checksArray | ForEach-Object {
29 | $ele = $_
30 | $key = $ele.name.ToString()
31 | $checks[$key] = $ele
32 | }
33 |
34 | # intermediate node for 2 layers
35 | $res = [pscustomobject]@{
36 | 'Pingdom Checks' = $checks
37 | counts = [pscustomobject]@{all=$counts}
38 | }
39 |
40 | ConvertTo-Json $res
41 |
--------------------------------------------------------------------------------
/api/powershell/adding-winrm-nodes.ps1:
--------------------------------------------------------------------------------
1 | [System.Net.ServicePointManager]::DefaultConnectionLimit = 1000
2 | # Uncomment if using a self-signed certificate
3 | # [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
4 |
5 | $global:server = 'companyname.scriptrock.net'
6 | $global:url = "https://" + $server + "/api/v1"
7 | $apiKey = ""
8 | $secretKey = ""
9 | $global:headers = @{
10 | Authorization = 'Token token="' + $apiKey + $secretKey + '"'
11 | }
12 |
13 | $MyURI = [System.Uri]$global:url
14 | $ServicePoint = [System.Net.ServicePointManager]::FindServicePoint($MyURI)
15 | $ServicePoint.CloseConnectionGroup("")
16 |
17 | function createNode($name)
18 | {
19 | Write-Host "createNode $name"
20 | $body = @{
21 | node = @{
22 | name = $name;
23 | medium_hostname = $name;
24 | node_type = "SV";
25 | medium_type = 7;
26 | medium_port = 5985;
27 | operating_system_family_id = 1;
28 | connection_manager_group_id = ;
29 | }
30 | } | ConvertTo-json -Depth 5
31 |
32 | Invoke-RestMethod -Method Post -Uri ($global:url + "/nodes.json") -Headers $global:headers -Body $body -ContentType "application/json; charset=utf-8"
33 | }
34 |
35 | $names = @( 'node1', 'node2', 'node3' )
36 | foreach ($name in $names) {
37 | createNode $name
38 | }
39 |
--------------------------------------------------------------------------------
/api/powershell/ci-query.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudhousetech/content/84fda2a16d04f56def651abb4694c2afc0a3cce7/api/powershell/ci-query.pdf
--------------------------------------------------------------------------------
/api/powershell/custom_reporting_with_api.ps1:
--------------------------------------------------------------------------------
1 | $instanceUrl = "https://serverurl.net"
2 | $apiKey = "apiKey"
3 | $secretKey = "secretKey"
4 | $headers = @{
5 | 'Authorization' = 'Token token="' + $apiKey + $secretKey + '"';
6 | }
7 |
8 | $cmURL = $instanceUrl + "/api/v2/connection_manager_groups.json"
9 | $envURL = $instanceUrl + "/api/v2/environments.json"
10 | $ngURL = $instanceUrl + "/api/v2/node_groups.json"
11 |
12 | # Get all the lists of Nodes, CM Groups, Environments and Node Groups
13 | $connectionManagerGroups = Invoke-RestMethod -Method "GET" -Uri $cmURL -Headers $headers
14 | $environments = Invoke-RestMethod -Method "GET" -Uri $envURL -Headers $headers
15 | $nodeGroups = Invoke-RestMethod -Method "GET" -Uri $ngURL -Headers $headers
16 |
17 | # Create Hashtables for CM Groups, Node Groups and Environments with ID and Name
18 |
19 | $listConnectionManagers = @{}
20 | $listEnvironment = @{}
21 | $listNodeGroups = @{}
22 |
23 | foreach($cm in $connectionManagerGroups) {
24 | $listConnectionManagers.Add($cm.id, $cm.name)
25 | }
26 |
27 | foreach($env in $environments) {
28 | $listEnvironment.Add($env.id, $env.name)
29 | }
30 |
31 | foreach($ng in $nodeGroups) {
32 | $listNodeGroups.Add($ng.id, $ng.name)
33 | }
34 |
35 | # Get Node Data via API
36 |
37 | for ($i = 1; $i -le 50; $i++ )
38 | {
39 | $nodeIndex = $instanceUrl + "/api/v2/nodes.json?page=" + $i + "&per_page=50"
40 | $nodes += Invoke-RestMethod -Method "GET" -Uri $nodeIndex -Headers $headers
41 | }
42 |
43 | # Get details for each node and dump data into the CSV
44 |
45 | $fullString = "Node Name, Connection Manager Group, Environment, Node Group, External ID" + "`n"
46 |
47 | foreach($node in $nodes) {
48 | $node = Invoke-RestMethod -Method "GET" -Uri $node.url -Headers $headers
49 |
50 | $cmID = $node.connection_manager_group_id
51 | $envID = $node.environment_id
52 | $ngID = $node.primary_node_group_id
53 |
54 | if ($node.name) { $nodeCSV = $node.name + ", "} else {$nodeCSV = "Null Name, "}
55 | if ($cmID) {$nodeCSV += $listConnectionManagers.Get_Item($cmID) + ", "} else {$nodeCSV += "null, "}
56 | if ($envID) {$nodeCSV += $listEnvironment.Get_Item($envID) + ", "} else {$nodeCSV += "null, "}
57 | if ($ngID) {$nodeCSV += $listNodeGroups.Get_Item($ngID) + ", "} else {$nodeCSV += "null, "}
58 | if ($node.external_id) {$nodeCSV += $node.external_id + "`n"} else {$nodeCSV += "null" + "`n"}
59 |
60 | $fullString += $nodeCSV
61 | }
62 |
63 | $fullString | Set-Content 'export.csv'
64 |
--------------------------------------------------------------------------------
/api/powershell/enable-winrm-https-1.ps1:
--------------------------------------------------------------------------------
1 | $MyFQDN = "$env:computername.$env:userdnsdomain"
2 | $CertFile = $env:userprofile + "\" + $MyFQDN
3 |
4 | # Create a self-signed certificate and install it
5 | $Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName $MyFQDN
6 |
7 | # Save the certificate for later export to another box
8 | Export-Certificate -Cert $Cert -FilePath $CertFile
9 |
10 | # Ensure that PSRemoting is enabled
11 | Enable-PSRemoting -SkipNetworkProfileCheck -Force
12 |
13 | # (Optional) Remove the WinRM HTTP listener
14 | Get-ChildItem WSMan:\Localhost\listener | Where -Property Keys -eq "Transport=HTTP" | Remove-Item -Recurse
15 |
16 | # (Optional) Disable the firewall rule for HTTP
17 | Disable-NetFirewallRule -DisplayName "Windows Remote Management (HTTP-In)"
18 |
19 | # Create a HTTPS listener with our certificate thumbprint
20 | New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint –Force
21 |
22 | # Allow inbound traffic on port 5986
23 | New-NetFirewallRule -DisplayName "Windows Remote Management (HTTPS-In)" -Name "Windows Remote Management (HTTPS-In)" -Profile Any -LocalPort 5986 -Protocol TCP
24 |
--------------------------------------------------------------------------------
/api/powershell/enable-winrm-https-2.ps1:
--------------------------------------------------------------------------------
1 | Import-Certificate -Filepath "C:\Path\To\Certificate" -CertStoreLocation "Cert:\LocalMachine\Root"
2 |
--------------------------------------------------------------------------------
/api/powershell/extract-automation-snippets.ps1:
--------------------------------------------------------------------------------
1 | param (
2 | [string]$fileName,
3 | [string]$newFileName,
4 | [string]$node,
5 | [string]$pattern,
6 | [string]$type,
7 | [string]$ciType
8 | )
9 |
10 | $apiKey = "[API_KEY]"
11 | $secretKey = "[SECRET_KEY]"
12 | $headers = @{Authorization = 'Token token="' + $apiKey + $secretKey + '"'}
13 |
14 | $hasInserted = $false
15 | $scanURI = "https://qa.upguard.org/api/v2/nodes/" + $node + "/automation_snippet?type=" + $type + "&ci_type=" + $ciType
16 | $result = Invoke-RestMethod -Method "GET" -Uri $scanURI -Headers $headers
17 | $result = $result.Split("`n")
18 |
19 | Get-Content($fileName) |
20 | Foreach-Object {
21 | if ($_ -match $pattern -and !$hasInserted) {
22 | echo $result
23 | $hasInserted = $true
24 | }
25 | else {
26 | echo $_
27 | }
28 | } | Set-Content($newFileName)
29 |
30 | #Format:
31 | # > .\extract-automation-snippets.ps1 "c:\oldfilename.txt" "c:\newfilename.txt" "node #" "pattern to search for in file"
32 | # "automation type parameter" "CI type parameter"
33 |
--------------------------------------------------------------------------------
/api/powershell/get-last-login-events.ps1:
--------------------------------------------------------------------------------
1 | $Events = @{}
2 | $Days = 2
3 | $computer = $env:COMPUTERNAME
4 |
5 | $eventlogs = Get-EventLog System -Source Microsoft-Windows-WinLogon -After (Get-Date).AddDays(-$Days) -ComputerName $Computer
6 | #$eventlogs = $eventlogs | sort InstanceID,Time -Descending
7 | If ($eventlogs)
8 | {
9 |
10 | $eventlogssort = @()
11 | ForEach ($log in $eventlogs)
12 | {
13 | $User = (New-Object System.Security.Principal.SecurityIdentifier $Log.ReplacementStrings[1]).Translate([System.Security.Principal.NTAccount])
14 | if($events.ContainsKey("$User") -eq $false) {
15 | $events["$User"] = New-Object Object
16 | $events["$User"] | Add-Member -MemberType NoteProperty -Name "User" -Value "$User"
17 | }
18 |
19 | if($log.InstanceID -eq 7001) {
20 | $events["$User"] | Add-Member -MemberType NoteProperty -Name "$($log.TimeWritten)" -Value "Log on"
21 | } elseif ($log.InstanceID -eq 7002) {
22 | $events["$User"] | Add-Member -MemberType NoteProperty -Name "$($log.TimeWritten)" -Value "Log 0ff"
23 | }
24 | }
25 | }
26 |
27 | $events.Values
--------------------------------------------------------------------------------
/api/powershell/get-used-space.ps1:
--------------------------------------------------------------------------------
1 | $freespace = Get-WmiObject -Class Win32_logicalDisk | ? {$_.DriveType -eq '3'}
2 | $drive = ($FreeSpace.DeviceID).Split("=")
3 | $temp = '' | Select FreeSpace, Drive
4 | $temp.FreeSpace = $freespace.Size - $freespace.FreeSpace
5 | $temp.Drive = $drive[0]
6 | $temp
7 |
--------------------------------------------------------------------------------
/api/powershell/ignore_ssl_cert_check.ps1:
--------------------------------------------------------------------------------
1 | add-type @"
2 | using System.Net;
3 | using System.Security.Cryptography.X509Certificates;
4 | public class TrustAllCertsPolicy : ICertificatePolicy {
5 | public bool CheckValidationResult(
6 | ServicePoint srvPoint, X509Certificate certificate,
7 | WebRequest request, int certificateProblem) {
8 | return true;
9 | }
10 | }
11 | "@
12 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
13 |
--------------------------------------------------------------------------------
/api/powershell/iis-site-logs-enabled.ps1:
--------------------------------------------------------------------------------
1 | Import-Module WebAdministration
2 |
3 | $output = @()
4 | foreach ($site in Get-ChildItem IIS:\Sites) {
5 | $obj = New-Object -TypeName PSObject
6 | $obj | Add-Member -MemberType NoteProperty -Name Name -Value $site.name
7 | $sitePath = "IIS:\Sites\" + $site.name
8 | $logsEnabled = (GI $sitePath).logfile.enabled
9 | $obj | Add-Member -MemberType NoteProperty -Name LogsEnabled -Value $logsEnabled
10 | $output += $obj
11 | }
12 | $output
13 |
14 |
--------------------------------------------------------------------------------
/api/powershell/node-group-attach-policy.ps1:
--------------------------------------------------------------------------------
1 | ########################################################################################
2 | # Author: UpGuard #
3 | # Description: This script will add a policy (latest policy version) to a node group. #
4 | # Last updated: April 26, 2017 #
5 | ########################################################################################
6 |
7 | # Setup API
8 | $upGuardServer = 'https://your.instance.url'
9 | $secretKey = '<< secret key >>'
10 | $serviceAccount = '<< api key >>'
11 |
12 | # Setup variables
13 | $NodeGroupID = x # The node group you are wanting to attach the policy to.
14 | $policyId = y # The policy to attach.
15 |
16 | # Uncomment if using a self-signed certificate
17 | add-type @"
18 | using System.Net;
19 | using System.Security.Cryptography.X509Certificates;
20 | public class TrustAllCertsPolicy : ICertificatePolicy {
21 | public bool CheckValidationResult(
22 | ServicePoint srvPoint, X509Certificate certificate,
23 | WebRequest request, int certificateProblem) {
24 | return true;
25 | }
26 | }
27 | "@
28 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
29 |
30 | $headers = @{'Authorization' = 'Token token="' + $serviceAccount + $secretKey + '"'
31 | 'Accept' = 'application/json'
32 | 'Content-Type' = 'application/json'
33 | }
34 |
35 | # Make an API call to query the "last" policy version Id.
36 | $getPolicyVersionsCall = $upGuardServer + "/api/v2/policies/" + $policyId + "/versions"
37 | $policyVersions = Invoke-RestMethod -Uri $getPolicyVersionsCall -Headers $headers -Method Get
38 |
39 | "Policy versions found for policy id " + $policyId + " ..."
40 | $policyVersions
41 |
42 | # Policy version id at array index -1 is the "latest" policy version
43 | $latestPolicyVersionId = 0
44 | if ($policyVersions -and $policyVersions[-1]) {
45 | $latestPolicyVersionId = ($policyVersions[-1]).id
46 | }
47 |
48 | # If this is stil 0 (the default value), then something has gone wrong.
49 | if ($latestPolicyVersionId -eq 0) {
50 | "Error: latest policy version not found, quitting."
51 | return
52 | } else {
53 | "Latest policy version id is " + $latestPolicyVersionId
54 | }
55 |
56 | # Make an API call to attach the latest policy version to the node group.
57 | $addPVToNodeGroupCall = $upGuardServer + "/api/v2/node_groups/"+$NodeGroupID + "/add_policy_version?policy_version_id=" + $latestPolicyVersionId
58 | try {
59 | $addPVToNodeGroup = Invoke-RestMethod -Uri $addPVToNodeGroupCall -Headers $headers -Method post
60 | "Attached policy_version_id " + $addPVToNodeGroup.policy_version_id + " to node_group_id " + $addPVToNodeGroup.node_group_id
61 | } catch {
62 | "Policy version already attached or API call has invalid parameters."
63 | }
64 |
--------------------------------------------------------------------------------
/api/powershell/node-update-alternate-password.ps1:
--------------------------------------------------------------------------------
1 | # Update the alternate_password for a particular SSH node.
2 | # Can be used to set empty ("") passwords.
3 |
4 | # Ignore SSL certificate errors. Comment out if not needed.
5 | add-type @"
6 | using System.Net;
7 | using System.Security.Cryptography.X509Certificates;
8 | public class TrustAllCertsPolicy : ICertificatePolicy {
9 | public bool CheckValidationResult(
10 | ServicePoint srvPoint, X509Certificate certificate,
11 | WebRequest request, int certificateProblem) {
12 | return true;
13 | }
14 | }
15 | "@
16 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
17 |
18 | $target_url = "<< target_url >>" # Without scheme
19 | $api_key = "<< api_key >>"
20 | $secret_key = "<< secret_key >>"
21 | $node_id = << node_id >>
22 | $new_password = "" # Blank
23 |
24 | $headers = @{'Authorization' = 'Token token="' + $api_key + $secret_key + '"';
25 | 'Accept' = 'application/json'; 'Content-Type' = 'application/json'}
26 |
27 | # Need to perform an additional lookup to get detailed node information.
28 | $node_details = Invoke-WebRequest -Uri ("https://" + $target_url + "/api/v2/nodes/" + $node_id) -Headers $headers -Method "GET"
29 | $node_details = ConvertFrom-Json -InputObject $node_details
30 |
31 | # Only update password for SSH nodes.
32 | if ($node_details.medium_type -ne 7)
33 | {
34 | "Node is not an SSH node, quitting."
35 | continue
36 | }
37 |
38 | "Updating node id {0} alternate_password..." -f $node_id
39 |
40 | $body = @{"node" = @{"alternate_password" = $new_password}}
41 | $body = ConvertTo-Json -InputObject $body
42 |
43 | $response = Invoke-WebRequest -Uri ("https://" + $target_url + "/api/v2/nodes/ " + $node_id + ".json") -Body $body -Headers $headers -Method "PUT"
44 | if ($response.StatusCode > 400)
45 | {
46 | throw [System.Exception] $response.StatusCode.ToString() + " " + $response.StatusDescription
47 | } else {
48 | $response
49 | }
50 |
--------------------------------------------------------------------------------
/api/powershell/node-update-ssh-creds.ps1:
--------------------------------------------------------------------------------
1 | # For SSH nodes in a particular node group, update their username/password.
2 | # Use -dry_run to see what would be changed
3 |
4 | # Ignore SSL certificate errors. Comment out if not needed.
5 | add-type @"
6 | using System.Net;
7 | using System.Security.Cryptography.X509Certificates;
8 | public class TrustAllCertsPolicy : ICertificatePolicy {
9 | public bool CheckValidationResult(
10 | ServicePoint srvPoint, X509Certificate certificate,
11 | WebRequest request, int certificateProblem) {
12 | return true;
13 | }
14 | }
15 | "@
16 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
17 |
18 |
19 | $target_url = "<< upguard_appliance_hostname >>" # Without scheme
20 | $api_key = "<< api_key >>"
21 | $secret_key = "<< secret_key >>"
22 | $node_group_id = "<< node_group_id >>"
23 | $new_username = "<< new_username >>"
24 | $new_password = "<< new_password >>"
25 | $dry_run = $true
26 |
27 | $headers = @{'Authorization' = 'Token token="' + $api_key + $secret_key + '"';
28 | 'Accept' = 'application/json'; 'Content-Type' = 'application/json'}
29 |
30 | $nodes = Invoke-WebRequest -Uri ("https://" + $target_url + "/api/v2/node_groups/$node_group_id/nodes.json?page=1&per_page=500") -Headers $headers -Method "GET"
31 |
32 | if ($nodes.StatusCode > 400)
33 | {
34 | throw [System.Exception] $nodes.StatusCode.ToString() +
35 | " " + $nodes.StatusDescription
36 | }
37 | else
38 | {
39 | $nodes = ConvertFrom-Json -InputObject $nodes
40 |
41 | ForEach ($node in $nodes)
42 | {
43 | # Need to perform an additional lookup to get detailed node information.
44 | $node_details = Invoke-WebRequest -Uri ("https://" + $target_url + "/api/v2/nodes/" + $node.id) -Headers $headers -Method "GET"
45 | $node_details = ConvertFrom-Json -InputObject $node_details
46 |
47 | # Only update username/password for SSH nodes.
48 | if ($node_details.medium_type -ne 3) { continue }
49 |
50 | "Updating node {0} username/password" -f $node.name
51 | $body = @{"node" = @{"medium_username" = $new_username; "medium_password" = $new_password}}
52 | $body = ConvertTo-Json -InputObject $body
53 |
54 | if ($dry_run -eq $false)
55 | {
56 | $response = Invoke-WebRequest -Uri ("https://" + $target_url + "/api/v2/nodes/ " + $node.id + ".json") -Body $body -Headers $headers -Method "PUT"
57 | if ($response.StatusCode > 400)
58 | {
59 | throw [System.Exception] $response.StatusCode.ToString() + " " + $response.StatusDescription
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/api/powershell/node_diff.ps1:
--------------------------------------------------------------------------------
1 | # Ignore self-signed SSL certificates
2 | add-type @"
3 | using System.Net;
4 | using System.Security.Cryptography.X509Certificates;
5 | public class TrustAllCertsPolicy : ICertificatePolicy {
6 | public bool CheckValidationResult(
7 | ServicePoint srvPoint, X509Certificate certificate,
8 | WebRequest request, int certificateProblem) {
9 | return true;
10 | }
11 | }
12 | "@
13 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
14 |
15 |
16 | $instance_url = "https://upguard.appliance.url"
17 | $api_key = "<< api_key >>"
18 | $secret_key = "<< service_key >>"
19 | $headers = @{
20 | 'Authorization' = 'Token token="' + $api_key + $secret_key + '"'
21 | 'Accept' = 'application/json'
22 | }
23 |
24 | $scan_id = "<< scan_id >>"
25 | $compare_scan_id = "<< compare_scan_id >>"
26 |
27 | $node_diff_endpoint = $instance_url + "/api/v2/nodes/diff?scan_id=[scan_id]?compare_scan_id=[compare_scan_id]"
28 |
29 | $node_diff_endpoint = $node_diff_endpoint.Replace("[scan_id]", $scan_id)
30 | $node_diff_endpoint = $node_diff_endpoint.Replace("[compare_scan_id]", $compare_scan_id)
31 |
32 | $response = Invoke-WebRequest $node_diff_endpoint -Method Get -Headers $headers
33 |
34 | if ($response.StatusCode -ge 299) {
35 | throw [System.Exception] $response.StatusCode.ToString() + " " + $response.StatusDescription
36 | }
37 | else {
38 | $diff = $response.Content | ConvertFrom-Json
39 | if ($diff.summary) {
40 | "Diff Summary Stats"
41 | "=================="
42 | $diff.summary
43 | }
44 | if ($diff[1]) {
45 | "Diff Details"
46 | "============"
47 | $diff_details = $diff[1]
48 | $diff_details
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/api/powershell/nodes-create-csv-ps2.ps1:
--------------------------------------------------------------------------------
1 | $apiKey = "YOUR API KEY HERE"
2 | $secretKey = "YOUR SECRET KEY HERE"
3 | $token = $apiKey + $secretKey
4 | $headerPart1 = 'Authorization'
5 | $headerPart2 = 'Token token="' + $token + '"'
6 | # NB: Swap in your custom URL below if you have a dedicated instance
7 | $uri = "https://guardrail.scriptrock.com/api/v1/nodes"
8 | $version = $PSVersionTable.PSVersion.Major
9 |
10 | function add_node($node) {
11 | $body = ''
12 | foreach($kvp in $node["node"].GetEnumerator()) {
13 | $body += 'node[' + $kvp.Key + ']=' + $kvp.Value + '&'
14 | }
15 |
16 | $body = $body.TrimEnd('&')
17 | $enc = [system.Text.Encoding]::UTF8
18 | $bodyBytes = $enc.GetBytes($body)
19 |
20 | # PowerShell 2.0 way
21 | $request = [System.Net.HTTPWebRequest]::Create($uri)
22 | $request.Method="Post"
23 | $request.ContentType = "application/json"
24 | $request.Headers.Set($headerPart1, $headerPart2)
25 | $request.ContentType = "application/x-www-form-urlencoded"
26 | $request.Accept = "application/json"
27 |
28 | $dataStream = $request.GetRequestStream()
29 | $dataStream.Write($bodyBytes, 0, $bodyBytes.Length)
30 | $dataStream.Close()
31 |
32 | $requestStream = $request.GetResponse().GetResponseStream()
33 | $readStream = New-Object System.IO.StreamReader $requestStream
34 | $data = $readStream.ReadToEnd()
35 | $readStream.Dispose();
36 | $readStream.Close();
37 |
38 | # The loading of this dll assumes that even though you are on PowerShell 2.0 you have .NET 3.5 installed
39 | [System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
40 | $serialization = New-Object System.Web.Script.Serialization.JavaScriptSerializer
41 | $results = $serialization.DeserializeObject($data)
42 | return $results
43 | }
44 |
45 | foreach ($row in Import-Csv -Header name,nodetype,mediumtype,mediumhostname,mediumusername,mediumpassword,mediumport,connectionmanagergroupid,operatingsystemfamilyid,operatingsystemid "nodes.csv")
46 | {
47 | $node = @{
48 | "node" = @{
49 | "name" = $row.name;
50 | "node_type" = $row.nodetype;
51 | "medium_type" = $row.mediumtype;
52 | "medium_hostname" = $row.mediumhostname;
53 | "medium_username" = $row.mediumusername;
54 | "medium_password" = $row.mediumpassword;
55 | "medium_port" = $row.mediumport;
56 | "connection_manager_group_id" = $row.connectionmanagergroupid;
57 | "operating_system_family_id" = $row.operatingsystemfamilyid;
58 | "operating_system_id" = $row.operatingsystemid;
59 | }
60 | }
61 | add_node($node)
62 | }
63 |
--------------------------------------------------------------------------------
/api/powershell/nodes-create-csv.ps1:
--------------------------------------------------------------------------------
1 | $apiKey = "YOUR SERVICE API KEY"
2 | $secretKey = "YOUR SECRET KEY"
3 | $uri = "https://guardrail.scriptrock.com/api/v1/nodes"
4 | $csvFileLocation = "C:\location\to\nodes.csv"
5 | $token = $apiKey + $secretKey
6 |
7 | Function add_node($node)
8 | {
9 | try {
10 | $headers = @{
11 | 'Authorization' = 'Token token="' + $token + '"'
12 | 'Accept' = 'application/json'
13 | }
14 |
15 | $body = ''
16 | foreach($kvp in $node["node"].GetEnumerator()) {
17 | $body += 'node[' + $kvp.Key + ']=' + $kvp.Value + '&'
18 | }
19 | $body = $body.TrimEnd('&')
20 | $body
21 |
22 | $req = Invoke-WebRequest $uri -Method POST -Headers $headers -Body $body
23 | $req.Content | ConvertFrom-Json
24 |
25 | } catch [System.Net.WebException] {
26 | if ($_.Exception.Response) {
27 | $_.Exception.Response
28 | $bodyStream = $_.Exception.Response.GetResponseStream()
29 | $bodyReader = New-Object System.IO.StreamReader($bodyStream)
30 | $bodyReader.BaseStream.Position = 0
31 | $bodyReader.DiscardBufferedData()
32 | $bodyReader.ReadToEnd()
33 | } else { # e.g. SSL errors
34 | $_.Exception.Message
35 | }
36 | } catch {
37 | $_.Exception.Message
38 | }
39 | }
40 |
41 | foreach ($row in Import-Csv -Header name,nodetype,mediumtype,mediumhostname,mediumusername,mediumpassword,mediumport,connectionmanagergroupid,operatingsystemfamilyid,operatingsystemid $csvFileLocation)
42 | {
43 | $node = @{
44 | "node" = @{
45 | "name" = $row.name
46 | "node_type" = $row.nodetype
47 | "medium_type" = $row.mediumtype
48 | "medium_hostname" = $row.mediumhostname
49 | "medium_username" = $row.mediumusername
50 | "medium_password" = $row.mediumpassword
51 | "medium_port" = $row.mediumport
52 | "connection_manager_group_id" = $row.connectionmanagergroupid
53 | "operating_system_family_id" = $row.operatingsystemfamilyid
54 | "operating_system_id" = $row.operatingsystemid
55 | }
56 | }
57 | add_node($node)
58 | }
59 |
--------------------------------------------------------------------------------
/api/powershell/nodes-create.ps1:
--------------------------------------------------------------------------------
1 | $apiKey = "1234"
2 | $secretKey = "5678"
3 |
4 | $node = @{
5 | 'name' = 'host.com';
6 | 'node_type' = 'SV';
7 | 'medium_type' = 3;
8 | 'medium_username' = 'username';
9 | 'medium_hostname' = 'hostname';
10 | 'medium_port' = 22;
11 | 'connection_manager_group_id' = 1
12 | }
13 |
14 |
15 | $headers = @{
16 | 'Authorization' = 'Token token="' + $apiKey + $secretKey + '"';
17 | }
18 |
19 | $body = ''
20 | foreach($kvp in $node.GetEnumerator()) {
21 | $body += 'node[' + $kvp.Key + ']=' + $kvp.Value + '&'
22 | }
23 |
24 | $body = $body.TrimEnd('&')
25 |
26 | # NB: Swap in your custom URL below if you have a dedicated instance
27 | $req = Invoke-WebRequest "https://guardrail.scriptrock.com/api/v1/nodes.json" -Method Post -Headers $headers -Body $body
28 |
29 | if ($req.StatusCode -ge 400) {
30 | throw [System.Exception] $req.StatusCode.ToString() +
31 | " " + $req.StatusDescription
32 | }
33 | else {
34 | $req.Content | ConvertFrom-Json
35 | }
36 |
--------------------------------------------------------------------------------
/api/powershell/nodes-lookup.ps1:
--------------------------------------------------------------------------------
1 | $secret_key = 'secret key goes here'
2 | $api_key = 'api key goes here'
3 | $url = 'appliance.url.here'
4 |
5 | $headers = @{'Authorization' = 'Token token="' + $api_key + $secret_key + '"';
6 | 'Accept' = 'application/json'}
7 |
8 | $req = Invoke-WebRequest
9 | "http://" + $url + "/api/v1/nodes/42/add_to_node_group.json?node_group_id=23"
10 | -Method "Post" -Headers $headers
11 |
12 | if ($req.StatusCode > 400)
13 | {
14 | throw [System.Exception] $req.StatusCode.ToString() +
15 | " " + $req.StatusDescription
16 | }
17 | else
18 | {
19 | $req.Content | ConvertFrom-Json
20 | }
--------------------------------------------------------------------------------
/api/powershell/nodes.csv:
--------------------------------------------------------------------------------
1 | name,SV,7,hostname,,,5985,2,1,123
--------------------------------------------------------------------------------
/api/powershell/os-families-index.ps1:
--------------------------------------------------------------------------------
1 | $secret_key = 'secret key goes here'
2 | $api_key = 'api key goes here'
3 | $url = 'appliance.url.here'
4 |
5 | $headers = @{'Authorization' = 'Token token="' + $api_key + $secret_key + '"';
6 | 'Accept' = 'application/json'}
7 |
8 | $req = Invoke-WebRequest "http://" + $url + "/api/v1/operating_system_families.json" -Headers $headers
9 |
10 | if ($req.StatusCode > 400)
11 | {
12 | throw [System.Exception] $req.StatusCode.ToString() +
13 | " " + $req.StatusDescription
14 | }
15 | else
16 | {
17 | $req.Content | ConvertFrom-Json
18 | }
19 |
--------------------------------------------------------------------------------
/api/powershell/os-index.ps1:
--------------------------------------------------------------------------------
1 | $secret_key = 'secret key goes here'
2 | $api_key = 'api key goes here'
3 | $url = 'appliance.url.here'
4 |
5 | $headers = @{'Authorization' = 'Token token="' + $api_key + $secret_key + '"';
6 | 'Accept' = 'application/json'}
7 |
8 | $req = Invoke-WebRequest
9 | "http://" + $url + "/api/v1/operating_systems.json" `
10 | -Headers $headers
11 |
12 | if ($req.StatusCode > 400)
13 | {
14 | throw [System.Exception] $req.StatusCode.ToString() +
15 | " " + $req.StatusDescription
16 | }
17 | else
18 | {
19 | $req.Content | ConvertFrom-Json
20 | }
21 |
--------------------------------------------------------------------------------
/api/powershell/powershell-2-web-requests.ps1:
--------------------------------------------------------------------------------
1 | $apiKey = "YOUR_API_KEY_HERE"
2 | $secretKey = " YOUR_SECRET_KEY_HERE "
3 | $token = $apiKey + $secretKey
4 | $headerPart1 = 'Authorization'
5 | $headerPart2 = 'Token token="' + $token + '"'
6 | $uri = "https://YOUR_GUARDRAIL/api/v1/node_groups/GROUP_NUMBER/nodes.json"
7 | $version = $PSVersionTable.PSVersion.Major
8 |
9 | # PowerShell 2.0 way
10 | $request = [System.Net.HTTPWebRequest]::Create($uri)
11 | $request.Method="Get"
12 | $request.ContentType = "application/json"
13 | $request.Headers.Set($headerPart1, $headerPart2)
14 |
15 | $requestStream = $request.GetResponse().GetResponseStream()
16 | $readStream = New-Object System.IO.StreamReader $requestStream
17 | $data = $readStream.ReadToEnd()
18 | $readStream.Dispose();
19 | $readStream.Close();
20 |
21 | # The loading of this dll assumes that even though you are on PowerShell 2.0 you have .NET 3.5 installed
22 | [System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
23 | $serialization = New-Object System.Web.Script.Serialization.JavaScriptSerializer
24 | $results = $serialization.DeserializeObject($data)
25 |
26 | # Raw results
27 | $results
28 |
--------------------------------------------------------------------------------
/api/powershell/query_vuln_endpoint.ps1:
--------------------------------------------------------------------------------
1 | $apiKey = "[enter API key here]"
2 | $secretKey = "[enter secret key here]"
3 | $headers = @{Authorization = 'Token token="' + $apiKey + $secretKey + '"'}
4 |
5 | $vulnScanURI = "https://app.upguard.com/api/v2/vulns.json?page="
6 | $counter = 1
7 |
8 | do {
9 | $name = $vulnScanURI + $counter
10 | $result = Invoke-RestMethod -Method "GET" -Uri $name -Headers $headers
11 | $counter += 1
12 | echo $result
13 | }
14 | until($result.length -eq 0)
15 |
--------------------------------------------------------------------------------
/api/powershell/retrieve-backups.ps1:
--------------------------------------------------------------------------------
1 | # Author: UpGuard
2 | # Email: support@upguard.com
3 | # Description: BitsTransfer for downloading very large files without using an excessive amount of system memory.
4 |
5 | Import-Module BitsTransfer
6 |
7 | $username = "<< backup username >>"
8 | $password = "<< backup password >>"
9 | $password_secure = ConvertTo-SecureString $password -AsPlainText -Force
10 | $credentials = New-Object System.Management.Automation.PSCredential ($username, $password_secure)
11 | $backup_endpoint = "https://<< your.appliance.hostname >>/backups/latest.tar.gz"
12 | $backup_location = "C:\Backups\"
13 | $backup_file = Get-Date -Format yyyy-MM-ddTHH-mm-ss
14 | $backup_filepath = $backup_location + $backup_file + ".tar.gz"
15 |
16 | # We make a unique display name for the transfer so that it can be uniquely
17 | # referenced by name and will not return an array of jobs if we have run the
18 | # script multiple times simultaneously.
19 | $display_name = "MyBitsTransfer " + (Get-Date)
20 |
21 | Start-BitsTransfer `
22 | -Source $backup_endpoint `
23 | -Destination $backup_filepath `
24 | -DisplayName $display_name `
25 | -Authentication Basic `
26 | -Credential $credentials `
27 | -Asynchronous
28 |
29 | # Enable CRL Check, Ignore invalid common name in server certificate, Ignore invalid date in server certificate
30 | # & "bitsadmin" /SetSecurityFlags $display_name 7
31 |
32 | $job = Get-BitsTransfer $display_name
33 |
34 | # Create a holding pattern while we wait for the connection to be established
35 | # and the transfer to actually begin. Otherwise the next Do...While loop may
36 | # exit before the transfer even starts. Print the job status as it changes
37 | # from Queued to Connecting to Transferring.
38 | # If the download fails, remove the bad job and exit the loop.
39 | $lastStatus = $job.JobState
40 | Do {
41 | If ($lastStatus -ne $job.JobState) {
42 | $lastStatus = $job.JobState
43 | $job
44 | }
45 | If ($lastStatus -like "*Error*") {
46 | Write-Host "Error connecting to download."
47 | Write-Host $job.ErrorDescription
48 | Get-BitsTransfer | Complete-BitsTransfer
49 | Exit
50 | }
51 | }
52 | while ($lastStatus -ne "Transferred" -and $lastStatus -ne "Transferring")
53 | $job
54 |
55 | # Print the transfer status as we go:
56 | # Date & Time BytesTransferred BytesTotal PercentComplete
57 | do {
58 | Write-Host (Get-Date) $job.BytesTransferred $job.BytesTotal `
59 | ($job.BytesTransferred/$job.BytesTotal*100)
60 | Start-Sleep -s 10
61 | }
62 | while ($job.BytesTransferred -lt $job.BytesTotal)
63 |
64 | # Print the final status once complete.
65 | Write-Host (Get-Date) $job.BytesTransferred $job.BytesTotal `
66 | ($job.BytesTransferred/$job.BytesTotal*100)
67 |
68 | Complete-BitsTransfer $job
69 |
70 | # Only keep the last two backups. There is no need to store backups beyond this.
71 | # We sort by Name because it includes a DateTime stamp.
72 | $backup_files = Get-ChildItem $backup_location -Filter *.tar.gz | Sort Name -Descending
73 | if ($backup_files.count -gt 2) {
74 | Remove-Item $backup_files[-1].FullName
75 | }
76 |
77 | #Get-BitsTransfer
78 | #Get-BitsTransfer | Complete-BitsTransfer
79 | #net stop BITS
80 | #net start BITS
81 |
--------------------------------------------------------------------------------
/api/powershell/scan-nodes-in-node-group.ps1:
--------------------------------------------------------------------------------
1 | $apiKey = "[API_KEY]"
2 | $secretKey = "[SECRET_KEY]"
3 | $headers = @{Authorization = 'Token token="' + $apiKey + $secretKey + '"'}
4 |
5 |
6 | #Get the list of nodes in the node group
7 | $nodeGroupsURI = "https://[SERVER]/api/v2/node_groups/[NODEGROUPID]/nodes.json"
8 | $nodes = Invoke-RestMethod -Method "GET" -Uri $nodeGroupsURI -Headers $headers
9 |
10 | #Loop over each node in the group and call start scan
11 | foreach($node in $nodes)
12 | {
13 | $url = $node.url + "/start_scan.json?label=[LABEL_HERE]"
14 | Invoke-RestMethod -Method "POST" -Uri $url -Headers $headers
15 | }
16 |
--------------------------------------------------------------------------------
/api/powershell/set-hostname-to-display-name.ps1:
--------------------------------------------------------------------------------
1 | # For every node in an UpGuard instance, set the hostname to match the display name
2 | # Use -dry_run to see what would be changed
3 |
4 | param (
5 | [Parameter(Mandatory=$true)][string]$target_url,
6 | [Parameter(Mandatory=$true)][string]$api_key,
7 | [Parameter(Mandatory=$true)][string]$secret_key,
8 | [switch]$dry_run
9 | )
10 |
11 | $headers = @{'Authorization' = 'Token token="' + $api_key + $secret_key + '"';
12 | 'Accept' = 'application/json'; 'Content-Type' = 'application/json'}
13 |
14 | $nodes = Invoke-WebRequest -Uri ("https://" + $target_url + "/api/v2/nodes.json?page=1&per_page=500") -Headers $headers -Method "GET"
15 |
16 | if ($nodes.StatusCode > 400)
17 | {
18 | throw [System.Exception] $nodes.StatusCode.ToString() +
19 | " " + $nodes.StatusDescription
20 | }
21 | else
22 | {
23 | $nodes = ConvertFrom-Json -InputObject $nodes
24 | $total = $nodes.Count
25 | $count = 1
26 | ForEach ($node in $nodes)
27 | {
28 | $hostname = $node.name
29 | "Setting node {0} hostname to {1} ({2}/{3})" -f $node.name, $hostname, $count, $total
30 | $body = @{"node" = @{"medium_hostname" = $hostname}}
31 | $body = ConvertTo-Json -InputObject $body
32 |
33 | if ($dry_run -eq $false)
34 | {
35 | $response = Invoke-WebRequest -Uri ("https://" + $target_url + "/api/v2/nodes/ " + $node.id + ".json") -Body $body -Headers $headers -Method "PUT"
36 | if ($response.StatusCode > 400)
37 | {
38 | throw [System.Exception] $response.StatusCode.ToString() + " " + $response.StatusDescription
39 | }
40 | }
41 |
42 | $count = $count + 1
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/api/powershell/simple-email-for-policy-failure.ps1:
--------------------------------------------------------------------------------
1 | # This script will send a simple email (no UpGuard headings) when it picks up a policy failure
2 | # This should be run once a day, after the policy has been run (which is after an environment scan has completed)
3 |
4 | $secret_key = 'secret key goes here'
5 | $api_key = 'api key goes here'
6 | $url = 'appliance.url.here'
7 | $policy_id = 0
8 | $insecure = $true
9 |
10 | # Email Settings
11 | $smtp_server = ""
12 | $from = ""
13 | $to = ""
14 | $subject = "UpGuard Policy Failed"
15 |
16 | $headers = @{'Authorization' = 'Token token="' + $api_key + $secret_key + '"'}
17 | $endpoint = "$($url)/api/v2/policies/$($policy_id)/latest_results.json?failed_only=true"
18 |
19 | if ($insecure)
20 | {
21 | add-type @"
22 | using System.Net;
23 | using System.Security.Cryptography.X509Certificates;
24 | public class TrustAllCertsPolicy : ICertificatePolicy {
25 | public bool CheckValidationResult(
26 | ServicePoint srvPoint, X509Certificate certificate,
27 | WebRequest request, int certificateProblem) {
28 | return true;
29 | }
30 | }
31 | "@
32 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
33 | }
34 |
35 | $req = Invoke-WebRequest $endpoint -Headers $headers -ContentType "application/json"
36 |
37 | if ($req)
38 | {
39 | if ($req.StatusCode > 400)
40 | {
41 | throw [System.Exception] $req.StatusCode.ToString() +
42 | " " + $req.StatusDescription
43 | }
44 | else
45 | {
46 | $json = $req.Content | ConvertFrom-Json
47 | Write-Output "Found $($json.policy_stats.Count) failed policies"
48 | if ($json.policy_stats.Count -gt 0)
49 | {
50 | $message = "The following nodes have failed:`n`n"
51 | foreach ($result in $json.policy_stats)
52 | {
53 | $message += "* $($result.name)`n"
54 | }
55 | # Send-MailMessage -SmtpServer $smtp_server -From $from -To $to -Body $message
56 | Write-Output $message
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/api/powershell/snippets/UpGuard-WebRequest.ps1:
--------------------------------------------------------------------------------
1 | # Perform an API request and return the result as a Powershell object
2 | # If you need to handle pagination, you can provide the Paginate switch with a CombineAttribute if you
3 | # need to combine pages on a specific attribute
4 | # For example, the /api/v2/nodes.json endpoint returns a list so pages can be combined and return a list
5 | # just by passing the Paginate switch
6 | # Alternatively, the /api/v2/diffs.json endpoint returns statistics along with a "diff_items" attribute
7 | # which contains the list of diffs. Passing the Paginate switch with "diff_items" for CombineAttribute
8 | # will return a usable list
9 | function UpGuard-WebRequest
10 | {
11 | param
12 | (
13 | [string]$Method = 'Get',
14 | [string]$Endpoint,
15 | [string]$ApiKey,
16 | [string]$SecretKey,
17 | [hashtable]$Body = @{},
18 | [switch]$Paginate,
19 | [string]$CombineAttribute = "" # To paginate, provide the attribute to combine multiple results
20 | )
21 |
22 | # Handle very large JSON responses (such as scan data)
23 | # [void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
24 | # $jsonserial= New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer
25 | # $jsonserial.MaxJsonLength = 67108864
26 |
27 | $headers = @{'Authorization' = "Token token=""$($ApiKey)$($SecretKey)"""}
28 | if ($Paginate) {
29 | $result = @()
30 | if ($Body.Keys -notcontains "page") { $Body.page = 1 }
31 | if ($Body.Keys -notcontains "per_page") { $Body.per_page = 50 }
32 | while ($true) {
33 | $new = Invoke-WebRequest -Method $Method -Uri $Endpoint -Headers $headers -Body $Body -ContentType "application/json"
34 | if ($new.StatusCode > 400){throw [System.Exception] "$($new.StatusCode.ToString()) $($new.StatusDescription)"}
35 | $new = ConvertFrom-Json $new.Content
36 |
37 | if ($CombineAttribute -ne "") {
38 | $new = $new | Select -ExpandProperty $CombineAttribute
39 |
40 | $result += $new
41 | if ([int]$new.Count -lt [int]$Body.per_page) { return $result}
42 | }
43 | else {
44 | # No CombineAttribute was provided
45 | $result += $new
46 | if ([int]$new.Count -lt [int]$Body.per_page) { return $result }
47 | }
48 | $Body.page = [int]$Body.page + 1
49 | }
50 | }
51 | if ($Method -in "Get","Delete"){$req = Invoke-WebRequest -Method $Method -Uri $Endpoint -Headers $headers -ContentType "application/json"}
52 | else{$req = Invoke-WebRequest -Method $Method -Uri $Endpoint -Headers $headers -Body $Body -ContentType "application/json"}
53 | if ($req)
54 | {
55 | if ($req.StatusCode > 400){throw [System.Exception] "$($req.StatusCode.ToString()) $($req.StatusDescription)"}
56 | # else{return $jsonserial.DeserializeObject($req.Content)}
57 | else { return ConvertFrom-Json $req.Content }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/api/powershell/update-externalid-from-ad.ps1:
--------------------------------------------------------------------------------
1 | # For all nodes in UpGuard, update the external id by pulling the LDAP DN from AD
2 | # You will be prompted for credentials to query AD
3 |
4 | param (
5 | [string]$ApiKey = '',
6 | [string]$SecretKey = '',
7 | [string]$Url = 'https://',
8 | [string]$DomainController = '',
9 | [switch]$Insecure,
10 | [switch]$DryRun
11 | )
12 |
13 | # Ignore SSL certificate if `-insecure` is used
14 | if ($Insecure)
15 | {
16 | add-type @"
17 | using System.Net;
18 | using System.Security.Cryptography.X509Certificates;
19 | public class TrustAllCertsPolicy : ICertificatePolicy {
20 | public bool CheckValidationResult(
21 | ServicePoint srvPoint, X509Certificate certificate,
22 | WebRequest request, int certificateProblem) {
23 | return true;
24 | }
25 | }
26 | "@
27 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
28 | }
29 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls11 -bor [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::SSL3 -bor [System.Net.SecurityProtocolType]::TLS;
30 |
31 | $creds = (Get-Credential)
32 |
33 | $headers = @{'Authorization' = "Token token=""$($ApiKey)$($SecretKey)""";
34 | 'Accept' = 'application/json'; 'Content-Type' = 'application/json'}
35 |
36 | $nodes = Invoke-WebRequest -Uri "https://$($Url)/api/v2/nodes.json?page=1&per_page=50000" -Headers $headers -Method "GET"
37 |
38 | if ($nodes.StatusCode > 400)
39 | {
40 | throw [System.Exception] "$($nodes.StatusCode.ToString()) $($nodes.StatusDescription)"
41 | }
42 | else
43 | {
44 | $nodes = ConvertFrom-Json -InputObject $nodes
45 |
46 | ForEach ($node in $nodes)
47 | {
48 | # Need to perform an additional lookup to get detailed node information.
49 | $node_details = Invoke-WebRequest -Uri "https://$($Url)/api/v2/nodes/$($node.id).json" -Headers $headers -Method "GET"
50 | $node_details = ConvertFrom-Json -InputObject $node_details
51 |
52 | $dn = Get-ADComputer -Identity "$($node_details.name)" -Credential $creds -Server $DomainController
53 | $external_id = "LDAP://$($dn.DistinguishedName)"
54 |
55 | if ($DryRun -eq $false)
56 | {
57 | "Updating node $($node_details.name) external id to $($external_id)"
58 | $body = @{"node" = @{"external_id" = $external_id}}
59 | $body = ConvertTo-Json -InputObject $body
60 | $response = Invoke-WebRequest -Uri "https://$($Url)/api/v2/nodes/$($node.id).json" -Body $body -Headers $headers -Method "PUT"
61 | if ($response.StatusCode > 400)
62 | {
63 | throw [System.Exception] "$($response.StatusCode.ToString()) $($response.StatusDescription)"
64 | }
65 | } else {
66 | "Would update node $($node_details.name) external id to $($external_id)"
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/api/powershell/update-password-from-node-group.ps1:
--------------------------------------------------------------------------------
1 | # For all nodes in a node group, update the password for each node
2 |
3 | ###############
4 | # Configuration
5 | ###############
6 |
7 | $target_url = "" # Hostname only, without scheme (leave off https)
8 | $api_key = ""
9 | $secret_key = ""
10 | $from_node_group = 0
11 | $password = ""
12 | $dry_run = $true
13 |
14 | ###################
15 | # End Configuration
16 | ###################
17 |
18 | # Ignore SSL certificate errors. Comment out if not needed.
19 | add-type @"
20 | using System.Net;
21 | using System.Security.Cryptography.X509Certificates;
22 | public class TrustAllCertsPolicy : ICertificatePolicy {
23 | public bool CheckValidationResult(
24 | ServicePoint srvPoint, X509Certificate certificate,
25 | WebRequest request, int certificateProblem) {
26 | return true;
27 | }
28 | }
29 | "@
30 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
31 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls11 -bor [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::SSL3 -bor [System.Net.SecurityProtocolType]::TLS;
32 |
33 | $headers = @{'Authorization' = "Token token=""$($api_key)$($secret_key)""";
34 | 'Accept' = 'application/json'; 'Content-Type' = 'application/json'}
35 |
36 | $nodes = Invoke-WebRequest -Uri "https://$($target_url)/api/v2/node_groups/$($from_node_group)/nodes.json?page=1&per_page=50000" -Headers $headers -Method "GET"
37 |
38 | if ($nodes.StatusCode > 400)
39 | {
40 | throw [System.Exception] "$($nodes.StatusCode.ToString()) $($nodes.StatusDescription)"
41 | }
42 | else
43 | {
44 | $nodes = ConvertFrom-Json -InputObject $nodes
45 |
46 | ForEach ($node in $nodes)
47 | {
48 | if ($dry_run -eq $false)
49 | {
50 | Write-Host -NoNewline "Updating password for node $($node.name)..."
51 | $body = @{"node" = @{"medium_password" = $password}}
52 | $body = ConvertTo-Json -InputObject $body
53 | $response = Invoke-WebRequest -Uri "https://$($target_url)/api/v2/nodes/$($node.id).json" -Body $body -Headers $headers -Method "PUT"
54 | if ($response.StatusCode -eq 204) { Write-Host "OK" }
55 | if ($response.StatusCode > 400)
56 | {
57 | Write-Host "ERROR"
58 | throw [System.Exception] "$($response.StatusCode.ToString()) $($response.StatusDescription)"
59 | }
60 | } else {
61 | "Would update medium_password for node $($node.name)"
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/api/powershell/upload-csv.ps1:
--------------------------------------------------------------------------------
1 | param(
2 | [string]$url='',
3 | [string]$apiKey='',
4 | [string]$secretKey='',
5 | [string]$file=''
6 | )
7 |
8 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
9 |
10 | function webRequest($requestUrl, $method='GET', $body=$null) {
11 | $headers = @{Authorization = 'Token token="' + $apiKey + $secretKey + '"'}
12 | $response = $null
13 |
14 | try {
15 | Write-Host (@{ 'node' = $body } | ConvertTo-JSON)
16 | $response = Invoke-WebRequest -Uri $requestUrl -Headers $headers -Method $method -Body (@{ 'node' = $body } | ConvertTo-Json) -ContentType 'application/json'
17 | } catch {
18 | Write-Host $_
19 | }
20 | return $response
21 | }
22 |
23 | $index = 0
24 |
25 | Import-Csv $file | ForEach-Object {
26 | $body = @{}
27 | $row = $_
28 | $row | Get-Member -MemberType NoteProperty | ForEach-Object {
29 | $body[$_.Name] = $row."$($_.Name)"
30 | }
31 |
32 | $response = webRequest ($url + "/api/v2/nodes.json") 'Post' $body
33 |
34 | if ($response -eq $null -or $response.StatusCode -gt 299) {
35 | Write-Host "Failed to upload row $($index), response code was: $($response.StatusCode)"
36 | }
37 |
38 | $index++
39 | }
--------------------------------------------------------------------------------
/api/python/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudhousetech/content/84fda2a16d04f56def651abb4694c2afc0a3cce7/api/python/.keep
--------------------------------------------------------------------------------
/api/python/change-nodes-environment.py:
--------------------------------------------------------------------------------
1 | import httplib;
2 | import urllib;
3 | import ssl;
4 | import json;
5 |
6 | # Parameters and constants
7 | api_key = 'api key here'
8 | secret_key = 'secret key here'
9 | url = 'appliance.url.here' # use only FQDN, leave out the 'https://' portion
10 | fromEnv = 4 # Set an environment id to transfer from
11 | toEnv = 3 # Set an environment id to transfer to
12 |
13 | try:
14 | # browser = httplib.HTTPConnection(url)
15 | # -- For HTTPS connections
16 | context = ssl._create_unverified_context()
17 | browser = httplib.HTTPSConnection(url, context=context)
18 | get_headers = {"Authorization": 'Token token="' + api_key + secret_key + '"',
19 | "Accept": "application/json"}
20 | browser.request("GET", "/api/v2/nodes.json", '', get_headers)
21 | get_res = browser.getresponse()
22 | # read() must be called before close(), or it will return an empty string
23 | data = get_res.read()
24 | if get_res.status >= 400:
25 | raise httplib.HTTPException(str(get_res.status) + ' ' +
26 | get_res.reason + (': ' + data.strip() if data.strip() else ''))
27 | else:
28 | print str(get_res.status) + get_res.reason;
29 |
30 | if data != '':
31 | nodes = json.loads(data)
32 | for node in nodes:
33 | node_id = node['id']
34 | environment_id = node['environment_id']
35 |
36 | if environment_id == fromEnv:
37 | # Change the node's environment_id = toEnv
38 | output = {'node' : { 'environment_id' : toEnv }}
39 | body = json.dumps(output)
40 | # Begin http connection for API call
41 | # conn = httplib.HTTPConnection(url)
42 | # -- For HTTPS connections
43 | conn = httplib.HTTPSConnection(url, context=context)
44 | put_headers = {"Authorization": 'Token token="' + api_key + secret_key + '"',
45 | "Accept": "application/json", 'Content-Type':'application/json'}
46 | conn.request("PUT", "/api/v2/nodes/" + str(node_id) +".json",
47 | body, put_headers)
48 | update_res = conn.getresponse()
49 | if update_res.status >= 400:
50 | raise httplib.HTTPException(str(update_res.status) + ' ' +
51 | update_res.reason + (': ' + data.strip() if data.strip() else ''))
52 | conn.close();
53 | # close() must be called after each request, or subsequent requests will fail
54 | browser.close()
55 |
56 | except httplib.HTTPException as h:
57 | print h.message;
58 | finally:
59 | browser.close()
60 |
--------------------------------------------------------------------------------
/api/python/custom-node-remote.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import json
4 | import subprocess
5 |
6 | command_list = [
7 | {'command_name': ['ls'], 'command_args': ['-la', '/var/log']},
8 | {'command_name': ['hostname'], 'command_args': []},
9 | {'command_name': ['find'], 'command_args': ['/var/log', '-name', '*.conf']}
10 | ]
11 |
12 | def generate_scan(commands, host=None):
13 | output_data = {
14 | 'Commands': {}
15 | }
16 |
17 | for c in commands:
18 | command_output = execute_command(c, host)
19 | output_data['Commands'][c['command_name'][0]] = {
20 | 'Output': {
21 | 'StdOut': command_output
22 | }
23 | }
24 |
25 |
26 | print(json.dumps(output_data, sort_keys=True,
27 | indent=4, separators=(',', ': ')))
28 |
29 | def execute_command(command, host=None):
30 | if host is not None:
31 | ssh = subprocess.Popen(["ssh", "%s" % host] + command['command_name'] + command['command_args'],
32 | shell=False,
33 | stdout=subprocess.PIPE,
34 | stderr=subprocess.PIPE)
35 | ssh.stdout.flush()
36 | result, error = ssh.communicate()
37 | if result == []:
38 | print >> sys.stderr, "ERROR: %s" % error
39 | return None
40 | else:
41 | return result
42 | else:
43 | process = subprocess.Popen(command['command_name'] + command['command_args'], stdout=subprocess.PIPE)
44 | process.stdout.flush()
45 | process_output, error = process.communicate()
46 | if process_output == []:
47 | print >> sys.stderr, "ERROR: %s" % error
48 | return None
49 | else:
50 | return process_output
51 |
52 | generate_scan(command_list, "user@the.server.address")
53 |
--------------------------------------------------------------------------------
/api/python/custom-node.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import json
4 | import subprocess
5 |
6 | command_list = [
7 | {'command_name': ['ls'], 'command_args': ['-la', '/var/log']},
8 | {'command_name': ['hostname'], 'command_args': []},
9 | {'command_name': ['find'], 'command_args': ['/var/log', '-name', '*.conf']}
10 | ]
11 |
12 | def generate_scan(commands):
13 | output_data = {
14 | 'Commands': {}
15 | }
16 |
17 | for c in commands:
18 | process = subprocess.Popen(c['command_name'] + c['command_args'], stdout=subprocess.PIPE)
19 | process.stdout.flush()
20 | process_output = process.communicate()
21 | output_data['Commands'][c['command_name'][0]] = {
22 | 'Output': {
23 | 'StdOut': process_output[0]
24 | }
25 | }
26 |
27 |
28 | print(json.dumps(output_data, sort_keys=True,
29 | indent=4, separators=(',', ': ')))
30 |
31 | generate_scan(command_list)
32 |
--------------------------------------------------------------------------------
/api/python/find-environment-id-by-name.py:
--------------------------------------------------------------------------------
1 | # pip3 install upguard
2 | import upguard
3 |
4 | api_key = "1234"
5 | sec_key = "5678"
6 | instance = "https://you.upguard.com"
7 |
8 | o = upguard.Account(instance, api_key, sec_key)
9 |
10 | env = o.environment_by_name("Production")
11 |
12 | print("EnvironmentID:" + str(env.id))
13 |
--------------------------------------------------------------------------------
/api/python/find-nodes-without-external-id.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import httplib
4 | import urllib
5 | import json
6 | import ssl
7 | import argparse
8 | import re
9 |
10 | parser = argparse.ArgumentParser(description='Find any node that does not have an external ID set.')
11 | parser.add_argument('--target-url', required=True, help='URL for the UpGuard instance. This should be the hostname only (appliance.upguard.org instead of https://appliance.upguard.org)')
12 | parser.add_argument('--api-key', required=True, help='API key for the UpGuard instance')
13 | parser.add_argument('--secret-key', required=True, help='Secret key for the UpGuard instance')
14 | parser.add_argument('--insecure', action='store_true', help='Ignore SSL certificate check?')
15 | parser.add_argument('--per-page', type=int, default=100, help='Number of nodes to retrieve in each call. (Default: 100)')
16 | args = parser.parse_args()
17 |
18 | # Initializations
19 | browser = None
20 |
21 | def getNodes(browser, method, endpoint, page=1, per_page=100):
22 | """
23 | Return a JSON-parsed dictionary of nodes
24 | """
25 | get_headers = {
26 | "Authorization": "Token token=\"{}{}\"".format(args.api_key, args.secret_key),
27 | "Accept": "application/json"}
28 |
29 | browser.request("GET", "{}?page={}&per_page={}".format(endpoint, page, per_page), '', get_headers)
30 | response = browser.getresponse()
31 | if response.status >= 400:
32 | raise httplib.HTTPException("{}: {}".format(str(response.status), str(response.reason)))
33 |
34 | return json.loads(response.read())
35 |
36 | try:
37 | # Setup browser object
38 | url = args.target_url
39 | if 'http' in url:
40 | # URL needs to be a hostname, so remove 'https://'
41 | url = re.sub('https?:\/\/', '', url)
42 | browser = httplib.HTTPConnection(url)
43 | if args.insecure:
44 | context = ssl._create_unverified_context()
45 | browser = httplib.HTTPSConnection(url, context=context)
46 |
47 | page = 1
48 | nodes = getNodes(browser, "GET", "/api/v2/nodes.json", page=page, per_page=args.per_page)
49 | print "Searching for nodes without an external ID..."
50 | while nodes:
51 | for node in nodes:
52 | if not node['external_id']:
53 | print "{} (hostname: {})".format(node['name'])
54 |
55 | page += 1
56 | nodes = getNodes(browser, "GET", "/api/v2/nodes.json", page=page, per_page=args.per_page)
57 |
58 | except httplib.HTTPException as h:
59 | print h.message;
60 | finally:
61 | if browser:
62 | browser.close()
63 |
--------------------------------------------------------------------------------
/api/python/get-last-node-scan.py:
--------------------------------------------------------------------------------
1 | import httplib;
2 | import urllib;
3 | import json;
4 | import sys;
5 |
6 | def recurse_to_key(obj, key):
7 | if isinstance(obj, dict):
8 | for k, value in obj.iteritems():
9 | if k == key:
10 | return obj[k]
11 | else:
12 | data = recurse_to_key(value, key)
13 | if data != None:
14 | try:
15 | if isinstance(data, unicode):
16 | return json.loads(unicodedata.normalize('NFKD', data).encode('ascii','ignore'))
17 | else:
18 | return json.loads(data)
19 | except:
20 | return data
21 | elif isinstance(obj, list):
22 | for avalue in obj:
23 | data = recurse_to_key(avalue, key)
24 | if data != None:
25 | try:
26 | if isinstance(data, unicode):
27 | return json.loads(unicodedata.normalize('NFKD', data).encode('ascii','ignore'))
28 | else:
29 | return json.loads(data)
30 | except:
31 | return data
32 | else:
33 | try:
34 | parsed = json.loads(obj)
35 | sdata = recurse_to_key(parsed, key)
36 | if sdata != None:
37 | try:
38 | if isinstance(sdata, unicode):
39 | return json.loads(unicodedata.normalize('NFKD', sdata).encode('ascii','ignore'))
40 | else:
41 | return json.loads(sdata)
42 | except:
43 | return sdata
44 | except:
45 | pass
46 |
47 | return None
48 |
49 | def get_key_info(json_string, key):
50 | parsed = json.loads(json_string)
51 | return recurse_to_key(parsed, key)
52 |
53 | hostname = "your.appliance.address"
54 | api_key = "11111"
55 | secret_key = "222222"
56 |
57 | try:
58 | browser = httplib.HTTPConnection(hostname)
59 |
60 | browser.request("GET", "/api/v2/nodes/1/last_node_scan_details?with_data=true", '',
61 | {"Authorization": "Token token=\"" + api_key + secret_key + "\"",
62 | "Accept": "application/json"})
63 | res = browser.getresponse()
64 | data = res.read()
65 |
66 | if res.status >= 400:
67 | raise httplib.HTTPException(str(res.status) + ' ' +
68 | res.reason + (': ' + data.strip() if data.strip() else ''))
69 |
70 | browser.close()
71 |
72 | if data != '':
73 | print(json.dumps(get_key_info(data, "Sublime Text")['version'], indent=4))
74 | else:
75 | print str(res.status) + res.reason;
76 | except httplib.HTTPException as h:
77 | print h.message;
78 | finally:
79 | browser.close()
80 |
--------------------------------------------------------------------------------
/api/python/get_file_from_node.py:
--------------------------------------------------------------------------------
1 | import csv
2 | import httplib;
3 | import urllib;
4 | import json;
5 | import argparse;
6 |
7 | api_key = 'YOUR API KEY HERE'
8 | secret_key = 'YOUR SECRET KEY HERE'
9 | url = 'your.url.here'
10 |
11 | def get_file_id(node, file_path):
12 | browser = httplib.HTTPConnection(url)
13 | try:
14 | browser.request('GET', '/api/v2/nodes/' + str(node) + '/ci_data?ci_type=files', '',
15 | {'Authorization': 'Token token="' + api_key + secret_key + '"',
16 | 'Accept':'application/json'})
17 | res = browser.getresponse()
18 |
19 | data = res.read()
20 |
21 | if res.status >= 400:
22 | print str(res.status) + ' ' + res.reason
23 | raise httplib.HTTPException(str(res.status) + ' ' + res.reason + (': ' + data.strip() if data.strip() else ''))
24 |
25 |
26 | browser.close()
27 |
28 | if data != '':
29 | for t, tval in json.loads(data).iteritems():
30 | for f, fval in tval.iteritems():
31 | if f == file_path and 'text_file_id' in fval:
32 | return fval['text_file_id']
33 |
34 | return None
35 | else:
36 | return str(res.status) + res.reason;
37 | except httplib.HTTPException as h:
38 | return h.message;
39 | finally:
40 | browser.close()
41 |
42 | def get_file(text_file_id):
43 | browser = httplib.HTTPConnection(url)
44 | try:
45 | browser.request('GET', '/api/v2/text_files/' + str(text_file_id), '',
46 | {'Authorization': 'Token token="' + api_key + secret_key + '"',
47 | 'Accept':'application/json'})
48 | res = browser.getresponse()
49 |
50 | data = res.read()
51 |
52 | if res.status >= 400:
53 | print str(res.status) + ' ' + res.reason
54 | raise httplib.HTTPException(str(res.status) + ' ' + res.reason + (': ' + data.strip() if data.strip() else ''))
55 |
56 |
57 | browser.close()
58 |
59 | if data != '':
60 | return json.loads(data)['data']
61 | else:
62 | return str(res.status) + res.reason;
63 | except httplib.HTTPException as h:
64 | return h.message;
65 | finally:
66 | browser.close()
67 |
68 | parser = argparse.ArgumentParser(description='Retrieve a file associated with a node.')
69 | parser.add_argument('node_id', help='The ID of the node the file is associated with.')
70 | parser.add_argument('file_path', help='The file path as it is stored in ScriptRock.')
71 |
72 | args = parser.parse_args()
73 |
74 | file_id = get_file_id(int(args.node_id), args.file_path)
75 | if file_id is not None:
76 | print(get_file(file_id))
77 | else:
78 | print("Requested file not associated with specified node")
79 |
--------------------------------------------------------------------------------
/api/python/list-environments.py:
--------------------------------------------------------------------------------
1 | # pip3 install upguard
2 | import upguard
3 |
4 | api_key = "1234"
5 | sec_key = "5678"
6 | instance = "https://you.upguard.com"
7 |
8 | o = upguard.Account(instance, api_key, sec_key)
9 |
10 | es = o.environments()
11 |
12 | for e in es:
13 | print("id:" + str(e.id) + "\tname:" + str(e.name))
14 |
--------------------------------------------------------------------------------
/api/python/list-operating-system-ids.py:
--------------------------------------------------------------------------------
1 | # pip3 install upguard
2 | import upguard
3 |
4 | api_key = "1234"
5 | sec_key = "5678"
6 | instance = "https://you.upguard.com"
7 |
8 | o = upguard.Account(instance, api_key, sec_key)
9 |
10 | oss = o.operating_systems()
11 |
12 | print("os.name,os.id,osf.name,osf.id")
13 | for os in oss:
14 | osf = os.operating_system_family()
15 | print("" + os.name + "," + str(os.id) + "," + osf.name + "," + str(osf.id))
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/api/python/nodes-create-csv.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import csv
4 | import httplib;
5 | import urllib;
6 | import json;
7 | import ssl;
8 |
9 | hostname = "your.appliance.hostname"
10 | api_key = "Appliance API Key"
11 | secret_key = "Appliance Secret Key"
12 |
13 | def add_node(node):
14 | # NB: Swap in your custom URL below if you have a dedicated instance
15 | browser = httplib.HTTPSConnection(hostname, timeout=5, context=ssl._create_unverified_context())
16 | try:
17 | body = ''
18 | for key, val in node.iteritems():
19 | body += "node[" + urllib.quote_plus(str(key)) + "]=" + urllib.quote_plus(str(val)) + "&"
20 |
21 | body = body[:-1]
22 |
23 | browser.request("POST", "/api/v2/nodes.json", body,
24 | {"Authorization": "Token token=\"" + api_key + secret_key + "\"",
25 | "Accept": "application/json",
26 | "Content-Type": "application/x-www-form-urlencoded"})
27 |
28 | res = browser.getresponse()
29 | data = res.read()
30 |
31 | if res.status >= 400:
32 | print str(res.status) + ' ' + res.reason
33 | raise httplib.HTTPException(str(res.status) + ' ' + res.reason +
34 | (': ' + data.strip() if data.strip() else ''))
35 |
36 | browser.close()
37 |
38 | if data != '':
39 | return json.dumps(json.loads(data), sort_keys=True,
40 | indent=4, separators=(',', ': '))
41 | else:
42 | return str(res.status) + res.reason;
43 | except httplib.HTTPException as h:
44 | return h.message;
45 | finally:
46 | browser.close()
47 |
48 | with open("nodes.csv", "rb") as f:
49 | reader = csv.reader(f)
50 | node = {}
51 | for row in reader:
52 | if row[0] == "node_type":
53 | # Looks like an empty row or heading row, skip
54 | continue
55 | else:
56 | node['node_type'] = row[0]
57 | node['medium_type'] = row[1]
58 | node['medium_username'] = row[2]
59 | node['medium_password'] = row[3]
60 | node['medium_port'] = row[4]
61 | node['connection_manager_group_id'] = row[5]
62 | node['operating_system_family_id'] = row[6]
63 | node['operating_system_id'] = row[7]
64 | node['organisation_id'] = row[8]
65 | node['environment_id'] = row[9]
66 | node['name'] = row[10]
67 | node['medium_hostname'] = row[11]
68 | node['short_description'] = row[12]
69 | print "node=" + str(node)
70 | add_node(node)
71 |
--------------------------------------------------------------------------------
/api/python/nodes-create.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import httplib;
4 | import urllib;
5 | import json;
6 |
7 | hostname = "guardrail.scriptrock.com"
8 | api_key = "1234..."
9 | secret_key = "5678..."
10 |
11 | browser = None
12 |
13 | try:
14 | browser = httplib.HTTPSConnection(hostname)
15 |
16 | node = {
17 | "name": "host.com",
18 | "node_type": "SV",
19 | "medium_type": 3,
20 | "medium_username": "username",
21 | "medium_hostname": "hostname",
22 | "connection_manager_group_id": 1,
23 | }
24 | body = ''
25 | for key, val in node.iteritems():
26 | body += 'node[' + urllib.quote_plus(str(key)) + ']=' + urllib.quote_plus(str(val)) + '&'
27 |
28 | body = body[:-1]
29 |
30 | browser.request("POST", "/api/v1/nodes.json", body,
31 | {"Authorization": "Token token=\"" + api_key + secret_key + "\"",
32 | "Accept": "application/json",
33 | "Content-Type": "application/x-www-form-urlencoded"})
34 | res = browser.getresponse()
35 | data = res.read()
36 |
37 | if res.status >= 400:
38 | raise httplib.HTTPException(str(res.status) + ' ' +
39 | res.reason + (': ' + data.strip() if data.strip() else ''))
40 |
41 | browser.close()
42 |
43 | if data != '':
44 | print json.dumps(json.loads(data), sort_keys=True,
45 | indent=4, separators=(',', ': '))
46 | else:
47 | print str(res.status) + res.reason;
48 | except httplib.HTTPException as h:
49 | print h.message;
50 | finally:
51 | if browser != None:
52 | browser.close()
53 |
--------------------------------------------------------------------------------
/api/python/nodes-lookup.py:
--------------------------------------------------------------------------------
1 | import httplib;
2 | import urllib;
3 | import json;
4 |
5 | api_key = 'api key here'
6 | secret_key = 'secret key here'
7 | url = 'appliance.url.here'
8 |
9 | try:
10 | browser = httplib.HTTPConnection('localhost:3000')
11 |
12 | browser.request("POST",
13 | "/api/v1/nodes/42/add_to_node_group.json?node_group_id=23",
14 | '',
15 | {"Authorization": 'Token token="' + api_key + secret_key + '"',
16 | "Accept": "application/json",
17 | "Content-Type": "application/x-www-form-urlencoded"})
18 | res = browser.getresponse()
19 | # read() must be called before close(), or it will return an empty string
20 | data = res.read()
21 |
22 | if res.status >= 400:
23 | raise httplib.HTTPException(str(res.status) + ' ' +
24 | res.reason + (': ' + data.strip() if data.strip() else ''))
25 |
26 | # close() must be called after each request, or subsequent requests will fail
27 | browser.close()
28 |
29 | if data != '':
30 | return json.dumps(json.loads(data), sort_keys=True,
31 | indent=4, separators=(',', ': '))
32 | else:
33 | return str(res.status) + res.reason;
34 | except httplib.HTTPException as h:
35 | return h.message;
36 | finally:
37 | browser.close()
--------------------------------------------------------------------------------
/api/python/nodes.csv:
--------------------------------------------------------------------------------
1 | node_type, medium_type, medium_username, medium_password, medium_port, connection_manager_group_id, operating_system_family_id, operating_system_id, organisation_id, environment_id, name, medium_hostname, short_description
2 | SV,3,username,,22,1,2,231,2,2,hostname1,1.2.3.4,Description #1
3 | SV,3,username,,22,1,2,231,2,2,hostname2,1.2.3.5,Description #2
4 | SV,3,username,,22,1,2,231,2,2,hostname3,1.2.3.6,Description #3
--------------------------------------------------------------------------------
/api/python/os-families-index.py:
--------------------------------------------------------------------------------
1 | import httplib;
2 | import json;
3 |
4 | api_key = 'api key here'
5 | secret_key = 'secret key here'
6 | url = 'appliance.url.here'
7 |
8 | try:
9 | browser = httplib.HTTPConnection(url)
10 | browser.request("GET", "/api/v1/operating_system_families.json", '',
11 | {"Authorization": 'Token token="' + api_key + secret_key + '"',
12 | "Accept": "application/json"})
13 | res = browser.getresponse()
14 | # read() must be called before close(), or it will return an empty string
15 | data = res.read()
16 |
17 | if res.status >= 400:
18 | raise httplib.HTTPException(str(res.status) + ' ' +
19 | res.reason + (': ' + data.strip() if data.strip() else ''))
20 |
21 | # close() must be called after each request, or subsequent requests will fail
22 | browser.close()
23 |
24 | if data != '':
25 | print json.dumps(json.loads(data), sort_keys=True,
26 | indent=4, separators=(',', ': '))
27 | else:
28 | print str(res.status) + res.reason;
29 | except httplib.HTTPException as h:
30 | print h.message;
31 | finally:
32 | browser.close()
33 |
--------------------------------------------------------------------------------
/api/python/os-index.py:
--------------------------------------------------------------------------------
1 | import httplib;
2 | import json;
3 |
4 | api_key = 'api key here'
5 | secret_key = 'secret key here'
6 | url = 'appliance.url.here'
7 |
8 | try:
9 | browser = httplib.HTTPConnection('localhost:3000')
10 | browser.request("GET", "/api/v1/operating_systems.json", '',
11 | {"Authorization": 'Token token="' + api_key + secret_key + '"',
12 | "Accept": "application/json"})
13 | res = browser.getresponse()
14 | # read() must be called before close(), or it will return an empty string
15 | data = res.read()
16 |
17 | if res.status >= 400:
18 | raise httplib.HTTPException(str(res.status) + ' ' +
19 | res.reason + (': ' + data.strip() if data.strip() else ''))
20 |
21 | # close() must be called after each request, or subsequent requests will fail
22 | browser.close()
23 |
24 | if data != '':
25 | print json.dumps(json.loads(data), sort_keys=True,
26 | indent=4, separators=(',', ': '))
27 | else:
28 | print str(res.status) + res.reason;
29 | except httplib.HTTPException as h:
30 | print h.message;
31 | finally:
32 | browser.close()
33 |
--------------------------------------------------------------------------------
/api/python/snippets/README.md:
--------------------------------------------------------------------------------
1 | # Overview
2 |
3 | A collection of functions that can be used to interact with the UpGuard API.
4 |
5 | # Requirements
6 |
7 | In order to run the `template.py` file, you will need to install the required packages in `requirements.txt`:
8 |
9 | ```
10 | pip install -r requirements.txt
11 | ```
12 |
13 | # Files
14 |
15 | There are two files here:
16 |
17 | * `template.py`: Driving script to demonstrate how to use the functions in `snippets.py`
18 | * `snippets.py`: A collection of functions that can be used in other scripts.
19 |
20 | # Usage
21 |
22 | You can import any functions from the `snippets.py` file for use in your own script.
23 |
24 | First, you will need to import the `getBrowser()` function in order to setup the connection:
25 |
26 | ```
27 | from snippets import getBrowser
28 | ```
29 |
30 | Then you can create the connection by passing the URL and the optional `insecure` boolean (which defaults to `False`):
31 |
32 | ```
33 | browser = getBrowser(target_url="https://appliance.upguard.org", insecure=False)
34 | ```
35 |
36 | You have a connection setup, but you will need your authentication token in order to make calls to the instance. This is a combination of your api and secret key with no spaces in between:
37 |
38 | ```
39 | token = "{}{}".format("api_key", "secret_key")
40 | ```
41 |
42 | Now you have a connection and token you can use to make API calls. For example, if you want to get a list of all the nodes:
43 |
44 | ```
45 | from snippets import getNodes
46 | nodes = getNodes(browser=browser, token=token, details=True)
47 | print("\n\nNodes\n-----")
48 | for node in nodes:
49 | print("{}\n{}".format(node["name"], node))
50 | ```
51 |
52 | Refer to the `template.py` file for more examples.
53 |
--------------------------------------------------------------------------------
/api/python/snippets/requests/README.md:
--------------------------------------------------------------------------------
1 | # Overview
2 |
3 | A collection of functions that can be used to interact with the UpGuard API using the requests package.
4 |
5 | # Requirements
6 |
7 | In order to run the `template.py` file or use the `snippets.py` (which uses the `requests` library), you will need to install the required packages in `requirements.txt`:
8 |
9 | ```
10 | pip install -r requirements.txt
11 | ```
12 |
13 | # Files
14 |
15 | There are two files here:
16 |
17 | * `template.py`: Driving script to demonstrate how to use the functions in `snippets.py`
18 | * `snippets.py`: A collection of functions that can be used in other scripts.
19 |
20 | # Usage
21 |
22 | You can import any functions from the `snippets.py` file for use in your own script.
23 |
24 | First, you will need to import the `getSession()` function in order to setup the connection:
25 |
26 | ```
27 | from snippets import getSession
28 | ```
29 |
30 | Then you can create the session by passing the API key, secret key, and the optional `insecure` boolean (which defaults to `False`):
31 |
32 | ```
33 | session = getSession(
34 | api_key="api_key",
35 | secret_key="secret_key",
36 | insecure=False)
37 | ```
38 |
39 | You now have a session setup to make API calls. For example, if you want to get a list of all the nodes:
40 |
41 | ```
42 | from snippets import getNodes
43 | nodes = getNodes(session=session, url="https://appliance.upguard.org", details=True)
44 | print("\n\nNodes\n-----")
45 | for node in nodes:
46 | print("{}\n{}".format(node["name"], node))
47 | ```
48 |
49 | Refer to the `template.py` file for more examples.
50 |
--------------------------------------------------------------------------------
/api/python/snippets/requests/requirements.txt:
--------------------------------------------------------------------------------
1 | future
2 | six
3 | requests
4 |
--------------------------------------------------------------------------------
/api/python/snippets/requirements.txt:
--------------------------------------------------------------------------------
1 | future
2 | six
3 |
--------------------------------------------------------------------------------
/api/python/snippets/template.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from __future__ import print_function
4 |
5 | import argparse
6 | import http.client
7 | from snippets import getBrowser, APICall, getNodes, getNodeGroups, getConnectionManagerGroups, getNodesInCMGroups, getPolicies, getEvents, scan
8 | from datetime import date, timedelta
9 |
10 | parser = argparse.ArgumentParser(description='')
11 | parser.add_argument('--target-url', required=True, help='URL for the UpGuard instance')
12 | parser.add_argument('--api-key', required=True, help='API key for the UpGuard instance')
13 | parser.add_argument('--secret-key', required=True, help='Secret key for the UpGuard instance')
14 | parser.add_argument('--insecure', action='store_true', help='Ignore SSL certificate checks')
15 | args = parser.parse_args()
16 |
17 | try:
18 | browser = getBrowser(target_url=args.target_url, insecure=args.insecure)
19 | token = "{}{}".format(args.api_key, args.secret_key)
20 |
21 | # Nodes
22 | nodes = getNodes(browser=browser, token=token, details=True)
23 | print("\n\nNodes\n-----")
24 | for node in nodes:
25 | print("{}\n{}\n\n".format(node["name"], node))
26 |
27 | # Node Groups
28 | node_groups = getNodeGroups(browser=browser, token=token, details=True)
29 | print("\n\nNode Groups\n-----")
30 | for group in node_groups:
31 | print("{}\n{}\n\n".format(group["name"], group))
32 |
33 | # CM Groups
34 | cm_groups = getConnectionManagerGroups(browser=browser, token=token)
35 | print("\n\nConnection Manager Groups\n-------------------------")
36 | for group in cm_groups:
37 | print("{}\n{}\n\n".format(group["name"], group))
38 |
39 | # CM Groups with Nodes
40 | cm_groups = getConnectionManagerGroups(browser=browser, token=token)
41 | cm_groups_with_nodes = getNodesInCMGroups(browser=browser, token=token)
42 | print("\n\nCM Groups Node Count\n--------------------")
43 | for id, nodes in cm_groups_with_nodes.iteritems():
44 | group_name = next((g["name"] for g in cm_groups if g["id"] == id), None)
45 | print("{}: {}".format(group_name, len(nodes)))
46 |
47 | # Policies
48 | policies = getPolicies(browser=browser, token=token, details=True)
49 | print("\n\nPolicies\n--------")
50 | for policy in policies:
51 | print("{}\n{}\n\n".format(policy["name"], policy))
52 |
53 | # Events
54 | events = getEvents(browser=browser, token=token, view="User Logins", since=(date.today() - timedelta(1)))
55 | print("\n\nEvents\n-----")
56 | for event in events:
57 | print("{}\n{}\n\n".format(event["id"], event))
58 | print("Total Events: {}".format(len(events)))
59 |
60 | # Scan
61 | result = scan(browser=browser, token=token, node="dev", wait=True)
62 | print("Node scanned, result:\n{}".format(str(result)))
63 |
64 | except http.client.HTTPException as h:
65 | print(h.message)
66 | finally:
67 | if browser:
68 | browser.close()
69 |
--------------------------------------------------------------------------------
/api/python/sync-node-scan-history-to-dir.py:
--------------------------------------------------------------------------------
1 |
2 | # pip install upguard
3 | import upguard
4 | import json
5 | import os
6 |
7 | api_key = "1234"
8 | sec_key = "5678"
9 | instance = "https://you.upguard.com"
10 | dir_to_save_to = "/tmp/scans"
11 | node_name = "My Example Node"
12 |
13 | try:
14 | os.mkdir(dir_to_save_to)
15 | except OSError as error:
16 | print("Dir already exists") # probably
17 |
18 | o = upguard.Account(instance, api_key, sec_key)
19 |
20 | # you can also find the node by ID, if you know the ID
21 | # node = o.node_by_id(node_id)
22 | node = o.node_by_name(node_name)
23 |
24 | scans = node.node_scans()
25 | for scan in scans:
26 | # reload the scan to load the data
27 | scan.load()
28 |
29 | print("Saving scan at " + str(scan.created_at))
30 | filename = dir_to_save_to + str(scan.created_at) + ".json"
31 | f = open(filename, "w")
32 | f.write(json.dumps(scan.data))
33 | f.close()
34 |
35 | print("DONE")
36 |
37 |
38 |
--------------------------------------------------------------------------------
/api/python/util/README.md:
--------------------------------------------------------------------------------
1 | # Problem:
2 |
3 | 1) UpGuard node scans must be 3 levels deep to work with the storage and display of scan results
4 | 2) Sometimes custom scripts run from scan.d product JSON structures that are not 3 levels
5 | and contain arrays/lists of maps/dicts at certain levels that don't load well with the
6 | node scan viewer
7 |
8 | # Solution:
9 | This script takes any json object and converts it to a proper 3 levels deep structure
10 | that secure is expecting and that the agents subscribe to.
11 |
12 | # To use:
13 |
14 | Ensure that the `pathlib2` module is installed: `pip install -r requirements.txt`
15 |
16 | `convert_scan` is the function that does all the work
17 |
18 | `example_of_how_to_run` shows how you can read a file and output a fixed json format.
19 |
20 | but you could also just import this script and call `convert_scan` on a given structure.
21 |
22 | # Bugs/Author
23 |
24 | Ask steve.cossell@upguard.com
25 |
--------------------------------------------------------------------------------
/api/python/util/requirements.txt:
--------------------------------------------------------------------------------
1 | pathlib2
2 |
--------------------------------------------------------------------------------
/api/python/yum-check-update.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | import json
3 | import subprocess
4 |
5 | # Comma delimited list of packages to exclude
6 | exclude_list = ""
7 |
8 | process = subprocess.Popen(["yum", "check-update", "-q", "-x", exclude_list], stdout=subprocess.PIPE)
9 | (output, err) = process.communicate()
10 | exit_code = process.wait()
11 |
12 | if exit_code == 0 and output == "":
13 | print json.dumps({"exit_code": exit_code, "raw": "Up to date"})
14 | else:
15 | print json.dumps({"exit_code": exit_code, "raw": output})
16 |
--------------------------------------------------------------------------------
/api/ruby/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudhousetech/content/84fda2a16d04f56def651abb4694c2afc0a3cce7/api/ruby/.keep
--------------------------------------------------------------------------------
/api/ruby/add_and_scan_node.rb:
--------------------------------------------------------------------------------
1 | require 'active_support/all'
2 | require "httparty"
3 |
4 | @website = "https://.upguard.org"
5 | @api_key =
6 | @secret_key =
7 | @headers = { "Authorization" => "Token token=\"#{@api_key}#{@secret_key}\"" }
8 |
9 | # Key Medium Types
10 | # AGENT = 1
11 | # SSH = 3
12 | # HTTPS = 6
13 | # WINRM = 7
14 |
15 | node = {
16 | "name" => "My Node",
17 | "medium_hostname" => "mynode.mydomain.com",
18 | "node_type" => "SV",
19 | "medium_type" => 3,
20 | "medium_username" => "root",
21 | "connection_manager_group_id" => 1,
22 | "operating_system_family_id" => 2, # Linux
23 | "operating_system_id" => 231, # CentOS
24 | }
25 |
26 | puts "Creating #{node["name"]} node record in UpGuard..."
27 | response = HTTParty.post(
28 | "#{@website}/api/v1/nodes.json",
29 | :headers => @headers,
30 | :body => node.map{|k, v| "node[#{k.to_s}]=#{v.to_s}"}.join('&')
31 | )
32 |
33 | if response.code == 201
34 | puts " Node #{response["name"]} (id: #{response["id"]} Added to UpGuard)"
35 | node["ug_id"] = response["id"]
36 | puts " Initiating first scan..."
37 | response = HTTParty.post(
38 | "#{@website}/api/v1/nodes/#{node["ug_id"]}/start_scan.json",
39 | :headers => @headers,
40 | :body => node.map{|k, v| "node[#{k.to_s}]=#{v.to_s}"}.join('&')
41 | )
42 | if response.code == 201
43 | puts " Scan started successfully."
44 | else
45 | puts " Error starting scan."
46 | end
47 | else
48 | puts " Failed to add node #{node["name"]}"
49 | puts " ErrorCode = #{response.code}"
50 | puts " ErrorBody = #{response.body}"
51 | end
52 |
--------------------------------------------------------------------------------
/api/ruby/custom-node-ms-sql.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'tiny_tds'
4 | require 'json'
5 |
6 | table = {}
7 | columns = {}
8 |
9 | client = TinyTds::Client.new username: '', password: '', host: '', port: 1433, database: ''
10 | result = client.execute("select * from sys.databases where name = ''")
11 |
12 | result.each do |row|
13 | row.to_hash
14 | row.each do |column_name, column_value|
15 | set = {}
16 | set['value'] = column_value
17 | columns[column_name] = set
18 | end
19 | end
20 |
21 | table['settings'] = columns
22 | puts table.to_json
23 |
--------------------------------------------------------------------------------
/api/ruby/extact_nodes_to_csv.rb:
--------------------------------------------------------------------------------
1 | require 'active_support/all'
2 | require "httparty"
3 |
4 | @api_key =
5 | @secret_key =
6 | @website = 'https://'
7 | @headers = { "Authorization" => "Token token=\"#{@api_key}#{@secret_key}\"" }
8 | @output_file = '/tmp/node_extract.csv'
9 |
10 | # Get environments
11 | env_lookup = {}
12 | envs = HTTParty.get("#{@website}/api/v2/environments.json", :headers => @headers)
13 | envs.each do |env|
14 | env_lookup[env["id"]] = env["name"]
15 | end
16 |
17 | # Get Operating System Families
18 | osf_lookup = {}
19 | osfs = HTTParty.get("#{@website}/api/v2/operating_system_families.json", :headers => @headers)
20 | osfs.each do |osf|
21 | osf_lookup[osf["id"]] = osf["name"]
22 | end
23 |
24 | # Get Operating Systems
25 | os_lookup = {}
26 | oss = HTTParty.get("#{@website}/api/v2/operating_systems.json", :headers => @headers)
27 | oss.each do |os|
28 | os_lookup[os["id"]] = os["name"]
29 | end
30 |
31 | # Set up file headers
32 | File.open(@output_file, 'w') { |file| file.write("ID,Name,OSF,OS,Environment,URL\n") }
33 |
34 | # Get nodes
35 | nodes = HTTParty.get("#{@website}/api/v2/nodes.json?page=1&per_page=1000", :headers => @headers)
36 |
37 | # Loop and write to file
38 | nodes.each do |node|
39 | File.open(@output_file, 'a') { |file| file.write("#{node["id"]},#{node["name"]},#{osf_lookup[node["operating_system_family_id"]]},#{os_lookup[node["operating_system_id"]]},#{env_lookup[node["environment_id"]]},#{@website}/node_groups#/nodes/#{node["id"]}\n") }
40 | end
41 |
--------------------------------------------------------------------------------
/api/ruby/get_events_with_paging.rb:
--------------------------------------------------------------------------------
1 | require 'active_support/all'
2 | require "httparty"
3 |
4 | @website = "https://"
5 | @api_key =
6 | @secret_key =
7 | @headers = { "Authorization" => "Token token=\"#{@api_key}#{@secret_key}\"" }
8 | page = 1
9 | per_page = 500
10 | events = nil
11 | total = 0
12 | all_events = []
13 |
14 | # Set fixed parts of the URL
15 | url = "#{@website}/api/v2/events.json?view_name=All&per_page=#{per_page}&date_from=10 days ago"
16 |
17 | while events.nil? || events.count == per_page
18 | puts " Retrieving page #{page} of events for view with url #{url}&page=#{page}"
19 | events = HTTParty.get("#{url}&page=#{page}", :headers => @headers)
20 |
21 | if events.response.code.to_i != 200
22 | puts " ERROR trying to retrieve events:"
23 | puts " #{events.body}"
24 | next
25 | end
26 |
27 | puts " Retrieved #{events.count} events"
28 | all_events += events
29 | page += 1
30 | end
31 |
32 | # Loop through all events
33 | all_events.each do |event|
34 | puts event
35 | end
36 |
--------------------------------------------------------------------------------
/api/ruby/latest-results.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'net/http'
4 | require 'json'
5 |
6 | api_key = '<<< API KEY >>>'
7 | secret_key = '<<< SECRET KEY >>>'
8 | url = 'https://app.upguard.com'
9 | node_id = 2458
10 | policy_id = 2116
11 |
12 | uri = URI.join(url, "/api/v2/policies/#{policy_id}/latest_results.json")
13 | req = Net::HTTP::Get.new(uri)
14 | req['Authorization'] = 'Token token="' + api_key + secret_key + '"'
15 | req['Accept'] = 'application/json'
16 |
17 | http = Net::HTTP.new(uri.host, uri.port)
18 | http.use_ssl = (uri.port == 443)
19 |
20 | res = http.request(req)
21 | data = res.body
22 |
23 | if Integer(res.code) >= 400
24 | raise res.code + ' ' + res.message + (data.strip() == '' ? ': ' + data.strip() : '')
25 | end
26 |
27 | if data != ''
28 | response = JSON.load(data)
29 | response['policy_stats'].each do |stat|
30 | if stat['node_id'].to_i == node_id
31 | if stat['fail_count'].to_i == 0
32 | puts "node is passing all policy tests"
33 | elsif
34 | puts "node is failing policy tests"
35 | end
36 | end
37 | end
38 | else
39 | return str(res.code) + res.message;
40 | end
41 |
--------------------------------------------------------------------------------
/api/ruby/list_all_operating_system_ids.rb:
--------------------------------------------------------------------------------
1 | require 'active_support/all'
2 | require "httparty"
3 |
4 | @website = "https://.upguard.org"
5 | @api_key =
6 | @secret_key =
7 | @headers = { "Authorization" => "Token token=\"#{@api_key}#{@secret_key}\"" }
8 |
9 | def get_operating_system_ids
10 | osfs = HTTParty.get("#{@website}/api/v2/operating_system_families.json", :headers => @headers)
11 | oss = HTTParty.get("#{@website}/api/v2/operating_systems.json", :headers => @headers)
12 |
13 | osfs.each do |osf|
14 | # Get OS for family
15 | oss.select { |os| os["operating_system_family_id"] == osf["id"] }.each do |os|
16 | puts "OSF ID: #{osf["id"]}, OS ID: #{os["id"]} - #{os["description"]}"
17 | end
18 | puts ""
19 | end
20 | end
21 |
22 | get_operating_system_ids
23 |
--------------------------------------------------------------------------------
/api/ruby/node-change-environment.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 | require 'erb'
3 |
4 | api_key = "<< your api key"
5 | secret_key = "<< your secret key >>"
6 | combined_key = "#{api_key}#{secret_key}"
7 | upguard_instance = "<< your upguard instance url >>"
8 | hostname = `hostname`.strip
9 | to_environment_id = 1
10 | node_details = '{ "node": { "environment_id": ' + "\"#{to_environment_id}\"" + '} }'
11 |
12 | # We need the node Id to edit the node. We can perform a lookup based on the node's hostname
13 | lookup_resp = `curl -X GET -s -k -H 'Authorization: Token token="#{combined_key}"' -H 'Accept: application/json' -H 'Content-Type: application/json' #{upguard_instance}/api/v2/nodes/lookup?name=#{ERB::Util.url_encode(hostname)}`
14 | if lookup_resp.is_a?(String) && lookup_resp.include?("node_id")
15 | lookup_json = JSON.load(lookup_resp)
16 | node_id = lookup_json['node_id']
17 | # Update node environment
18 | update_resp = `curl -X PUT -s -k -H 'Authorization: Token token="#{combined_key}"' -H 'Accept: application/json' -H 'Content-Type: application/json' -d '#{node_details}' #{upguard_instance}/api/v2/nodes/#{node_id}`
19 | if update_resp.is_a?(String) && update_resp == ""
20 | puts "upguard: node id #{node_id} updated with environment id #{to_environment_id}"
21 | else
22 | puts "upguard: #{update_resp}"
23 | exit
24 | end
25 | else
26 | puts "upguard: #{lookup_resp}"
27 | exit
28 | end
29 |
--------------------------------------------------------------------------------
/api/ruby/nodes-create-csv.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'net/http'
4 | require 'json'
5 | require 'csv'
6 |
7 | def add_node(node)
8 | uri = URI.join('http://localhost:3000', '/api/v1/nodes.json')
9 | req = Net::HTTP::Post.new(uri)
10 |
11 | req.body = node.map{|k, v| "node[#{k.to_s}]=#{v.to_s}"}.join('&')
12 |
13 | req['Authorization'] = 'Token token="ABCD123456EF7890GH"'
14 | req['Content-Type'] = 'application/x-www-form-urlencoded'
15 |
16 | Net::HTTP::start(uri.host, uri.port) do |http|
17 | res = http.request(req)
18 |
19 | data = res.body
20 |
21 | if Integer(res.code) >= 400
22 | raise res.code + ' ' + res.message + (data.strip() == '' ? ': ' +
23 | data.strip() : '')
24 | end
25 |
26 | if data != ''
27 | return JSON.pretty_generate(JSON.load(data), {:indent => ' ', :space => ' '})
28 | else
29 | return str(res.code) + res.message;
30 | end
31 | end
32 | end
33 |
34 | CSV.foreach('nodes.csv') do |row|
35 | node = {
36 | :name => row[0],
37 | :node_type => row[1],
38 | :medium_type => row[2],
39 | :medium_username => row[3],
40 | :medium_password => row[4],
41 | :connection_manager_group_id => row[5]
42 | }
43 | add_node(node)
44 | end
45 |
--------------------------------------------------------------------------------
/api/ruby/nodes-create.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'net/http'
4 | require 'json'
5 |
6 | api_key = ""
7 | secret_key = ""
8 |
9 | node = {
10 | :name => "host.com",
11 | :node_type => "SV",
12 | :medium_type => 3,
13 | :medium_username => "username",
14 | :medium_hostname => "hostname",
15 | :connection_manager_group_id => 1,
16 | }
17 |
18 | # NB: Swap in your custom URL here if you have a dedicated instance
19 | uri = URI.join('https://guardrail.scriptrock.com', '/api/v1/nodes.json')
20 | req = Net::HTTP::Get.new(uri)
21 | req['Authorization'] = 'Token token="AB123456CDEF7890GH"'
22 | req['Accept'] = 'application/json'
23 | req['Content-Type'] = 'application/x-www-form-urlencoded'
24 | req.body = node.map{|k, v| "node[#{k.to_s}]=#{v.to_s}"}.join('&')
25 |
26 | Net::HTTP::start(uri.host, uri.port) do |http|
27 | res = http.request(req)
28 | data = res.body
29 |
30 | if Integer(res.code) >= 400
31 | raise res.code + ' ' + res.message + (data.strip() == '' ?
32 | ': ' + data.strip() : '')
33 | end
34 |
35 | if data != ''
36 | puts JSON.pretty_generate(JSON.load(data), {:indent => ' ',
37 | :space => ' '})
38 | else
39 | puts str(res.code) + res.message;
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/api/ruby/nodes-index.rb:
--------------------------------------------------------------------------------
1 | @nodes = []
2 |
3 | while true
4 |
5 | page += 1
6 | puts "Getting page #{page}"
7 |
8 | response = HTTParty.get(
9 | "https://guardrail.scriptrock.com/api/v1/nodes.json?page=#{page}&per_page=#{per_page}",
10 | :headers => { "Authorization" => "Token token=\"#{api_key}#{secret_key}\"",
11 | 'Accept' => 'application/json' }
12 | )
13 |
14 | if response.code.to_s == "200"
15 | node_array = JSON.parse(response.body)
16 | @nodes << node_array
17 | if node_array.size < per_page
18 | break
19 | end
20 | elsif response.code.to_s != "404"
21 | puts "Error getting nodes: http code=#{response.code}"
22 | end
23 |
24 | end
25 |
--------------------------------------------------------------------------------
/api/ruby/nodes-lookup.rb:
--------------------------------------------------------------------------------
1 | require 'net/http'
2 | require 'json'
3 |
4 | api_key = 'api key here'
5 | secret_key = 'secret key here'
6 | url = 'appliance.url.here'
7 |
8 | uri = URI.join('https://' + url,
9 | '/api/v1/nodes/42/add_to_node_group.json?node_group_id=23')
10 | req = Net::HTTP::Get.new(uri)
11 | req['Authorization'] = 'Token token="' + api_key + secret_key + '"'
12 | req['Accept'] = 'application/json'
13 |
14 | Net::HTTP::start(uri.host, uri.port) do |http|
15 | res = http.request(req)
16 | data = res.body
17 |
18 | if Integer(res.code) >= 400
19 | raise res.code + ' ' + res.message + (data.strip() == '' ?
20 | ': ' + data.strip() : '')
21 | end
22 |
23 | if data != ''
24 | return JSON.pretty_generate(JSON.load(data), {:indent => ' ',
25 | :space => ' '})
26 | else
27 | return str(res.code) + res.message;
28 | end
29 | end
--------------------------------------------------------------------------------
/api/ruby/os-families-index.rb:
--------------------------------------------------------------------------------
1 | require 'net/http'
2 | require 'json'
3 |
4 | api_key = 'api key here'
5 | secret_key = 'secret key here'
6 | url = 'appliance.url.here'
7 |
8 | uri = URI.join('https://' + url, '/api/v1/operating_system_families.json')
9 | req = Net::HTTP::Get.new(uri)
10 | req['Authorization'] = 'Token token="' + api_key + secret_key + '"'
11 | req['Accept'] = 'application/json'
12 |
13 | Net::HTTP::start(uri.host, uri.port) do |http|
14 | res = http.request(req)
15 | data = res.body
16 |
17 | if Integer(res.code) >= 400
18 | raise res.code + ' ' + res.message + (data.strip() == '' ?
19 | ': ' + data.strip() : '')
20 | end
21 |
22 | if data != ''
23 | puts JSON.pretty_generate(JSON.load(data), {:indent => ' ',
24 | :space => ' '})
25 | else
26 | puts str(res.code) + res.message;
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/api/ruby/os-index.rb:
--------------------------------------------------------------------------------
1 | require 'net/http'
2 | require 'json'
3 |
4 | api_key = 'api key here'
5 | secret_key = 'secret key here'
6 | url = 'appliance.url.here'
7 |
8 | uri = URI.join('https://' + url, '/api/v1/operating_system_families.json')
9 | req = Net::HTTP::Get.new(uri)
10 | req['Authorization'] = 'Token token="' + api_key + secret_key + '"'
11 | req['Accept'] = 'application/json'
12 |
13 | Net::HTTP::start(uri.host, uri.port) do |http|
14 | res = http.request(req)
15 | data = res.body
16 |
17 | if Integer(res.code) >= 400
18 | raise res.code + ' ' + res.message + (data.strip() == '' ?
19 | ': ' + data.strip() : '')
20 | end
21 |
22 | if data != ''
23 | puts JSON.pretty_generate(JSON.load(data), {:indent => ' ',
24 | :space => ' '})
25 | else
26 | puts str(res.code) + res.message;
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/api/ruby/policies-delete-v2.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'net/http'
4 | require 'json'
5 |
6 | def main
7 |
8 | policies = []
9 | policies_whitelist = [1389, 1263, 1320, 1267, 1345, 1337, 1316, 1344, 1408]
10 |
11 | # Grab all policies
12 | sr = ScriptRock.new
13 | all_policies = sr.get_policies
14 | all_policies.each do |p|
15 | policies.push(p["id"])
16 | end
17 |
18 | # Nicely display all policies
19 | puts JSON.pretty_generate(all_policies, {:indent => ' ', :space => ' '})
20 |
21 | # Remove from this the nodes we have whitelisted
22 | policies_whitelist.each do |w|
23 | if policies.index(w)
24 | policies.delete_at(policies.index(w))
25 | else
26 | puts "Looks like policy id #{w} (from whitelist) has been deleted by someone"
27 | end
28 | end
29 |
30 | # Delete!
31 | sr.delete_policies(policies)
32 |
33 | end
34 |
35 | class ScriptRock
36 |
37 | $api_key = '<<< API_KEY >>>'
38 | $secret_key = '<<< SECRET_KEY >>>'
39 | $website = 'https://app.upguard.com'
40 | $policies_index_api = '/api/v2/policies'
41 |
42 | def delete_policies(policies)
43 |
44 | policies.each do |p|
45 |
46 | uri = URI.join($website, "#{$policies_index_api}/#{p}")
47 | req = Net::HTTP::Delete.new(uri)
48 | req['Authorization'] = "Token token=\"#{$api_key}#{$secret_key}\""
49 | req['Accept'] = 'application/json'
50 | req['Content-Type'] = 'application/x-www-form-urlencoded'
51 |
52 | http = Net::HTTP.new(uri.host, uri.port)
53 | http.use_ssl = (uri.scheme == "https")
54 |
55 | res = http.request(req)
56 | data = res.body
57 |
58 | if Integer(res.code) >= 400
59 | raise res.code + ' ' + res.message + (data.strip() == '' ? ': ' + data.strip() : '')
60 | elsif Integer(res.code) == 204
61 | puts "Deleted policy id: #{p}"
62 | end
63 | end
64 | end
65 |
66 | def get_policies
67 |
68 | uri = URI.join($website, $policies_index_api, '?page=1&per_page=50')
69 | req = Net::HTTP::Get.new(uri)
70 | req['Authorization'] = "Token token=\"#{$api_key}#{$secret_key}\""
71 | req['Accept'] = 'application/json'
72 | req['Content-Type'] = 'application/x-www-form-urlencoded'
73 |
74 | http = Net::HTTP.new(uri.host, uri.port)
75 | http.use_ssl = (uri.scheme == "https")
76 |
77 | res = http.request(req)
78 | data = res.body
79 |
80 | if Integer(res.code) >= 400
81 | raise res.code + ' ' + res.message + (data.strip() == '' ? ': ' + data.strip() : '')
82 | end
83 |
84 | if data != ''
85 | return JSON.parse(data)
86 | #puts JSON.pretty_generate(JSON.load(data), {:indent => ' ', :space => ' '})
87 | else
88 | puts res.code + res.message;
89 | end
90 | end
91 | end
92 |
93 | main
94 |
--------------------------------------------------------------------------------
/api/ruby/policies-delete.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'net/http'
4 | require 'json'
5 |
6 | def main
7 |
8 | policies = []
9 | policies_whitelist = [1389, 1263, 1320, 1267, 1345, 1337, 1316, 1344, 1408]
10 |
11 | # Grab all policies
12 | sr = ScriptRock.new
13 | all_policies = sr.get_policies
14 | all_policies.each do |p|
15 | policies.push(p["id"])
16 | end
17 |
18 | # Nicely display all policies
19 | puts JSON.pretty_generate(all_policies, {:indent => ' ', :space => ' '})
20 |
21 | # Remove from this the nodes we have whitelisted
22 | policies_whitelist.each do |w|
23 | if policies.index(w)
24 | policies.delete_at(policies.index(w))
25 | else
26 | puts "Looks like policy id #{w} (from whitelist) has been deleted by someone"
27 | end
28 | end
29 |
30 | # Delete!
31 | sr.delete_policies(policies)
32 |
33 | end
34 |
35 | class ScriptRock
36 |
37 | $api_key = '<<< API_KEY >>>'
38 | $secret_key = '<<< SECRET_KEY >>>'
39 | $website = 'https://guardrail.scriptrock.com'
40 | $policies_index_api = '/api/v1/policies'
41 |
42 | def delete_policies(policies)
43 |
44 | policies.each do |p|
45 |
46 | uri = URI.join($website, "#{$policies_index_api}/#{p}")
47 | req = Net::HTTP::Delete.new(uri)
48 | req['Authorization'] = "Token token=\"#{$api_key}#{$secret_key}\""
49 | req['Accept'] = 'application/json'
50 | req['Content-Type'] = 'application/x-www-form-urlencoded'
51 |
52 | http = Net::HTTP.new(uri.host, uri.port)
53 | http.use_ssl = (uri.scheme == "https")
54 |
55 | res = http.request(req)
56 | data = res.body
57 |
58 | if Integer(res.code) >= 400
59 | raise res.code + ' ' + res.message + (data.strip() == '' ? ': ' + data.strip() : '')
60 | elsif Integer(res.code) == 204
61 | puts "Deleted policy id: #{p}"
62 | end
63 | end
64 | end
65 |
66 | def get_policies
67 |
68 | uri = URI.join($website, $policies_index_api, '?page=1&per_page=50')
69 | req = Net::HTTP::Get.new(uri)
70 | req['Authorization'] = "Token token=\"#{$api_key}#{$secret_key}\""
71 | req['Accept'] = 'application/json'
72 | req['Content-Type'] = 'application/x-www-form-urlencoded'
73 |
74 | http = Net::HTTP.new(uri.host, uri.port)
75 | http.use_ssl = (uri.scheme == "https")
76 |
77 | res = http.request(req)
78 | data = res.body
79 |
80 | if Integer(res.code) >= 400
81 | raise res.code + ' ' + res.message + (data.strip() == '' ? ': ' + data.strip() : '')
82 | end
83 |
84 | if data != ''
85 | return JSON.parse(data)
86 | #puts JSON.pretty_generate(JSON.load(data), {:indent => ' ', :space => ' '})
87 | else
88 | puts res.code + res.message;
89 | end
90 | end
91 | end
92 |
93 | main
94 |
--------------------------------------------------------------------------------
/api/shell/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudhousetech/content/84fda2a16d04f56def651abb4694c2afc0a3cce7/api/shell/.keep
--------------------------------------------------------------------------------
/api/shell/create-event.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | curl -X POST \
5 | https://example.upguard.com/api/v2/events.json \
6 | -H 'Authorization: Token token=""' \
7 | -H 'Content-Type: application/json' \
8 | --data '{ "user_id": 2, "node_id": 123, "variables": { "type": "jenkins deploy" } }'
9 |
--------------------------------------------------------------------------------
/api/shell/create-legacy-event.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Usage:
4 | # chmod +x api-timeline.sh
5 | # ./api-timeline.sh -c "Build" -a "Started" -s 2 -i "jira" -d 15 -e "Deploy to production"
6 |
7 | while [[ $# > 0 ]]
8 | do
9 | key="$1"
10 |
11 | case $key in
12 | -c|--category)
13 | CATEGORY="$2"
14 | shift # past argument
15 | ;;
16 | -a|--action)
17 | ACTION="$2"
18 | shift
19 | ;;
20 | -s|--status)
21 | STATUS="$2"
22 | shift
23 | ;;
24 | -i|--icon)
25 | ICON="$2"
26 | shift
27 | ;;
28 | -d|--duration)
29 | DURATION="$2"
30 | shift
31 | ;;
32 | -e|--extra)
33 | EXTRA="$2"
34 | shift
35 | ;;
36 | esac
37 | shift
38 | done
39 |
40 | data="{\"event\":{\"sub_category\":\"${CATEGORY}\",\"action_taken\":\"${ACTION}\",\"status\":${STATUS},\"source\":\"${ICON}\",\"duration\":\"${DURATION}\",\"extra\":\"${EXTRA}\"}}"
41 | curl -s -k -H "Authorization: Token token=\"abc123\"" -H "Content-Type: application/json" -d "$data" http://hostname/api/v2/legacy_events
42 |
--------------------------------------------------------------------------------
/api/shell/node-scan.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | # UpGuard parameters
5 | apiKey="abcd"
6 | secretKey="1234"
7 | upguard="https://appliance.url"
8 | linuxConnectionManagerGroupId=1
9 | linuxNodeOSFamily=2 # Linux
10 | ubuntuNodeOS=231 # Centos
11 | nodeIPHostname=$(hostname -f)
12 | manifestDesc="Logoff%20script"
13 |
14 | # UpGuard endpoints
15 | nodes="/api/v2/nodes"
16 | nodesLookup="/api/v2/nodes/lookup.json?external_id=[0]"
17 | nodesScan="/api/v2/nodes/[0]/start_scan.json?label=[1]"
18 |
19 | # Headers
20 | combinedKey="$apiKey$secretKey"
21 | authHeader="Authorization: Token token=\"$combinedKey\""
22 | acceptHeader="Accept: application/json"
23 | contentHeader="Content-Type: application/json"
24 |
25 | # Check to see if the node has already been added to UpGuard.
26 | nodesLookupReplaced="${nodesLookup/\[0\]/$nodeIPHostname}"
27 | nodeIdResponse=`curl -X GET -s -k -H "$authHeader" -H "$acceptHeader" -H "$contentHeader" $upguard$nodesLookupReplaced`
28 |
29 | if [[ $nodeIdResponse == *"node_id"* ]]; then
30 | # It's already here.
31 | nodeId=`echo $nodeIdResponse | perl -ne 'if ( /\"node_id\":(\d+)\b/ ) { print "$1"; }'`
32 | else
33 | # Not here, need to create it.
34 | nodeIdResponse=`curl -X POST -s -k -H "$authHeader" -H "$acceptHeader" -H "$contentHeader" -d '{"node": {"name": '\"$nodeIPHostname\"', "short_description": "Added via the API.", "node_type": "SV", "operating_system_family_id": '$linuxNodeOSFamily', "operating_system_id": '$ubuntuNodeOS', "medium_type": 3, "medium_port": 22, "connection_manager_group_id": '$linuxConnectionManagerGroupId', "medium_hostname": '\"$nodeIPHostname\"', "external_id": '\"$nodeIPHostname\"' }}' $upguard$nodes`
35 | nodeId=`echo $nodeIdResponse | perl -ne 'if ( /\"id\":(\d+)\b/ ) { print "$1"; }'`
36 | fi
37 |
38 | if [ -n "$nodeId" ]; then
39 | # Kick off a node scan.
40 | nodesScanReplaced="${nodesScan/\[0\]/$nodeId}"
41 | nodesScanReplaced="${nodesScanReplaced/\[1\]/$manifestDesc}"
42 | startScanResponse=`curl -L -w '%{http_code}\n' -X POST -s -k -H "$authHeader" -H "$acceptHeader" -H "$contentHeader" $upguard$nodesScanReplaced`
43 | jobId=`echo $startScanResponse | perl -ne 'if ( /\"job_id\":(\d+)\b/ ) { print "$1"; }'`
44 | else
45 | echo "upguard: unable to find or create node to scan"
46 | fi
47 |
48 | if [ -n "$jobId" ]; then
49 | echo "upguard: node scan kicked off against "$nodeIPHostname" ("$upguard"/jobs/"$jobId"/show_job?show_all=true)"
50 | else
51 | echo "upguard: unable to start a node scan"
52 | fi
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/api/shell/node-update-password.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | # UpGuard parameters
5 | apiKey="<< apiKey >>"
6 | secretKey="<< secretKey >>"
7 | upguard="<< https://your.upguard.appliance >>"
8 | mediumPassword="abc"
9 | alternatePassword="123"
10 | cmGroupId=123
11 | nodeId=123
12 |
13 | # UpGuard endpoints
14 | nodesShow="/api/v2/nodes/[0]"
15 |
16 | # Headers
17 | combinedKey="$apiKey$secretKey"
18 | authHeader="Authorization: Token token=\"$combinedKey\""
19 | acceptHeader="Accept: application/json"
20 | contentHeader="Content-Type: application/json"
21 |
22 | nodesShowReplaced="${nodesShow/\[0\]/$nodeId}"
23 | response=`curl -X PUT -s -k -H "$authHeader" -H "$acceptHeader" -H "$contentHeader" -d '{"node": {"connection_manager_group_id": '\"$cmGroupId\"', "medium_password": '\"$mediumPassword\"', "alternate_password": '\"$alternatePassword\"' }}' $upguard$nodesShowReplaced`
24 | if [[ $response == "" ]]; then
25 | echo "Updated node password."
26 | else
27 | echo $response
28 | fi
29 |
--------------------------------------------------------------------------------
/api/shell/nodes-create.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | curl -w '%{http_code}\n' -X POST -s -k -H "Authorization: Token token=\"abcd1234\"" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"node": {"name": "test", "short_description": "added via api", "node_type": "SV", "operating_system_family_id": 2, "operating_system_id": 221, "medium_type": 3, "medium_username": "username", "medium_hostname": "hostname", "connection_manager_group_id": 1}}' https://hostname/api/v1/nodes
4 |
--------------------------------------------------------------------------------
/api/shell/retrieve-backup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Download nightly backups of the file system backup into a folder for safekeeping
3 | # Usage: retrieve-backup.sh