Initial Commit
This commit is contained in:
parent
07de5a2996
commit
bcd9706454
30 changed files with 302 additions and 968 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1 @@
|
||||||
.venv
|
result
|
||||||
.ruff_cache
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
# Calliope
|
|
||||||
|
|
||||||
A monorepo for QoL stuff for Adaptation
|
|
17
calliope.nix
Normal file
17
calliope.nix
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Consumes user.nix, configuration.nix
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
{ config, pkgs, lib, ...}:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./configuration.nix
|
||||||
|
./user.nix
|
||||||
|
];
|
||||||
|
calliope = {
|
||||||
|
hostName = "marcille";
|
||||||
|
ipv4Address = "172.18.154.50";
|
||||||
|
cec = "akristip";
|
||||||
|
username = "mira";
|
||||||
|
shell = pkgs.xonsh;
|
||||||
|
#password = "";
|
||||||
|
}
|
||||||
|
}
|
135
configuration.nix
Normal file
135
configuration.nix
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
# Edit this configuration file to define what should be installed on
|
||||||
|
# your system. Help is available in the configuration.nix(5) man page
|
||||||
|
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
||||||
|
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# imports =
|
||||||
|
# [ # Include the results of the hardware scan.
|
||||||
|
# ./user.nix
|
||||||
|
# ];
|
||||||
|
|
||||||
|
networking.nameservers = [ "64.102.6.247" ];
|
||||||
|
networking.search = [ "cisco.com" ];
|
||||||
|
|
||||||
|
# Bootloader.
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
nix.package = pkgs.lix;
|
||||||
|
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||||
|
|
||||||
|
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
|
||||||
|
|
||||||
|
# Configure network proxy if necessary
|
||||||
|
# networking.proxy.default = "http://user:password@proxy:port/";
|
||||||
|
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||||
|
|
||||||
|
|
||||||
|
# Set your time zone.
|
||||||
|
time.timeZone = "America/New_York";
|
||||||
|
|
||||||
|
# Select internationalisation properties.
|
||||||
|
i18n.defaultLocale = "en_US.UTF-8";
|
||||||
|
|
||||||
|
i18n.extraLocaleSettings = {
|
||||||
|
LC_ADDRESS = "en_US.UTF-8";
|
||||||
|
LC_IDENTIFICATION = "en_US.UTF-8";
|
||||||
|
LC_MEASUREMENT = "en_US.UTF-8";
|
||||||
|
LC_MONETARY = "en_US.UTF-8";
|
||||||
|
LC_NAME = "en_US.UTF-8";
|
||||||
|
LC_NUMERIC = "en_US.UTF-8";
|
||||||
|
LC_PAPER = "en_US.UTF-8";
|
||||||
|
LC_TELEPHONE = "en_US.UTF-8";
|
||||||
|
LC_TIME = "en_US.UTF-8";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure keymap in X11
|
||||||
|
services.xserver.xkb = {
|
||||||
|
layout = "us";
|
||||||
|
variant = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||||
|
users.users.mira = {
|
||||||
|
isNormalUser = true;
|
||||||
|
description = "Mira";
|
||||||
|
extraGroups = [ "networkmanager" "wheel" ];
|
||||||
|
packages = with pkgs; [];
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.chris = {
|
||||||
|
isNormalUser = true;
|
||||||
|
description = "Chris";
|
||||||
|
extraGroups = [ "networkmanager" "wheel" ];
|
||||||
|
packages = with pkgs; [];
|
||||||
|
};
|
||||||
|
# Enable automatic login for the user.
|
||||||
|
services.getty.autologinUser = lib.mkDefault "mira";
|
||||||
|
|
||||||
|
# Allow unfree packages
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
|
# List packages installed in system profile. To search, run:
|
||||||
|
# $ nix search wget
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
|
||||||
|
# wget
|
||||||
|
lsd
|
||||||
|
fd
|
||||||
|
ripgrep
|
||||||
|
thefuck
|
||||||
|
nh
|
||||||
|
hyfetch
|
||||||
|
fastfetch
|
||||||
|
uv
|
||||||
|
edit
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.neovim = {
|
||||||
|
enable = true;
|
||||||
|
defaultEditor = true;
|
||||||
|
};
|
||||||
|
# Some programs need SUID wrappers, can be configured further or are
|
||||||
|
# started in user sessions.
|
||||||
|
# programs.mtr.enable = true;
|
||||||
|
programs.gnupg.agent = {
|
||||||
|
enable = true;
|
||||||
|
enableSSHSupport = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.tmux = {
|
||||||
|
enable = true;
|
||||||
|
shortcut = "a";
|
||||||
|
keyMode = "vi";
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO: copy git config here
|
||||||
|
|
||||||
|
# TODO: configure git-delta
|
||||||
|
|
||||||
|
# TODO: set aliases (eg ls to lsd)
|
||||||
|
|
||||||
|
|
||||||
|
# List services that you want to enable:
|
||||||
|
|
||||||
|
# Enable the OpenSSH daemon.
|
||||||
|
services.openssh.enable = true;
|
||||||
|
|
||||||
|
# Open ports in the firewall.
|
||||||
|
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||||
|
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||||
|
# Or disable the firewall altogether.
|
||||||
|
networking.firewall.enable = true;
|
||||||
|
|
||||||
|
# This value determines the NixOS release from which the default
|
||||||
|
# settings for stateful data, like file locations and database versions
|
||||||
|
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||||
|
# this value at the release version of the first install of this system.
|
||||||
|
# Before changing this value read the documentation for this option
|
||||||
|
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||||
|
system.stateVersion = "24.11"; # Did you read the comment?
|
||||||
|
virtualisation.vmware.guest.enable = true;
|
||||||
|
}
|
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1747825515,
|
||||||
|
"narHash": "sha256-BWpMQymVI73QoKZdcVCxUCCK3GNvr/xa2Dc4DM1o2BE=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "cd2812de55cf87df88a9e09bf3be1ce63d50c1a6",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-25.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
27
flake.nix
Normal file
27
flake.nix
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
# NOTE: Replace "nixos-23.11" with that which is in system.stateVersion of
|
||||||
|
# configuration.nix. You can also use latter versions if you wish to
|
||||||
|
# upgrade.
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
|
||||||
|
};
|
||||||
|
outputs = inputs@{ self, nixpkgs, ... }: {
|
||||||
|
# NOTE: 'nixos' is the default hostname set by the installer
|
||||||
|
nixosConfigurations.marcille = nixpkgs.lib.nixosSystem {
|
||||||
|
# NOTE: Change this to aarch64-linux if you are on ARM
|
||||||
|
system = "x86_64-linux";
|
||||||
|
modules = [
|
||||||
|
./configuration.nix
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
};
|
||||||
|
nixosConfigurations.live = nixpkgs.lib.nixosSystem {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
modules = [
|
||||||
|
(nixpkgs + "/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix")
|
||||||
|
./configuration.nix
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
51
hardware-configuration.nix
Normal file
51
hardware-configuration.nix
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ ];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "ata_piix" "vmw_pvscsi" "ahci" "sd_mod" "sr_mod" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "/dev/disk/by-uuid/2135c59d-9c2d-487c-9c4e-0f566fa9d316";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [ "subvol=@" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/7E60-8E0B";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0077" "dmask=0077" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault false;
|
||||||
|
# networking.interfaces.ens33.useDHCP = lib.mkDefault true;
|
||||||
|
networking.interfaces.ens33 = {
|
||||||
|
ipv4.addresses = [{
|
||||||
|
address = "172.18.154.50";
|
||||||
|
prefixLength = 24;
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable networking
|
||||||
|
networking.networkmanager.enable = true;
|
||||||
|
|
||||||
|
networking.defaultGateway = {
|
||||||
|
address = "172.18.154.1";
|
||||||
|
interface = "ens33";
|
||||||
|
};
|
||||||
|
networking.nameservers = [ "64.102.6.247" ];
|
||||||
|
networking.search = [ "cisco.com" ];
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
}
|
2
ise/ISE-bash-scripts/.gitignore
vendored
2
ise/ISE-bash-scripts/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
*.tar.gz
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
# ISE Utility Bash Scripts
|
|
||||||
|
|
||||||
Currently these set of scripts are able to:
|
|
||||||
- Login to ISE
|
|
||||||
- Logout of ISE
|
|
||||||
- Enable/Disable ERS API
|
|
||||||
- Create new OCSP Profile
|
|
||||||
- Disable admin password requirements such as expiration and complexity
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
1. Change `HOSTNAME` in `login.bash` to the IP address/FQDN of your ISE server.
|
|
||||||
2. Read the script to understand what it is doing and modify any variables that you need to.
|
|
||||||
1. For example, `create_new_ocsp_profile.bash` requires you to modify the following:
|
|
||||||
- CRUD="Create"
|
|
||||||
- OCSP_PRIMARY_URL="[2001:420:27ff:fff9::7]:5000"
|
|
||||||
- OCSP_SERVICE_NAME="ggg"
|
|
||||||
- SELECTED_ITEM_NAME="ggg"
|
|
||||||
2. Execute any of the scripts that you want to modify settings on.
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
source ./login.bash
|
|
||||||
|
|
||||||
# Make OCSP request
|
|
||||||
echo -e "Updating OCSP Client Profile"
|
|
||||||
CRUD="Create" # This can be Create or Edit
|
|
||||||
OCSP_PRIMARY_URL="[2001:420:27ff:fff9::7]:5000"
|
|
||||||
OCSP_SERVICE_NAME="ggg"
|
|
||||||
SELECTED_ITEM_NAME="ggg" # This one is needed when you edit an existing OCSP service
|
|
||||||
curl -k 'https://diorite.cisco.com/admin/ocspServicesAction.do' -X POST \
|
|
||||||
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:126.0) Gecko/20100101 Firefox/126.0' \
|
|
||||||
-H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.5' \
|
|
||||||
-H 'Accept-Encoding: gzip, deflate, br, zstd' \
|
|
||||||
-H '_QPH_: Y29tbWFuZD1zYXZl' -H 'Content-Type: application/x-www-form-urlencoded' \
|
|
||||||
-H 'X-Requested-With: XMLHttpRequest, XMLHttpRequest' \
|
|
||||||
-H "OWASP_CSRFTOKEN: ${CSRFTOKEN}" \
|
|
||||||
-H 'Connection: keep-alive' \
|
|
||||||
-H "Cookie: APPSESSIONID=${APPSESSIONID}; MNTLA_JWT_TOKEN=${JWT_TOKEN}" \
|
|
||||||
--data-raw "crud=$CRUD&selectedItemName=$SELECTED_ITEM_NAME&ocspServicesStub.failoverToSecondary=false&ocspServicesStub.alwaysAccessPrimaryFirst=true&ocspServicesStub.primaryNonceExtensions=true&ocspServicesStub.primaryValidateResponseSignature=true&ocspServicesStub.secondaryNonceExtensions=true&ocspServicesStub.secondaryValidateResponseSignature=true&ocspServicesStub.selectedOCSPConfig=OCSP_RESPONDER&ocspServicesStub.enableNonceExtensionSupportAia=true&ocspServicesStub.validateResponseSignatureAia=true&ocspServicesStub.name=$OCSP_SERVICE_NAME&ocspServicesStub.description=&ocspServicesStub.primaryURL=$OCSP_PRIMARY_URL&primaryNonceExtensionsCB=on&primaryValidateResponseSignatureCB=on&ocspServicesStub.cacheTimeout=1440" 2>/dev/null | jq
|
|
||||||
|
|
||||||
source ./logout.bash
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
source ./login.bash
|
|
||||||
|
|
||||||
# _QPC_ is a base64 encoded string that contains the CSRF token
|
|
||||||
QPC=$(printf "command=editAuthSubmit&OWASP_CSRFTOKEN=$CSRFTOKEN" | $BASE64 -w0)
|
|
||||||
|
|
||||||
curl "https://$HOSTNAME/admin/adminAuthSettingsAction.do" --compressed --insecure -X POST \
|
|
||||||
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:128.0) Gecko/20100101 Firefox/128.0' \
|
|
||||||
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8' \
|
|
||||||
-H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate, br, zstd' \
|
|
||||||
-H 'Content-Type: multipart/form-data; boundary=---------------------------1799742068132450087154255035' \
|
|
||||||
-H "Cookie: APPSESSIONID=$APPSESSIONID; _QPC_=$QPC; MNTLA_JWT_TOKEN=$JWT_TOKEN" \
|
|
||||||
--data-binary $'-----------------------------1799742068132450087154255035\r\nContent-Disposition: form-data; name="adminAuthSettingsStub.passwordLengthTxt"\r\n\r\n4\r\n-----------------------------1799742068132450087154255035\r\nContent-Disposition: form-data; name="adminAuthSettingsStub.passwordNotUserCharsTxt"\r\n\r\n\r\n-----------------------------1799742068132450087154255035\r\nContent-Disposition: form-data; name="adminAuthSettingsStub.isNewDictFile"\r\n\r\nfalse\r\n-----------------------------1799742068132450087154255035\r\nContent-Disposition: form-data; name="adminAuthSettingsStub.passwordHistoryTxt"\r\n\r\n3\r\n-----------------------------1799742068132450087154255035\r\nContent-Disposition: form-data; name="adminAuthSettingsStub.passwordReuse"\r\n\r\n15\r\n-----------------------------1799742068132450087154255035\r\nContent-Disposition: form-data; name="adminAuthSettingsStub.passwordDisableUserAccountTxt"\r\n\r\n45\r\n-----------------------------1799742068132450087154255035\r\nContent-Disposition: form-data; name="adminAuthSettingsStub.passwordDisplayReminderTxt"\r\n\r\n30\r\n-----------------------------1799742068132450087154255035\r\nContent-Disposition: form-data; name="OWASP_CSRFTOKEN"\r\n\r\n""\r\n-----------------------------1799742068132450087154255035--\r\n'
|
|
||||||
|
|
||||||
source ./logout.bash
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
source ./login.bash
|
|
||||||
|
|
||||||
# Make the API call to enable ERS API
|
|
||||||
ENABLE_ERS_API='true'
|
|
||||||
curl -k "https://$HOSTNAME/admin/ersSettingsAction.do" -X POST \
|
|
||||||
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:128.0) Gecko/20100101 Firefox/128.0' \
|
|
||||||
-H 'Accept: */*' \
|
|
||||||
-H 'Accept-Language: en-US,en;q=0.5' \
|
|
||||||
-H 'Accept-Encoding: gzip, deflate, br, zstd' \
|
|
||||||
-H '_QPH_: Y29tbWFuZD1zdWJtaXRBUElTZXJ2aWNlU2V0dGluZ3M=' \
|
|
||||||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
|
||||||
-H 'X-Requested-With: XMLHttpRequest, XMLHttpRequest' \
|
|
||||||
-H "OWASP_CSRFTOKEN: $CSRFTOKEN" \
|
|
||||||
-H "Origin: https://$HOSTNAME" \
|
|
||||||
-H 'Connection: keep-alive' \
|
|
||||||
-H 'Referer: https://diorite.cisco.com/admin/' \
|
|
||||||
-H "Cookie: APPSESSIONID=$APPSESSIONID; MNTLA_JWT_TOKEN=$JWT_TOKEN" \
|
|
||||||
-H 'Sec-Fetch-Dest: empty' \
|
|
||||||
-H 'Sec-Fetch-Mode: cors' \
|
|
||||||
-H 'Sec-Fetch-Site: same-origin' \
|
|
||||||
-H 'Priority: u=0' \
|
|
||||||
--data-raw "PAPEnabled=$ENABLE_ERS_API&OWASP_CSRFTOKEN=$CSRFTOKEN" 2>/dev/null | awk '{$1=$1};1' | awk '{printf "%s",$0} END {print ""}' | awk '{gsub(/'\''/, "\""); print}' | jq
|
|
||||||
|
|
||||||
source ./logout.bash
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
JOB_NAME=STO_Sparta_sysdevST02
|
|
||||||
JOB_SCRIPT=ipv6_policy_set_radius_attributes.py
|
|
||||||
BRANCH_NAME=radius_ipv6_ise_1971
|
|
||||||
|
|
||||||
curl -k -X POST https://spotlight-jenkins.cisco.com/job/STO_Sparta/job/$JOB_NAME/buildWithParameters \
|
|
||||||
--user iuser:11cdf2ceeab4fd7bd0e3d3bca18066ad2a \
|
|
||||||
--data jobname=$JOB_SCRIPT \
|
|
||||||
--data branch=$BRANCH_NAME \
|
|
||||||
--data revert=true \
|
|
||||||
--data revert_option=init/standalone \
|
|
||||||
--data build=3.4.0.379
|
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
HOSTNAME="sto-sparta-ise-3.cisco.com"
|
|
||||||
USERNAME="admin"
|
|
||||||
PASSWORD="Lab@12345"
|
|
||||||
APPSESSIONID=0
|
|
||||||
CSRFTOKEN=0
|
|
||||||
JWT_TOKEN=0
|
|
||||||
QPC=0
|
|
||||||
|
|
||||||
GREP="grep"
|
|
||||||
BASE64="base64"
|
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
||||||
echo -e "Using g* tools because of course macOS"
|
|
||||||
GREP="ggrep"
|
|
||||||
BASE64="gbase64"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the CSRF token and APPSESSIONID
|
|
||||||
echo -e "Getting CSRF token and initial APPSESSIONID"
|
|
||||||
output=$(curl -c - -k -L -s --compressed --request POST \
|
|
||||||
--url https://$HOSTNAME/admin/JavaScriptServlet \
|
|
||||||
--header 'Accept: */*' \
|
|
||||||
--header 'Accept-Encoding: gzip, deflate, br, zstd' \
|
|
||||||
--header 'Accept-Language: en-US,en;q=0.5' \
|
|
||||||
--header 'Connection: keep-alive' \
|
|
||||||
--header 'Content-Length: 0' \
|
|
||||||
--header 'DNT: 1' \
|
|
||||||
--header 'FETCH-CSRF-TOKEN: 1' \
|
|
||||||
--header 'Origin: CWILLIA5-M-WJ2C' \
|
|
||||||
--header 'Sec-Fetch-Dest: empty' \
|
|
||||||
--header 'Sec-GPC: 1' \
|
|
||||||
--header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:126.0) Gecko/20100101 Firefox/126.0' 2>/dev/null )
|
|
||||||
|
|
||||||
CSRFTOKEN=$(echo $output | $GREP -oP '(?<=OWASP_CSRFTOKEN:)[^#]*')
|
|
||||||
APPSESSIONID=$(echo $output | awk '{print $NF}')
|
|
||||||
echo -e "CSRFTOKEN: $CSRFTOKEN"
|
|
||||||
echo -e "APPSESSIONID: $APPSESSIONID"
|
|
||||||
|
|
||||||
# Get the JWT token
|
|
||||||
echo -e "Logging in, getting JWT token and updating APPSESSIONID"
|
|
||||||
output=$(curl -k -c - --request POST \
|
|
||||||
--cookie "APPSESSIONID=$APPSESSIONID" \
|
|
||||||
--url https://$HOSTNAME/admin/LoginAction.do \
|
|
||||||
--header 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' \
|
|
||||||
--header 'Accept-Encoding: gzip, deflate, br, zstd' \
|
|
||||||
--header 'Accept-Language: en-US,en;q=0.5' \
|
|
||||||
--header 'Connection: keep-alive' \
|
|
||||||
--header 'Content-Type: application/x-www-form-urlencoded' \
|
|
||||||
--header 'DNT: 1' \
|
|
||||||
--header 'Priority: u=1' \
|
|
||||||
--header 'Sec-Fetch-Dest: document' \
|
|
||||||
--header 'Sec-Fetch-Mode: navigate' \
|
|
||||||
--header 'Sec-Fetch-User: ?1' \
|
|
||||||
--header 'Sec-GPC: 1' \
|
|
||||||
--header 'Upgrade-Insecure-Requests: 1' \
|
|
||||||
--header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:126.0) Gecko/20100101 Firefox/126.0' \
|
|
||||||
--data username=$USERNAME \
|
|
||||||
--data password=$PASSWORD \
|
|
||||||
--data samlLogin=false \
|
|
||||||
--data rememberme=off \
|
|
||||||
--data name=$USERNAME \
|
|
||||||
--data password=$PASSWORD \
|
|
||||||
--data authType=Internal \
|
|
||||||
--data CSRFTokenNameValue=OWASP_CSRFTOKEN=$CSRFTOKEN \
|
|
||||||
--data OWASP_CSRFTOKEN=$CSRFTOKEN \
|
|
||||||
--data locale=en \
|
|
||||||
--data hasSelectedLocale=false 2>/dev/null)
|
|
||||||
|
|
||||||
# APPSESSIONID Gets updated here so we need to reassign APPSESSIONID
|
|
||||||
APPSESSIONID=$(echo -e "$output" | awk '/APPSESSIONID/ {print $7}')
|
|
||||||
JWT_TOKEN=$(echo -e "$output" | awk '/MNTLA_JWT_TOKEN/ {print $7}')
|
|
||||||
echo -e "JWT_TOKEN: $JWT_TOKEN"
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Logging out
|
|
||||||
echo -e "Logging out"
|
|
||||||
curl -k "https://$HOSTNAME/admin/logout.jsp" \
|
|
||||||
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:128.0) Gecko/20100101 Firefox/128.0' \
|
|
||||||
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8' \
|
|
||||||
-H 'Accept-Language: en-US,en;q=0.5' \
|
|
||||||
-H 'Accept-Encoding: gzip, deflate, br, zstd' \
|
|
||||||
-H 'Connection: keep-alive' \
|
|
||||||
-H "Cookie: APPSESSIONID=$APPSESSIONID; MNTLA_JWT_TOKEN=$JWT_TOKEN" \
|
|
||||||
-H 'Upgrade-Insecure-Requests: 1' \
|
|
||||||
-H 'Sec-Fetch-Dest: document' \
|
|
||||||
-H 'Sec-Fetch-Mode: navigate' \
|
|
||||||
-H 'Sec-Fetch-Site: same-origin' \
|
|
||||||
-H 'Sec-Fetch-User: ?1' \
|
|
||||||
-H 'Priority: u=0, i'
|
|
2
ise/ise_logparser/.gitignore
vendored
2
ise/ise_logparser/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
/target
|
|
||||||
*.log
|
|
|
@ -1 +0,0 @@
|
||||||
pypy@3.10.14
|
|
140
ise/ise_logparser/Cargo.lock
generated
140
ise/ise_logparser/Cargo.lock
generated
|
@ -1,140 +0,0 @@
|
||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aho-corasick"
|
|
||||||
version = "1.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "const_format"
|
|
||||||
version = "0.2.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673"
|
|
||||||
dependencies = [
|
|
||||||
"const_format_proc_macros",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "const_format_proc_macros"
|
|
||||||
version = "0.2.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-xid",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ise_logparser"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"const_format",
|
|
||||||
"lazy_static",
|
|
||||||
"nom",
|
|
||||||
"nom-regex",
|
|
||||||
"regex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lazy_static"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.7.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "minimal-lexical"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "7.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"minimal-lexical",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom-regex"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72e5c7731c4c1370b61604ed52a2475e861aac9e08dec9f23903d4ddfdc91c18"
|
|
||||||
dependencies = [
|
|
||||||
"nom",
|
|
||||||
"regex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.86"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.36"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "1.10.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-automata",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-automata"
|
|
||||||
version = "0.4.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.8.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-xid"
|
|
||||||
version = "0.2.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
|
|
@ -1,11 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "ise_logparser"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
const_format = "0.2.32"
|
|
||||||
lazy_static = "1.5.0"
|
|
||||||
nom = "7.1.3"
|
|
||||||
nom-regex = "0.2.0"
|
|
||||||
regex = "1.10.6"
|
|
|
@ -1,3 +0,0 @@
|
||||||
# ise-logparser
|
|
||||||
|
|
||||||
Describe your project here.
|
|
|
@ -1,13 +0,0 @@
|
||||||
```
|
|
||||||
pre_test_output := .*
|
|
||||||
start_marker := 'JOB START'
|
|
||||||
test_output := .*
|
|
||||||
end_marker := 'JOB END'
|
|
||||||
post_test_output := .*
|
|
||||||
report_marker := 'Report'
|
|
||||||
report := .*
|
|
||||||
summary_marker := 'Result Summary'
|
|
||||||
summary := .*
|
|
||||||
details_marker := 'Result Details'
|
|
||||||
details := .*
|
|
||||||
```
|
|
|
@ -1,33 +0,0 @@
|
||||||
[project]
|
|
||||||
name = "ise-logparser"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = "Add your description here"
|
|
||||||
authors = [
|
|
||||||
{ name = "Mira Kristipati", email = "akristip@cisco.com" }
|
|
||||||
]
|
|
||||||
dependencies = [
|
|
||||||
"parsy>=2.1",
|
|
||||||
"icecream>=2.1.3",
|
|
||||||
"python-dotenv>=1.0.1",
|
|
||||||
"mypy>=1.11.1",
|
|
||||||
"setuptools>=72.1.0",
|
|
||||||
"colorama>=0.4.6",
|
|
||||||
"types-colorama>=0.4.15.20240311",
|
|
||||||
"flameprof>=0.4",
|
|
||||||
]
|
|
||||||
readme = "README.md"
|
|
||||||
requires-python = ">= 3.8"
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
requires = ["hatchling"]
|
|
||||||
build-backend = "hatchling.build"
|
|
||||||
|
|
||||||
[tool.rye]
|
|
||||||
managed = true
|
|
||||||
dev-dependencies = []
|
|
||||||
|
|
||||||
[tool.hatch.metadata]
|
|
||||||
allow-direct-references = true
|
|
||||||
|
|
||||||
[tool.hatch.build.targets.wheel]
|
|
||||||
packages = ["src/ise_logparser"]
|
|
|
@ -1,43 +0,0 @@
|
||||||
# generated by rye
|
|
||||||
# use `rye lock` or `rye sync` to update this lockfile
|
|
||||||
#
|
|
||||||
# last locked with the following flags:
|
|
||||||
# pre: false
|
|
||||||
# features: []
|
|
||||||
# all-features: false
|
|
||||||
# with-sources: false
|
|
||||||
# generate-hashes: false
|
|
||||||
# universal: false
|
|
||||||
|
|
||||||
-e file:.
|
|
||||||
asttokens==2.4.1
|
|
||||||
# via icecream
|
|
||||||
colorama==0.4.6
|
|
||||||
# via icecream
|
|
||||||
# via ise-logparser
|
|
||||||
executing==2.0.1
|
|
||||||
# via icecream
|
|
||||||
flameprof==0.4
|
|
||||||
# via ise-logparser
|
|
||||||
icecream==2.1.3
|
|
||||||
# via ise-logparser
|
|
||||||
mypy==1.11.1
|
|
||||||
# via ise-logparser
|
|
||||||
mypy-extensions==1.0.0
|
|
||||||
# via mypy
|
|
||||||
parsy==2.1
|
|
||||||
# via ise-logparser
|
|
||||||
pygments==2.18.0
|
|
||||||
# via icecream
|
|
||||||
python-dotenv==1.0.1
|
|
||||||
# via ise-logparser
|
|
||||||
setuptools==72.1.0
|
|
||||||
# via ise-logparser
|
|
||||||
six==1.16.0
|
|
||||||
# via asttokens
|
|
||||||
tomli==2.0.1
|
|
||||||
# via mypy
|
|
||||||
types-colorama==0.4.15.20240311
|
|
||||||
# via ise-logparser
|
|
||||||
typing-extensions==4.12.2
|
|
||||||
# via mypy
|
|
|
@ -1,43 +0,0 @@
|
||||||
# generated by rye
|
|
||||||
# use `rye lock` or `rye sync` to update this lockfile
|
|
||||||
#
|
|
||||||
# last locked with the following flags:
|
|
||||||
# pre: false
|
|
||||||
# features: []
|
|
||||||
# all-features: false
|
|
||||||
# with-sources: false
|
|
||||||
# generate-hashes: false
|
|
||||||
# universal: false
|
|
||||||
|
|
||||||
-e file:.
|
|
||||||
asttokens==2.4.1
|
|
||||||
# via icecream
|
|
||||||
colorama==0.4.6
|
|
||||||
# via icecream
|
|
||||||
# via ise-logparser
|
|
||||||
executing==2.0.1
|
|
||||||
# via icecream
|
|
||||||
flameprof==0.4
|
|
||||||
# via ise-logparser
|
|
||||||
icecream==2.1.3
|
|
||||||
# via ise-logparser
|
|
||||||
mypy==1.11.1
|
|
||||||
# via ise-logparser
|
|
||||||
mypy-extensions==1.0.0
|
|
||||||
# via mypy
|
|
||||||
parsy==2.1
|
|
||||||
# via ise-logparser
|
|
||||||
pygments==2.18.0
|
|
||||||
# via icecream
|
|
||||||
python-dotenv==1.0.1
|
|
||||||
# via ise-logparser
|
|
||||||
setuptools==72.1.0
|
|
||||||
# via ise-logparser
|
|
||||||
six==1.16.0
|
|
||||||
# via asttokens
|
|
||||||
tomli==2.0.1
|
|
||||||
# via mypy
|
|
||||||
types-colorama==0.4.15.20240311
|
|
||||||
# via ise-logparser
|
|
||||||
typing-extensions==4.12.2
|
|
||||||
# via mypy
|
|
|
@ -1,323 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
from __future__ import annotations
|
|
||||||
import cProfile
|
|
||||||
import argparse
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import profile
|
|
||||||
import re
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import cast
|
|
||||||
import time
|
|
||||||
from icecream import ic
|
|
||||||
import pstats
|
|
||||||
|
|
||||||
import parsy as ps
|
|
||||||
from colorama import Back, Fore, Style
|
|
||||||
from parsy import Parser, generate, peek, regex, seq, string
|
|
||||||
from functools import reduce
|
|
||||||
|
|
||||||
ic.configureOutput(includeContext=True)
|
|
||||||
|
|
||||||
LEVEL_UNKNOWN = 255
|
|
||||||
NEWLINE = string("\n")
|
|
||||||
SPACE = string(" ")
|
|
||||||
|
|
||||||
|
|
||||||
class Config(dict[str, str]):
|
|
||||||
class LevelAction(argparse.Action):
|
|
||||||
def __call__(self, parser, namespace, values, option_string=None) -> None:
|
|
||||||
_ = (parser, option_string)
|
|
||||||
values = cast(str, values)
|
|
||||||
setattr(namespace, self.dest, get_debug_level_const(values.upper())[0])
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.dict = {}
|
|
||||||
if os.path.exists(".env"):
|
|
||||||
from dotenv import dotenv_values
|
|
||||||
|
|
||||||
self.dict = {
|
|
||||||
k: v for k, v in dotenv_values(".env").items() if v is not None
|
|
||||||
}
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
if not ("LOGFILE" in self.dict or "LOGFILE" in os.environ):
|
|
||||||
parser.add_argument(
|
|
||||||
"LOGFILE",
|
|
||||||
type=Path,
|
|
||||||
)
|
|
||||||
parser.add_argument("-q", "--query", dest="QUERY")
|
|
||||||
parser.add_argument(
|
|
||||||
"-l",
|
|
||||||
"--level",
|
|
||||||
dest="LOGLEVEL",
|
|
||||||
type=str,
|
|
||||||
choices=["debug", "info", "warn", "err", "crit", "unk"],
|
|
||||||
default=logging.INFO,
|
|
||||||
action=self.LevelAction,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.dict.update(parser.parse_args().__dict__)
|
|
||||||
|
|
||||||
def __getitem__(self, key: str, /) -> str:
|
|
||||||
try:
|
|
||||||
return self.dict[key]
|
|
||||||
except KeyError:
|
|
||||||
return os.environ[key]
|
|
||||||
|
|
||||||
def __setitem__(self, _key: str, _value: str, /) -> None:
|
|
||||||
msg = "Config is read-only"
|
|
||||||
raise NotImplementedError(msg)
|
|
||||||
|
|
||||||
def __delitem__(self, _: str, /) -> None:
|
|
||||||
msg = "Config is read-only"
|
|
||||||
raise NotImplementedError(msg)
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return iter(self.dict)
|
|
||||||
|
|
||||||
def __len__(self) -> int:
|
|
||||||
return len(self.dict)
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return self.dict.__repr__()
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Formatting functions
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def colorize_status(status: str) -> str:
|
|
||||||
if "PASS" in status:
|
|
||||||
return Fore.GREEN + status + Style.RESET_ALL
|
|
||||||
elif "FAIL" in status:
|
|
||||||
return Fore.RED + status + Style.RESET_ALL
|
|
||||||
elif "ERROR" in status:
|
|
||||||
return Fore.BLACK + Back.RED + status + Style.RESET_ALL
|
|
||||||
return status
|
|
||||||
|
|
||||||
|
|
||||||
def get_debug_level_const(level: str) -> tuple[int, str]:
|
|
||||||
if "DEBUG" in level:
|
|
||||||
return (logging.DEBUG, level)
|
|
||||||
elif "INFO" in level:
|
|
||||||
return (logging.INFO, level)
|
|
||||||
elif "WARN" in level:
|
|
||||||
return (logging.WARNING, level)
|
|
||||||
elif "ERR" in level:
|
|
||||||
return (logging.ERROR, level)
|
|
||||||
elif "CRIT" in level:
|
|
||||||
return (logging.CRITICAL, level)
|
|
||||||
else:
|
|
||||||
return (LEVEL_UNKNOWN, level)
|
|
||||||
|
|
||||||
|
|
||||||
def colorize_by_level(level: str, text: str) -> str:
|
|
||||||
if "DEBUG" in level:
|
|
||||||
return Style.DIM + text + Style.RESET_ALL
|
|
||||||
elif "INFO" in level:
|
|
||||||
return Style.BRIGHT + text + Style.RESET_ALL
|
|
||||||
elif "WARN" in level:
|
|
||||||
return Fore.YELLOW + text + Style.RESET_ALL
|
|
||||||
elif "ERR" in level:
|
|
||||||
return Fore.RED + text + Style.RESET_ALL
|
|
||||||
elif "CRIT" in level:
|
|
||||||
return Style.BRIGHT + Back.RED + Fore.BLACK + text + Style.RESET_ALL
|
|
||||||
else:
|
|
||||||
return Fore.BLUE + text + Style.RESET_ALL
|
|
||||||
# return level
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Output functions
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class TestPrinterBuilder:
|
|
||||||
loglevel: int = logging.NOTSET
|
|
||||||
query: str | re.Pattern[str] | None = None
|
|
||||||
|
|
||||||
def __call__(
|
|
||||||
self, ts: str, level: tuple[int, str], src: str, msg: str
|
|
||||||
) -> str | None:
|
|
||||||
level_name = level[1]
|
|
||||||
if (level[0] >= self.loglevel) or (
|
|
||||||
self.query is not None and re.search(self.query, msg)
|
|
||||||
):
|
|
||||||
res = f"{ts}\t{Fore.BLACK + Back.WHITE + level[1] + Style.RESET_ALL}\t{colorize_by_level(level_name,f'{src}: {msg}')}"
|
|
||||||
|
|
||||||
print(res)
|
|
||||||
return res
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def with_loglevel(self, loglevel: int) -> TestPrinterBuilder:
|
|
||||||
self.loglevel = loglevel
|
|
||||||
return self
|
|
||||||
|
|
||||||
def with_query(self, query: str | re.Pattern) -> TestPrinterBuilder:
|
|
||||||
self.query = query
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Parser defs
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def block_parser(text: str) -> Parser:
|
|
||||||
return regex(rf"^.*\n^.*{text}.*$\n.*", re.MULTILINE)
|
|
||||||
|
|
||||||
|
|
||||||
timestamp: Parser = regex(
|
|
||||||
r"^\d{4}-\d{2}-\d{2}.\d{2}:\d{2}:\d{2}(\+\d{2}:\d{2})?(,\d{3})?", re.MULTILINE
|
|
||||||
).skip(string(":").optional())
|
|
||||||
|
|
||||||
debug_level: Parser = regex(r"[A-Za-z0-9_%-]+").skip(string(":").optional())
|
|
||||||
|
|
||||||
|
|
||||||
start_block = block_parser("EASYPY JOB START")
|
|
||||||
end_block = block_parser("EASYPY JOB END")
|
|
||||||
report_block = block_parser("Easypy Report")
|
|
||||||
summary_block = block_parser("Task Result Summary")
|
|
||||||
details_block = block_parser("Task Result Details")
|
|
||||||
|
|
||||||
|
|
||||||
message = ps.any_char.until(ps.alt(ps.peek(timestamp), ps.eof)).concat()
|
|
||||||
|
|
||||||
|
|
||||||
@generate
|
|
||||||
def test_output_line():
|
|
||||||
ts = yield timestamp.skip(SPACE)
|
|
||||||
level = yield debug_level.skip(SPACE)
|
|
||||||
src = yield (
|
|
||||||
string("[").then(regex(r"[A-Za-z_0-9]+")).skip(string("] ")).optional()
|
|
||||||
)
|
|
||||||
msg = yield message.map(lambda x: x.rstrip())
|
|
||||||
|
|
||||||
print_test_line(ts, get_debug_level_const(level), src, msg)
|
|
||||||
return ps.success("")
|
|
||||||
|
|
||||||
|
|
||||||
@generate
|
|
||||||
def test_details():
|
|
||||||
indent = yield (
|
|
||||||
NEWLINE.optional()
|
|
||||||
.skip(string("|").optional())
|
|
||||||
.skip(SPACE.at_least(1))
|
|
||||||
.then(ps.seq(ps.char_from("|`"), string("--").skip(ps.whitespace)).concat())
|
|
||||||
)
|
|
||||||
test_name = yield ps.any_char.until(ps.whitespace).skip(ps.whitespace).concat()
|
|
||||||
test_results = yield ps.letter.many().skip(NEWLINE).concat()
|
|
||||||
print(f" {' ' * (len(indent)//2)} {colorize_status(test_results)}\t{test_name}")
|
|
||||||
return {"test_results": test_results, "test_name": test_name}
|
|
||||||
|
|
||||||
|
|
||||||
@generate
|
|
||||||
def subtask_details():
|
|
||||||
subtask_name = (
|
|
||||||
yield seq(ps.alt(string("|--"), string("`--")), ps.whitespace)
|
|
||||||
.then(ps.any_char.until(ps.whitespace))
|
|
||||||
.skip(ps.whitespace)
|
|
||||||
.concat()
|
|
||||||
)
|
|
||||||
|
|
||||||
subtask_result = yield ps.letter.many().skip(NEWLINE).concat()
|
|
||||||
print(f" {colorize_status(subtask_result)}\t{subtask_name}")
|
|
||||||
tests = yield test_details.many()
|
|
||||||
return {
|
|
||||||
"subtask_result": subtask_result,
|
|
||||||
"subtask_name": subtask_name,
|
|
||||||
"tests": tests,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@generate
|
|
||||||
def task_details():
|
|
||||||
task_number = (
|
|
||||||
yield ps.any_char.until(string(":"))
|
|
||||||
.skip(string(":"))
|
|
||||||
.skip(ps.whitespace)
|
|
||||||
.concat()
|
|
||||||
)
|
|
||||||
|
|
||||||
task_name = yield ps.any_char.until(ps.whitespace).concat().skip(ps.whitespace)
|
|
||||||
print(f"{task_number}\t {Style.BRIGHT + task_name + Style.RESET_ALL}")
|
|
||||||
|
|
||||||
subtasks = yield subtask_details.many()
|
|
||||||
return {"task_number": task_number, "task_name": task_name, "subtasks": subtasks}
|
|
||||||
|
|
||||||
|
|
||||||
@generate
|
|
||||||
# NOTE: Uncomment the print statements if you actually care what's in these sections
|
|
||||||
def sections():
|
|
||||||
header = yield seq(
|
|
||||||
ps.any_char.until(peek(timestamp)), # TODO: output this
|
|
||||||
test_output_line.until(start_block).skip(start_block).skip(NEWLINE),
|
|
||||||
).combine(list.__add__).concat()
|
|
||||||
|
|
||||||
ic(elapsed())
|
|
||||||
test_output = yield test_output_line.until(end_block).skip(end_block).skip(NEWLINE)
|
|
||||||
ic(elapsed())
|
|
||||||
# exit(1)
|
|
||||||
post_test = yield ps.any_char.until(report_block).skip(report_block).concat()
|
|
||||||
ic(elapsed())
|
|
||||||
# print(post_test)
|
|
||||||
report = yield ps.any_char.until(summary_block).skip(summary_block).concat()
|
|
||||||
ic(elapsed())
|
|
||||||
# print(report)
|
|
||||||
summary = yield ps.any_char.until(details_block).skip(details_block).concat()
|
|
||||||
ic(elapsed())
|
|
||||||
# print(summary)
|
|
||||||
details = yield task_details.many()
|
|
||||||
ic(elapsed())
|
|
||||||
etc = yield ps.any_char.until(ps.eof).concat()
|
|
||||||
ic(elapsed())
|
|
||||||
return {
|
|
||||||
"header": header,
|
|
||||||
"test_output": test_output,
|
|
||||||
"post_test": post_test,
|
|
||||||
"report": report,
|
|
||||||
"summary": summary,
|
|
||||||
"details": details,
|
|
||||||
"etc": etc,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def elapsed():
|
|
||||||
global current
|
|
||||||
global prev
|
|
||||||
current = time.time()
|
|
||||||
elapsed = current - prev
|
|
||||||
prev = current
|
|
||||||
return elapsed
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: make this work with streams
|
|
||||||
def main():
|
|
||||||
global current
|
|
||||||
global prev
|
|
||||||
current = time.time()
|
|
||||||
prev = time.time()
|
|
||||||
config = Config()
|
|
||||||
with Path(config["LOGFILE"]).open() as f:
|
|
||||||
log = f.read()
|
|
||||||
global print_test_line
|
|
||||||
print_test_line = TestPrinterBuilder()
|
|
||||||
if loglevel := config["LOGLEVEL"]:
|
|
||||||
print_test_line = print_test_line.with_loglevel(cast(int, loglevel))
|
|
||||||
if query := config.get("QUERY"):
|
|
||||||
print_test_line = print_test_line.with_query(query)
|
|
||||||
|
|
||||||
sections.parse(log)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# import io
|
|
||||||
# pr = cProfile.Profile()
|
|
||||||
# pr.enable()
|
|
||||||
main()
|
|
||||||
# pr.disable()
|
|
||||||
# s = io.StringIO()
|
|
||||||
# ps = pstats.Stats(pr)
|
|
||||||
# ps.dump_stats("test.stats")
|
|
||||||
# print(s.getvalue())
|
|
|
@ -1,69 +0,0 @@
|
||||||
use std::{cell::OnceCell, sync::OnceLock};
|
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use nom::{
|
|
||||||
bytes::complete::take_while1, character::complete::anychar, error::ErrorKind, multi::many_till,
|
|
||||||
IResult,
|
|
||||||
};
|
|
||||||
use nom_regex::str::re_match;
|
|
||||||
use regex::Regex;
|
|
||||||
|
|
||||||
struct Sections {
|
|
||||||
header: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
static TIMESTAMP_REGEX: OnceLock<Regex> = OnceLock::new();
|
|
||||||
static START_BLOCK_REGEX: OnceLock<Regex> = OnceLock::new();
|
|
||||||
static END_BLOCK_REGEX: OnceLock<Regex> = OnceLock::new();
|
|
||||||
fn timestamp<'a>(input: &'a str) -> IResult<&'a str, &'a str> {
|
|
||||||
re_match::<nom::error::Error<&str>>(TIMESTAMP_REGEX.get().unwrap().clone())(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_level(input: &str) -> IResult<&str, &str> {
|
|
||||||
take_while1(|c: char| c.is_alphabetic() || ['_', '-', '%'].contains(&c))(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_block(input: &str) -> IResult<&str, &str> {
|
|
||||||
re_match::<nom::error::Error<&str>>(START_BLOCK_REGEX.get().unwrap().clone())(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end_block(input: &str) -> IResult<&str, &str> {
|
|
||||||
re_match::<nom::error::Error<&str>>(END_BLOCK_REGEX.get().unwrap().clone())(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn test_output_line(input: &str) -> IResult<&str, &str> {
|
|
||||||
let (input, timestamp) = timestamp(input)?;
|
|
||||||
let (input, _) = nom::character::complete::char(' ')(input)?;
|
|
||||||
let (input, level) = debug_level(input)?;
|
|
||||||
let (input, _) = nom::character::complete::char(' ')(input)?;
|
|
||||||
let (input, _) = nom::character::complete::line_ending(input)?;
|
|
||||||
let (input, msg) = message(input)?;
|
|
||||||
IResult::Ok((input, ""))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn header(input: &str) -> IResult<&str, String> {
|
|
||||||
// any_char.until(timestamp).concat()
|
|
||||||
let (_, (b, rest)) = many_till(anychar, timestamp)(input)?;
|
|
||||||
let joined = b.iter().collect::<String>();
|
|
||||||
// test_output_line.until(start_block)
|
|
||||||
let (_, (c, rest)) = many_till(test_output_line, start_block)(rest)?;
|
|
||||||
print!("{}", rest);
|
|
||||||
IResult::Ok((input, joined))
|
|
||||||
}
|
|
||||||
fn sections(log: &str) -> IResult<&str, Sections> {
|
|
||||||
let (_log, _header) = header(log)?;
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
TIMESTAMP_REGEX
|
|
||||||
.set(Regex::new(r"^\d{4}-\d{2}-\d{2}.\d{2}:\d{2}:\d{2}(\+\d{2}:\d{2})?(,\d{3})?").unwrap())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
START_BLOCK_REGEX
|
|
||||||
.set(Regex::new(r"^.*\n^.*EASYPY JOB START.*$\n.*").unwrap())
|
|
||||||
.unwrap();
|
|
||||||
let file = include_str!("../consoleText");
|
|
||||||
header(file);
|
|
||||||
}
|
|
2
ise/reset-ise-passwd/.gitignore
vendored
2
ise/reset-ise-passwd/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
.venv
|
|
||||||
.ruff_cache
|
|
|
@ -1,13 +0,0 @@
|
||||||
{ pkgs ? import <nixpkgs> { } }:
|
|
||||||
|
|
||||||
pkgs.mkShell {
|
|
||||||
packages = [
|
|
||||||
(pkgs.python3.withPackages (python-pkgs: [
|
|
||||||
python-pkgs.pexpect
|
|
||||||
python-pkgs.icecream
|
|
||||||
python-pkgs.mypy
|
|
||||||
# python-pkgs.ruff
|
|
||||||
]))
|
|
||||||
pkgs.openssh
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
import argparse
|
|
||||||
import logging
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
from logging import getLogger
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
import pexpect
|
|
||||||
|
|
||||||
|
|
||||||
def login(username: str, password: str) -> pexpect.spawn:
|
|
||||||
child = pexpect.spawn(
|
|
||||||
f"ssh -i /dev/null {username}@{addr}",
|
|
||||||
encoding="utf-8",
|
|
||||||
logfile=sys.stdout,
|
|
||||||
)
|
|
||||||
child.expect("password:")
|
|
||||||
child.sendline(password)
|
|
||||||
return child
|
|
||||||
|
|
||||||
|
|
||||||
def change_password(child: pexpect.spawn, old_password: str, new_password: str) -> None:
|
|
||||||
child.expect("password:")
|
|
||||||
child.sendline(old_password)
|
|
||||||
child.expect("[Nn]ew password:")
|
|
||||||
child.sendline(new_password)
|
|
||||||
child.expect("[Nn]ew password:")
|
|
||||||
child.sendline(new_password)
|
|
||||||
child.expect_list([re.compile("success"), re.compile(f"{username}#")])
|
|
||||||
logger.info("Changing password to %s", new_password)
|
|
||||||
|
|
||||||
|
|
||||||
def set_new_password_and_verify(
|
|
||||||
child: pexpect.spawn,
|
|
||||||
password: str,
|
|
||||||
new_password: str,
|
|
||||||
) -> pexpect.spawn:
|
|
||||||
change_password(child, password, new_password)
|
|
||||||
|
|
||||||
child = login(username, new_password)
|
|
||||||
child.expect(f"{username}#")
|
|
||||||
return child
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
logger = getLogger(__name__)
|
|
||||||
logger.level = logging.DEBUG
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("addr", help="IP address of the device")
|
|
||||||
parser.add_argument("username", help="Username of the device", default="admin")
|
|
||||||
parser.add_argument("password", help="Password of the device")
|
|
||||||
args = parser.parse_args()
|
|
||||||
username = args.username
|
|
||||||
password = args.password
|
|
||||||
addr = args.addr
|
|
||||||
try:
|
|
||||||
passwords: List[str] = [password] + [
|
|
||||||
"".join([f"{i}{j}" for i in password]) for j in range(4)
|
|
||||||
]
|
|
||||||
|
|
||||||
child = login(username, password)
|
|
||||||
new_password = passwords.pop()
|
|
||||||
child = set_new_password_and_verify(child, password, new_password)
|
|
||||||
|
|
||||||
while len(passwords):
|
|
||||||
password = new_password
|
|
||||||
child.sendline("password")
|
|
||||||
new_password = passwords.pop()
|
|
||||||
child = set_new_password_and_verify(child, password, new_password)
|
|
||||||
|
|
||||||
except Exception:
|
|
||||||
logger.exception("man idek anymore, file a bug")
|
|
44
user.nix
Normal file
44
user.nix
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# User config definitions
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
{
|
||||||
|
|
||||||
|
options = {
|
||||||
|
calliope = {
|
||||||
|
hostname = lib.mkOption {
|
||||||
|
type = string;
|
||||||
|
default = "calliope";
|
||||||
|
|
||||||
|
};
|
||||||
|
ipv4Address = lib.mkOption {
|
||||||
|
type = string;
|
||||||
|
};
|
||||||
|
# TODO:
|
||||||
|
password = lib.mkOption {};
|
||||||
|
cec = lib.mkOption {
|
||||||
|
type = string;
|
||||||
|
username = lib.mkOption {
|
||||||
|
type = string;
|
||||||
|
# TODO: make this default to CEC
|
||||||
|
};
|
||||||
|
defaultShell = mkPackageOption pkgs "shell" {
|
||||||
|
default = [ "bash" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# TODO:
|
||||||
|
authorizedKeys = lib.mkOption {};
|
||||||
|
|
||||||
|
# TODO:
|
||||||
|
sshIdentities = lib.mkOption {};
|
||||||
|
}
|
||||||
|
config = {
|
||||||
|
networking.hostName = options.calliope.hostname;
|
||||||
|
# TODO: set the ipv4 address, and figure out how to set this without knowing interface name
|
||||||
|
# TODO: set default gateway
|
||||||
|
# TODO: use CEC to set up git identity
|
||||||
|
# TODO: set default shell
|
||||||
|
# TODO: set authorized_keys
|
||||||
|
# TODO: set SSH Private keys
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue