cloud_terrastodon 0.35.0

A command-line tool for interacting with cloud ecosystems
# TODO


## Policy definition and set definition properties type


Currently we are flattening the properties in the type when the properties struct should be a separate type.

[text](crates/azure_types/src/policy_definition.rs)
[text](crates/azure/src/policy_definitions.rs)

[can finish this test once changed](crates/azure_types/tests/policy_compliance_evaluation_test_tags.rs)

## Access token reauth


`az account get-access-token` will do a reauth flow which we don't want, so need to read the tokens beforehand to determine if they are valid and if not bail. we can maybe track the latest login time from `ct tenant login` or read the tokens directly.

verification command:

cloud_terrastodon.exe rest --method GET --url https://graph.microsoft.com/v1.0/organization --tenant ssc

will do login flow if the `az login` has expired but it won't actually refresh the cred properly.

## Relative Location


Audit for cloud_terrastodon_relative_location usage, and identify spots where Location is used without RelativeLocation that we should fix.

## Subscription Name


- Add subscription name to resources with subscription id like resource groups
Maybe a `.name().await` helper that is memoized?

## Tags


Add a AzureTagKey and AzureTagValue type

## Parsing rewrite


chunks
/subscriptions/dbc82d5f-1d23-4772-99e2-4d47cfb9a949/resourceGroups/my-resource-group-123/providers/Microsoft.Network/publicIPAddresses/my-public-ip
/     0       /                1                   /      2       /           3         /    4    /        5        /       6         /     7
chunks[0..=1].with_trailing_slash() -> &str "/subscriptions/dbc82d5f-1d23-4772-99e2-4d47cfb9a949/"
chunks[0..=1].without_trailing_slash() -> &str "/subscriptions/dbc82d5f-1d23-4772-99e2-4d47cfb9a949"

## Location


Unify `location: String` and `location: CompactString` to use `location: AzureLocationName`

## Formatting


> https://mina86.com/2024/fmt-display-impl/
> You’re implementing fmt::Display wrong
> Posted by Michał ‘mina86’ Nazarewicz on 12th of May 2024

Update our `std::fmt::Display` to `core::fmt::Display` following the guidance in that blog post

## Tests


- Update tests to not print details when fetching resources; avoid AI agents seeing our resource info. Just print "Found {} resource groups" instead of printing the names and stuff.
- Should ensure a `browse` or `list` cli command exists for the tests that will no longer print names and stuff

## Azure DevOps


Add optional --org-url arg to commands that use an org url to support overriding the default organization url

## Logging


Allow specifying a path after `--json` global arg, using current logic if not provided.

## Cloud lint


- App registrations with expired (client secrets|certificates)
- App registrations with (client secrets|certificates) that are expiring in 30 days when no (client secrets|certificates) exists that is expiring in more than 30 days from now
- Users who are Owner on App Registration without having Directory Reader role or similar

## VM sku permission


- list skus
- find assignments for "Allowed virtual machine size SKUs" policy - /providers/microsoft.authorization/policydefinitions/cccc23c7-8427-4f53-ad12-b6a63eb452b3 to filter
https://stackoverflow.com/a/73192111/11141271
az vm list-sizes --location canadacentral
az rest --method get `
  --uri "https://prices.azure.com/api/retail/prices?$filter=serviceName eq 'Virtual Machines' and armRegionName eq 'canadacentral' and (contains(armSkuName, 'Promo') eq false and contains(armSkuName, 'Standard_B') eq false)"

## Oauth2

Add oauth2 permission scope browser

## Graph


Add general-purpose ms graph postman/rest api helper

## General


- PickerTui highlight matching chars like fzf
- Graceful exit when user hits esc to quit from main or submenus
- browse resource groups should look more like az role assignment list dialog
    - output full expanded form id for copy pasting as terraform import
- Update user fetching to use graph batch; add `otherMails` property
- Implement `audit_azure.rs` to use `otherMails` property

## New Types


- Add `VirtualMachineName` type
- Add `VirtualMachineSizeSku` type
    - If struct, add `fetch_all_virtual_machine_size_skus()`
    - If enum, add `VARIANTS` array
    

## Virtual Machine Images


- Add virtual machine image discovery
    - Include link to helper resource
    - https://az-vm-image.info/?cmd=--all+--publisher+center-for-internet-security-inc


0. Observe az cli
    - `az vm image list --all --publisher center-for-internet-security-inc --debug`
1. Fetch publishers
    - `az rest --method get --url "https://management.azure.com/subscriptions/{subscription_id}/providers/Microsoft.Compute/locations/canadacentral/publishers?api-version=2024-11-01"`
2. Fetch offers
    - `az rest --method get --url "https://management.azure.com/subscriptions/{subscription_id}/providers/Microsoft.Compute/locations/canadacentral/publishers/center-for-internet-security-inc/artifacttypes/vmimage/offers?api-version=2024-07-01"`
3. Check `accepted` in terms
    - `az vm image terms show --urn center-for-internet-security-inc:cis-windows-server:cis-windows-server2016-l2-gen2:latest`

## Privileges


- Add entra role definition fetch
- Add prediction for privileged operation like creating security group

## Linting


- cloud lint: assert `name.trim()==name` for all entra groups

## Discovery and Navigation Properties


"My website https://blah.agr.gc.ca/ is down"
-> NSLOOKUP
-> discover application-gateway.listeners and app-services.custom_domains that match
-> app gateway backend pools gives IPs
-> IPs give private endpoint
-> private endpoint gives resource

## Documentation


- Nice docs like Winnow https://docs.rs/winnow/latest/winnow/_tutorial/index.html

## Authentication


- jwt auth verification
- https://github.com/ramosbugs/openidconnect-rs
- https://www.whatismytenantid.com/
    - https://login.microsoftonline.com/agr.gc.ca/.well-known/openid-configuration
- https://login.microsoftonline.com/9da98bb1-1857-4cc3-8751-9a49e35d24cd/discovery/v2.0/keys
- https://sts.windows.net/9da98bb1-1857-4cc3-8751-9a49e35d24cd/.well-known/openid-configuration
- https://login.windows.net/common/discovery/keys