first commit
This commit is contained in:
150
PROJECT.md
Normal file
150
PROJECT.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# Project: HanaToolbox
|
||||
|
||||
The project should be written in C#, it should use .NET 10 and it should be compiled as native AOT.
|
||||
Note that .NET 10 is the only SDK installed on this system, so you don't need to specify it.
|
||||
|
||||
I have provided the templates folder with some Bash script files. These contain some tools which help me with managing systems.
|
||||
The systems I'm managing are SUSE Linux systems, which have SAP Business One and SAP HANA databases on them. The scripts are used for creating backups, cleaning up log backups, generating firewall rules, exporting schemas, importing schemas, and monitoring the system.
|
||||
|
||||
Your task is to create a C# application which will provide the same functionality as the Bash scripts. The application should be a console application and it should be compiled as native AOT.
|
||||
|
||||
The application should have the following features:
|
||||
- Cron systems:
|
||||
- Backup (Create tenant backups at a set time every day, backup.sh)
|
||||
- Clean up log backups (Delete log and tenant backups older than a set time every day, cleanup.sh)
|
||||
- Monitor (Monitor the system, monitor.sh)
|
||||
- Generate firewall rules (Generate firewall rules for the system, firewall.sh)
|
||||
- Aurora (Create a new schema early morning every day, so the customer has a fresh test schema, aurora.sh)
|
||||
- Non-cron systems:
|
||||
- Export schema (Export schema of the system, hanatools.sh)
|
||||
- Import schema (Import schema of the system, hanatools.sh)
|
||||
- Keymanager (Manage the hdbuserstore, keymanager.sh)
|
||||
|
||||
## Questions
|
||||
|
||||
### General Architecture
|
||||
1. **Single binary or multi-command CLI?** The Bash scripts are separate files that call each other (e.g., `backup.sh` invokes `hanatool.sh`). Should the C# app be a single executable with subcommands (e.g., `hanatoolbox backup`, `hanatoolbox export`, `hanatoolbox keymanager`), similar to how `git` or `docker` work? Or should there be separate executables per tool?
|
||||
|
||||
Answer: Yes, I want a single executable with subcommands.
|
||||
|
||||
2. **Configuration format** — The Bash scripts use `.conf` files that are simple `KEY=VALUE` shell files sourced at runtime. Should the C# app use a similar flat format, or would you prefer a structured format like **JSON**, **TOML**, or **YAML** for the configuration files? Should the config file location be fixed (next to the binary) or configurable via a flag?
|
||||
|
||||
Answer: Structured formats like JSON would be perfect for this.
|
||||
|
||||
3. **Logging** — The Bash scripts print emoji-prefixed progress messages to stdout/stderr. Should the C# app replicate this exact style (colorful, emoji-rich console output), or would you prefer a more structured approach (e.g., using a logging library with severity levels like `INFO`, `WARN`, `ERROR`)? Should log output also be written to a file?
|
||||
|
||||
Answer: I want a verbose flag which prints out also info and warnings, but generally I only want to log errors. You can log them in the structured C# kind of way.
|
||||
|
||||
### Cron / Scheduling
|
||||
4. **Built-in scheduler or external cron?** The scripts are designed to be called by the OS cron daemon. Should the C# app include its own built-in scheduler (running as a daemon/service), or should the compiled binary still be invoked directly by a system cron job — just replacing the Bash scripts as the executable?
|
||||
|
||||
Answer: The binary should be called by the system cron job with the command cron, and I also want another command where I can set up the cron job. So basically a TUI; you can use Spectre.Console for that. Keep in mind that Spectre.Console is compatible with AOT, but Spectre.Console.Cli is not, so use the System.CommandLine library for that. I also plan to run the cron job every minute, so make sure you think about that.
|
||||
|
||||
5. **Systemd integration** — If it runs as a daemon, should it integrate with systemd (e.g., notify readiness via `sd_notify`, handle `SIGTERM` gracefully)?
|
||||
|
||||
Answer: No, I don't need systemd integration.
|
||||
|
||||
### `hanatool` / Core Functionality
|
||||
6. **HDB client path detection** — `hanatool.sh` checks two hardcoded paths (`/usr/sap/hdbclient` and `/usr/sap/NDB/HDB00/exe`). Should the C# app keep these same two fallback paths, or make them fully configurable? Are those the only two paths that ever appear in the wild across your managed systems?
|
||||
|
||||
Answer: The program will need to have access to HDBSQL and HDBUserStore binaries or scripts. So you can also get them with the which command, but these are generally the two paths that they are usually located in.
|
||||
|
||||
7. **`install.sh` scope** — `install.sh` downloads scripts from your Gitea instance (`git.technopunk.space`). Should this self-updater/installer also be ported to C#, or is it out of scope since the C# app will be distributed differently (e.g., as a single AOT binary)?
|
||||
|
||||
Answer: Yeah, keep the install.sh because I will grab this binary from my git instance. So the install logic should be roughly the same, but it will only get this binary file, not the thousands of scripts.
|
||||
|
||||
8. **ntfy.sh notifications** — `hanatool.sh` and `monitor.sh` send notifications to a hardcoded ntfy topic URL (`https://ntfy.technopunk.space/sap`). Should the ntfy topic URL and bearer token be configurable in a global config file, or per-tool config? Should the C# app support sending notifications on success, failure, or both (currently the scripts only send on both but the behaviour differs per script)?
|
||||
|
||||
Answer: You can hardcode the URL, but actually you can hardcode the token as well. Since it's a binary it's very difficult to get it out of.
|
||||
|
||||
### Firewall Tool
|
||||
9. **Interactive vs. non-interactive** — `firewalld.sh` is fully interactive (menu-driven). Should the C# port also be interactive (like a TUI), or should it be a pure CLI tool where service rules are passed as arguments or defined in a config file upfront?
|
||||
|
||||
Answer: I want a TUI. Spectre.Console again here.
|
||||
|
||||
10. **Predefined services** — The firewall script has 8 hardcoded SAP-related services with fixed port numbers. Should these remain hardcoded in the C# app, or should they be loaded from a configurable list so you can add/remove services without recompiling?
|
||||
|
||||
Answer: I want to keep them hardcoded.
|
||||
|
||||
### Key Manager
|
||||
11. **Interactive TUI or CLI subcommands?** — `keymanager.sh` is an interactive menu. Should the C# version also be interactive (e.g., using `Spectre.Console` prompts), or should it expose subcommands like `hanatoolbox keymanager add`, `hanatoolbox keymanager delete`, `hanatoolbox keymanager test`?
|
||||
|
||||
Answer: I want a TUI. Spectre.Console again.
|
||||
|
||||
### Monitor
|
||||
12. **State persistence** — `monitor.sh` stores alert state in flat `.state` files under a `monitor_state/` directory to avoid duplicate notifications. Should the C# app use the same file-based state mechanism, or would you prefer a lightweight embedded database (e.g., SQLite)?
|
||||
|
||||
Answer: Whatever is more simple, if you can use an embedded database while still keeping the codebase relatively simple and easy to maintain, then you can do that, otherwise you can stick with the very simple file-based system.
|
||||
|
||||
### Aurora
|
||||
13. **Post-import SQL scripts** — `aurora.sh` supports running arbitrary SQL files from a configurable `SQL_SCRIPTS_ROOT` directory after the import. Should this feature be preserved in the C# version?
|
||||
|
||||
Answer: No need for these scripts to run.
|
||||
|
||||
### Deployment
|
||||
14. **Target user / privilege level** — The scripts invoke `firewall-cmd` and other privileged tools. Is the app expected to be run as root, or via `sudo`? Should it handle privilege escalation internally (e.g., re-exec itself with sudo if not root)?
|
||||
|
||||
Answer: By default I want it to run as root, however most other parts should run as the tenant user for SAP HANA. So that means if I want to use keymanager, backup, aurora, monitor, etc. you need to do a `su - <SID>adm` and then run the command. In 90% of the cases the SID is just NDB. But there are some exceptions where the SID is different, so I want to be able to specify the SID in the command line.
|
||||
|
||||
15. **Multi-system management** — Each system currently has its own copy of the scripts with its own `.conf` files. Should the C# app manage a single local system only, or should it be able to target remote systems (e.g., via SSH)?
|
||||
|
||||
Answer: I only want to do local systems, so I will install this binary into every single system manually. It's fine.
|
||||
|
||||
I also want basically an onboard command where I can do the initial setup for all the parameters and everything.
|
||||
|
||||
---
|
||||
|
||||
## Follow-up Questions (Round 2)
|
||||
|
||||
### Cron Scheduling
|
||||
16. **Schedule storage model** — Since the `cron` command runs every minute, the app needs to know which tasks are due. Should each scheduled task store its own "next run time" or "last run time" in the state/config, and the `cron` command checks whether enough time has passed since the last run? Or should the schedule be expressed as a cron expression (e.g., `"0 2 * * *"`) that the app evaluates itself?
|
||||
|
||||
Answer: So for backups, Aurora, and the cleaner parts, they will need to run at a set time each day. So for that, you can just check basically the system time and then make sure that it runs when it needs to run. For the monitor, the monitor needs to run often. So, basically, you shouldn't create a separate monitor; you should monitor every time the cron command runs.
|
||||
|
||||
17. **Which tasks are cron-driven?** — The project lists Backup, Cleanup, Monitor, Firewall, and Aurora as cron tasks. Should all five be independently schedulable (each with their own time), or is the intent that Monitor runs every minute (so it's always called on every cron tick) while the others run once a day at a configured time?
|
||||
|
||||
Answer: Monitor runs every minute, and the others run once a day at a configured time.
|
||||
|
||||
18. **`cron setup` TUI scope** — When you run `hanatoolbox cron setup`, should it let you configure the schedule and settings for *all* cron tasks in one flow, or just install/update the system crontab entry for the binary itself (i.e., add `* * * * * /path/to/hanatoolbox cron` to the user's crontab)?
|
||||
|
||||
Answer: The cron setup should let me configure all the schedule and settings for all the cron tasks. So I will do the system cron tab manually. But generally the cron setup command in the binary should let me configure the actual settings and schedule.
|
||||
|
||||
### Configuration & Onboarding
|
||||
19. **Single config file or per-tool?** — The Bash scripts use separate `.conf` files per tool (`backup.conf`, `aurora.conf`, `monitor.conf`). Should the C# app use one global `hanatoolbox.json` file covering all tools, or separate JSON files per subsystem? And where should it be stored — next to the binary, in `/etc/hanatoolbox/`, or somewhere else?
|
||||
|
||||
Answer: I want to use one global `hanatoolbox.json` file covering all tools, and it should be stored in `/etc/hanatoolbox/`.
|
||||
|
||||
20. **`onboard` command scope** — Should `onboard` be a guided TUI wizard that walks through every setting for every tool in one session, or should each tool have its own `configure` subcommand (e.g., `hanatoolbox backup configure`) so you can re-configure individual tools later without redoing everything?
|
||||
|
||||
Answer: The onboard command should be a TUI wizard that walks through every setting for every tool. So that means that it should create the user store keys based on the key manager. It should ask for the backup locations, the schedules, everything.
|
||||
|
||||
### User Switching
|
||||
21. **How to switch to `<SID>adm`?** — When the app (running as root) needs to execute HANA operations, should it shell out the relevant process via `su - ndbadm -c "<command>"`, or use `runuser -l ndbadm -c "<command>"`? Some operations like `hdbuserstore` are very sensitive to which user's home directory is used, so I want to make sure the switching strategy matches what the Bash scripts were doing.
|
||||
|
||||
Answer: I'm not sure what the difference is, but the first one works perfectly for now. So `su - ndbadm -c <command>`.
|
||||
|
||||
22. **SID as a global config value or per-invocation flag?** — Should the HANA SID (defaulting to `NDB`) be stored in the global config and optionally overridden with a `--sid` flag on any command, or should it only ever be set in the config file?
|
||||
|
||||
Answer: I want the SID to be stored in the global config and optionally overridden with a `--sid` flag on any command.
|
||||
|
||||
### ntfy Notifications
|
||||
23. **Token as a compile-time placeholder** — Since both the URL and token will be hardcoded into the binary, should I leave them as clearly-named compile-time constants (e.g., `const string NtfyToken = "YOUR_TOKEN_HERE"`) that you fill in before building, or do you want to provide the actual token now so it can be set from the start?
|
||||
|
||||
Answer: Here's the token: "tk_ggis2y224ip7r5q0p6x3v2t4j1q7m"
|
||||
|
||||
### Cleaner / Cleanup
|
||||
24. **`cleaner.sh` target paths** — `cleaner.sh` takes `<retention_days>:<path>` pairs as arguments. In the C# version (which is cron-driven), those pairs need to come from config. What paths and retention periods are typically configured? For example: tenant backup files for 7 days, log backup files for 3 days? Knowing the typical setup will help design the config schema correctly.
|
||||
|
||||
Answer: Tenant backup files for 7 days, log backup files for 1 day. Keep in mind that log backups can be found in multiple locations, so I want to be able to specify multiple paths.
|
||||
|
||||
### Firewall
|
||||
25. **`firewall-cmd` only?** — The script uses `firewall-cmd` (firewalld). Can I assume all target systems use firewalld, or do some use raw `iptables`/`nftables` that would need a different backend?
|
||||
|
||||
Answer: I want to use `firewall-cmd` only.
|
||||
|
||||
### Aurora
|
||||
26. **`_AURORA` suffix — always fixed?** — `aurora.sh` always names the target schema `<SOURCE_SCHEMA>_AURORA`. Should this suffix be hardcoded in the C# version too, or do you want it to be configurable per instance?
|
||||
|
||||
Answer: I want to use the suffix as hardcoded in the C# version.
|
||||
|
||||
I also want to adhere to the SOLID principles as much as possible. For easy maintenance and extensibility, I want to use the SOLID principles as much as possible.
|
||||
Reference in New Issue
Block a user