Podman kube pod
- Added YAML for a Podman kube pod - Support configuring with environment variables
This commit is contained in:
parent
8a6a9e9380
commit
375d7fc0b7
41
README.md
41
README.md
|
@ -24,13 +24,11 @@ Binary:
|
||||||
```
|
```
|
||||||
Container:
|
Container:
|
||||||
```shell
|
```shell
|
||||||
podman run -it --rm -v hydroxide-config:/data ghcr.io/0ranki/hydroxide-push auth your.proton@email.address
|
podman run -it --rm -v hydroxide-push:/data ghcr.io/0ranki/hydroxide-push auth your.proton@email.address
|
||||||
```
|
```
|
||||||
You will be prompted for the Proton account credentials and the details for the push server. Proton credentials are stored encrypted form.
|
You will be prompted for the Proton account credentials and the details for the push server. Proton credentials are stored encrypted form.
|
||||||
|
|
||||||
The auth flow generates a separate password for the bridge, which is stored in plaintext
|
The auth flow generates a separate password for the bridge to fake a login to the bridge, which is stored in plaintext to `$HOME/.config/notify.json`. Unlike upstream `hydroxide`, there is no service listening on any port, the password isn't useful for anything else.
|
||||||
to `$HOME/.config/notify.json`. Unlike upstream `hydroxide`, there is no service listening on any port,
|
|
||||||
all communications is internal to the program.
|
|
||||||
|
|
||||||
### Reconfigure push server
|
### Reconfigure push server
|
||||||
Binary:
|
Binary:
|
||||||
|
@ -39,12 +37,13 @@ hydroxide-push setup-ntfy
|
||||||
```
|
```
|
||||||
Container:
|
Container:
|
||||||
```shell
|
```shell
|
||||||
podman run -it --rm -v hydroxide-config:/data ghcr.io/0ranki/hydroxide-push setup-ntfy
|
podman run -it --rm -v hydroxide-push:/data ghcr.io/0ranki/hydroxide-push setup-ntfy
|
||||||
```
|
```
|
||||||
You'll be asked for the base URL of the push server, and the topic. These will probably
|
You'll be asked for the base URL of the push server, and the topic. The push endpoint configuration can be changed while the daemon is running.
|
||||||
be combined to a single string in future versions.
|
|
||||||
|
|
||||||
**NOTE:** Authentication for the push endpoint is not yet supported.
|
The currently configured values are shown inside braces. Leave input blank to use the current values.
|
||||||
|
|
||||||
|
>**NOTE:** Authentication for the push endpoint is not yet supported.
|
||||||
|
|
||||||
### Start the service
|
### Start the service
|
||||||
|
|
||||||
|
@ -54,8 +53,32 @@ hydroxide-push notify
|
||||||
```
|
```
|
||||||
Container:
|
Container:
|
||||||
```shell
|
```shell
|
||||||
podman run -it --rm -v hydroxide-config:/data ghcr.io/0ranki/hydroxide-push
|
podman run -it --rm -v hydroxide-push:/data ghcr.io/0ranki/hydroxide-push
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Podman pod
|
||||||
|
|
||||||
|
A Podman kube YAML file is provided in the repo.
|
||||||
|
|
||||||
|
> **Note:** If you're using 2FA or just don't want to put your password to a file, use the manual method above. Make sure the volume name (claimName) in the YAML mathces what you use in the commands.
|
||||||
|
|
||||||
|
- Download/copy `hydroxide-push-podman.yaml` to the machine you intend to run the daemon on
|
||||||
|
- Edit the config values at the top of the file
|
||||||
|
- Start the pod:
|
||||||
|
```shell
|
||||||
|
podman kube play ./hydroxide-push-podman.yaml
|
||||||
|
```
|
||||||
|
- Latest container image is pulled
|
||||||
|
- A named volume (`hydroxide-push`) will be created for the configuration
|
||||||
|
- Login to Proton and push URL configuration is handled automatically, after which the daemon starts
|
||||||
|
- After the initial setup, the ConfigMap (before `---`) can be removed from the YAML.). Optionally to clear the environment variables, run
|
||||||
|
|
||||||
|
```shell
|
||||||
|
podman kube play ./hydroxide-push-podman.yaml --replace
|
||||||
|
```
|
||||||
|
The command can also be used to pull the latest version and restart the pod.
|
||||||
|
- To reauthenticate or clear data, simply remove the named volume or run the `auth` command
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
MIT
|
MIT
|
||||||
|
|
|
@ -74,56 +74,13 @@ func listenEventsAndNotify(addr string, debug bool, authManager *auth.Manager, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const usage = `usage: hydroxide-push [options...] <command>
|
func authenticate(authCmd *flag.FlagSet) {
|
||||||
Commands:
|
var username string
|
||||||
auth <username> Login to ProtonMail via hydroxide
|
if os.Getenv("PROTON_ACCT") != "" {
|
||||||
status View hydroxide status
|
username = os.Getenv("PROTON_ACCT")
|
||||||
notify Start the notification daemon
|
} else {
|
||||||
|
username = authCmd.Arg(0)
|
||||||
Global options:
|
|
||||||
-debug
|
|
||||||
Enable debug logs
|
|
||||||
-api-endpoint <url>
|
|
||||||
ProtonMail API endpoint
|
|
||||||
-app-version <version>
|
|
||||||
ProtonMail application version
|
|
||||||
|
|
||||||
Environment variables:
|
|
||||||
HYDROXIDE_BRIDGE_PASS Don't prompt for the bridge password, use this variable instead
|
|
||||||
`
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.BoolVar(&debug, "debug", false, "Enable debug logs")
|
|
||||||
flag.StringVar(&apiEndpoint, "api-endpoint", defaultAPIEndpoint, "ProtonMail API endpoint")
|
|
||||||
flag.StringVar(&appVersion, "app-version", defaultAppVersion, "ProtonMail app version")
|
|
||||||
|
|
||||||
tlsCert := flag.String("tls-cert", "", "Path to the certificate to use for incoming connections")
|
|
||||||
tlsCertKey := flag.String("tls-key", "", "Path to the certificate key to use for incoming connections")
|
|
||||||
tlsClientCA := flag.String("tls-client-ca", "", "If set, clients must provide a certificate signed by the given CA")
|
|
||||||
|
|
||||||
authCmd := flag.NewFlagSet("auth", flag.ExitOnError)
|
|
||||||
|
|
||||||
flag.Usage = func() {
|
|
||||||
fmt.Print(usage)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
tlsConfig, err := config.TLS(*tlsCert, *tlsCertKey, *tlsClientCA)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = cfg.Read()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := flag.Arg(0)
|
|
||||||
switch cmd {
|
|
||||||
case "auth":
|
|
||||||
authCmd.Parse(flag.Args()[1:])
|
|
||||||
username := authCmd.Arg(0)
|
|
||||||
if username == "" {
|
if username == "" {
|
||||||
log.Fatal("usage: hydroxide auth <username>")
|
log.Fatal("usage: hydroxide auth <username>")
|
||||||
}
|
}
|
||||||
|
@ -142,7 +99,9 @@ func main() {
|
||||||
|
|
||||||
var loginPassword string
|
var loginPassword string
|
||||||
if a == nil {
|
if a == nil {
|
||||||
if pass, err := askPass("Password"); err != nil {
|
if os.Getenv("PROTON_ACCT_PASSWORD") != "" {
|
||||||
|
loginPassword = os.Getenv("PROTON_ACCT_PASSWORD")
|
||||||
|
} else if pass, err := askPass("Password"); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
} else {
|
} else {
|
||||||
loginPassword = string(pass)
|
loginPassword = string(pass)
|
||||||
|
@ -218,6 +177,60 @@ func main() {
|
||||||
}
|
}
|
||||||
cfg.BridgePw = bridgePassword
|
cfg.BridgePw = bridgePassword
|
||||||
cfg.Setup()
|
cfg.Setup()
|
||||||
|
}
|
||||||
|
|
||||||
|
const usage = `usage: hydroxide-push [options...] <command>
|
||||||
|
Commands:
|
||||||
|
auth <username> Login to ProtonMail via hydroxide
|
||||||
|
status View hydroxide status
|
||||||
|
notify Start the notification daemon
|
||||||
|
setup-ntfy (Re)configure the push endpoint
|
||||||
|
|
||||||
|
Global options:
|
||||||
|
-debug
|
||||||
|
Enable debug logs
|
||||||
|
-api-endpoint <url>
|
||||||
|
ProtonMail API endpoint
|
||||||
|
-app-version <version>
|
||||||
|
ProtonMail application version
|
||||||
|
|
||||||
|
Environment variables:
|
||||||
|
HYDROXIDE_BRIDGE_PASS Don't prompt for the bridge password, use this variable instead
|
||||||
|
`
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.BoolVar(&debug, "debug", false, "Enable debug logs")
|
||||||
|
flag.StringVar(&apiEndpoint, "api-endpoint", defaultAPIEndpoint, "ProtonMail API endpoint")
|
||||||
|
flag.StringVar(&appVersion, "app-version", defaultAppVersion, "ProtonMail app version")
|
||||||
|
|
||||||
|
tlsCert := flag.String("tls-cert", "", "Path to the certificate to use for incoming connections")
|
||||||
|
tlsCertKey := flag.String("tls-key", "", "Path to the certificate key to use for incoming connections")
|
||||||
|
tlsClientCA := flag.String("tls-client-ca", "", "If set, clients must provide a certificate signed by the given CA")
|
||||||
|
|
||||||
|
authCmd := flag.NewFlagSet("auth", flag.ExitOnError)
|
||||||
|
|
||||||
|
flag.Usage = func() {
|
||||||
|
fmt.Print(usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
tlsConfig, err := config.TLS(*tlsCert, *tlsCertKey, *tlsClientCA)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = cfg.Read()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := flag.Arg(0)
|
||||||
|
switch cmd {
|
||||||
|
case "auth":
|
||||||
|
authCmd.Parse(flag.Args()[1:])
|
||||||
|
authenticate(authCmd)
|
||||||
|
|
||||||
case "status":
|
case "status":
|
||||||
usernames, err := auth.ListUsernames()
|
usernames, err := auth.ListUsernames()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -235,7 +248,15 @@ func main() {
|
||||||
|
|
||||||
case "setup-ntfy":
|
case "setup-ntfy":
|
||||||
cfg.Setup()
|
cfg.Setup()
|
||||||
|
|
||||||
case "notify":
|
case "notify":
|
||||||
|
if os.Getenv("PROTON_ACCT_PASSWORD") != "" && os.Getenv("PROTON_ACCT") != "" && os.Getenv("PUSH_URL") != "" && os.Getenv("PUSH_TOPIC") != "" && cfg.BridgePw == "" {
|
||||||
|
log.Println("Logging in to Proton account using values from environment")
|
||||||
|
cfg.URL = os.Getenv("PUSH_URL")
|
||||||
|
cfg.Topic = os.Getenv("PUSH_TOPIC")
|
||||||
|
cfg.Save()
|
||||||
|
authenticate(new(flag.FlagSet))
|
||||||
|
}
|
||||||
authManager := auth.NewManager(newClient)
|
authManager := auth.NewManager(newClient)
|
||||||
eventsManager := events.NewManager()
|
eventsManager := events.NewManager()
|
||||||
listenEventsAndNotify("0", debug, authManager, eventsManager, tlsConfig)
|
listenEventsAndNotify("0", debug, authManager, eventsManager, tlsConfig)
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
## Remove this ConfigMap section after the initial run
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: hydroxide-push-config
|
||||||
|
data:
|
||||||
|
PROTON_ACCT: "my.account@protonmail.com"
|
||||||
|
PROTON_ACCT_PASSWORD: "myprotonaccountpassword"
|
||||||
|
PUSH_URL: "http://ntfy.sh"
|
||||||
|
PUSH_TOPIC: ""
|
||||||
|
## Remove the above after first run
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: "2024-03-27T07:02:59Z"
|
||||||
|
labels:
|
||||||
|
app: hydroxide-push
|
||||||
|
name: hydroxide-push
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- args:
|
||||||
|
- notify
|
||||||
|
image: ghcr.io/0ranki/hydroxide-push:latest
|
||||||
|
name: main
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /data
|
||||||
|
name: hydroxide-push-pvc
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: hydroxide-push-config
|
||||||
|
optional: true
|
||||||
|
volumes:
|
||||||
|
- name: hydroxide-push-pvc
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: hydroxide-push
|
||||||
|
|
16
ntfy/ntfy.go
16
ntfy/ntfy.go
|
@ -63,7 +63,7 @@ func ntfyConfigFile() (string, error) {
|
||||||
func Notify() {
|
func Notify() {
|
||||||
cfg := NtfyConfig{}
|
cfg := NtfyConfig{}
|
||||||
if err := cfg.Read(); err != nil {
|
if err := cfg.Read(); err != nil {
|
||||||
log.Printf("error reading notification: %v", err)
|
log.Printf("error reading configuration: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req, _ := http.NewRequest("POST", cfg.URI(), strings.NewReader("New message received"))
|
req, _ := http.NewRequest("POST", cfg.URI(), strings.NewReader("New message received"))
|
||||||
|
@ -148,11 +148,25 @@ func Login(cfg *NtfyConfig, be backend.Backend) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *NtfyConfig) Setup() {
|
func (cfg *NtfyConfig) Setup() {
|
||||||
|
|
||||||
|
// Configure using environment
|
||||||
|
if os.Getenv("PUSH_URL") != "" && os.Getenv("PUSH_TOPIC") != "" {
|
||||||
|
cfg.URL = os.Getenv("PUSH_URL")
|
||||||
|
cfg.Topic = os.Getenv("PUSH_TOPIC")
|
||||||
|
log.Printf("Current push endpoint: %s\n", cfg.URI())
|
||||||
|
err := cfg.Save()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var n string
|
var n string
|
||||||
if cfg.URL != "" && cfg.Topic != "" {
|
if cfg.URL != "" && cfg.Topic != "" {
|
||||||
fmt.Printf("Current push endpoint: %s\n", cfg.URI())
|
fmt.Printf("Current push endpoint: %s\n", cfg.URI())
|
||||||
n = "new "
|
n = "new "
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read push base URL
|
// Read push base URL
|
||||||
notValid := true
|
notValid := true
|
||||||
scanner := bufio.NewScanner(os.Stdin)
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
|
Loading…
Reference in New Issue