@@ -53,7 +53,7 @@ show_help() {
53
53
echo " COMMANDS:"
54
54
echo " quickstart [--demo] [--api-key=KEY] [--db-url=URL] [-y] Complete setup: install, configure, and start monitoring"
55
55
echo " install [--demo] Clone repository and setup the monitoring project"
56
- echo " start Start all monitoring services using Docker Compose"
56
+ echo " start Start all monitoring services using Docker Compose (auto-generates secure Grafana password) "
57
57
echo " stop Stop all services"
58
58
echo " restart Restart all services"
59
59
echo " status Show status of all services"
@@ -77,6 +77,10 @@ show_help() {
77
77
echo " show-key Show current API key (masked)"
78
78
echo " remove-key Remove stored API key"
79
79
echo " "
80
+ echo " GRAFANA PASSWORD MANAGEMENT:"
81
+ echo " generate-grafana-password Generate secure password for Grafana"
82
+ echo " show-grafana-credentials Show current Grafana credentials"
83
+ echo " "
80
84
echo " OPTIONS:"
81
85
echo " --demo Include demo PostgreSQL database for testing"
82
86
echo " --api-key=KEY Provide API key for automated report uploads"
@@ -99,11 +103,13 @@ show_help() {
99
103
echo " 0ドル quickstart -y --api-key=key --db-url=postgresql://user:pass@host:5432/db # Fully automated setup"
100
104
echo " 0ドル install # Clone repository and setup for production"
101
105
echo " 0ドル install --demo # Clone repository and setup with demo database"
102
- echo " 0ドル start # Start monitoring services"
106
+ echo " 0ドル start # Start monitoring services (auto-generates secure Grafana password) "
103
107
echo " 0ドル logs pgwatch-postgres # Show logs for postgres pgwatch instance"
104
108
echo " 0ドル health # Check if all services are healthy"
105
109
echo " 0ドル shell target-db # Open shell in target database (demo mode only)"
106
110
echo " 0ドル check # Verify system prerequisites and readiness"
111
+ echo " 0ドル generate-grafana-password # Generate secure password for Grafana"
112
+ echo " 0ドル show-grafana-credentials # Show current Grafana login credentials"
107
113
echo " "
108
114
echo " INSTANCE MANAGEMENT EXAMPLES:"
109
115
echo " 0ドル list-instances # Show all configured instances"
@@ -118,17 +124,18 @@ show_help() {
118
124
echo " • Add '--api-key=your_key' to any quickstart command for automated report uploads"
119
125
echo " • Add '--db-url=postgresql://user:pass@host:port/db' to automatically configure a database"
120
126
echo " • Add '-y' to accept all defaults and skip interactive prompts (useful for automation)"
127
+ echo " • Secure Grafana password is automatically generated for all setups"
121
128
echo " "
122
129
echo " MANUAL SETUP:"
123
130
echo " PRODUCTION MODE:"
124
131
echo " 1. Run '0ドル install' to setup monitoring infrastructure"
125
132
echo " 2. Add your PostgreSQL instances: '0ドル add-instance postgresql://user:pass@host:port/db'"
126
- echo " 3. Start monitoring: '0ドル start'"
133
+ echo " 3. Start monitoring: '0ドル start' (auto-generates secure Grafana password) "
127
134
echo " "
128
135
echo " DEMO MODE:"
129
136
echo " 1. Run '0ドル install --demo' to setup with demo database included"
130
- echo " 2. Start all services: '0ドル start'"
131
- echo " 3. Access demo database at localhost:5432 "
137
+ echo " 2. Start all services: '0ドル start' (auto-generates secure Grafana password) "
138
+ echo " 3. Access demo database at localhost:55432 "
132
139
echo " "
133
140
echo " The CLI auto-detects the project directory and should be run from outside it"
134
141
echo
@@ -146,12 +153,12 @@ show_help() {
146
153
echo " 🚀 MAIN: Grafana Dashboard: http://localhost:3000 (demouser/demopwd)"
147
154
echo " "
148
155
echo " Technical URLs (for advanced users):"
149
- echo " PGWatch Postgres: http://localhost:8080 "
150
- echo " PGWatch Prometheus: http://localhost:8089 "
151
- echo " Prometheus: http://localhost:9090 "
152
- echo " Flask API: http://localhost:5000 "
153
- echo " Sink DB: postgresql://postgres:postgres@localhost:5433 /postgres"
154
- echo " Demo DB: postgresql://postgres:postgres@localhost:5432 /target_database (--demo mode only)"
156
+ echo " PGWatch Postgres: http://localhost:58080 "
157
+ echo " PGWatch Prometheus: http://localhost:58089 "
158
+ echo " Prometheus: http://localhost:59090 "
159
+ echo " Flask API: http://localhost:55000 "
160
+ echo " Sink DB: postgresql://postgres:postgres@localhost:55433 /postgres"
161
+ echo " Demo DB: postgresql://postgres:postgres@localhost:55432 /target_database (--demo mode only)"
155
162
}
156
163
157
164
# Check basic prerequisites (software installation)
@@ -243,7 +250,7 @@ check_system_resources() {
243
250
fi
244
251
245
252
# Check if required ports are available
246
- local required_ports=(3000 5000 5432 5433 8080 8089 9090 )
253
+ local required_ports=(3000 55000 55432 55433 58080 58089 59090 )
247
254
local ports_in_use=()
248
255
249
256
for port in " ${required_ports[@]} " ; do
@@ -261,8 +268,8 @@ check_system_resources() {
261
268
if [ ${# ports_in_use[@]} -ne 0 ]; then
262
269
log_warning " The following ports are already in use: ${ports_in_use[*]} "
263
270
log_warning " This may cause conflicts when starting services"
264
- echo " Required ports: 3000 (Grafana), 5000 (Flask), 5432 (Target DB), 5433 (Sink DB),"
265
- echo " 8080 (PGWatch), 8089 (PGWatch Prometheus), 9090 (Prometheus)"
271
+ echo " Required ports: 3000 (Grafana), 55000 (Flask), 55432 (Target DB), 55433 (Sink DB),"
272
+ echo " 58080 (PGWatch), 58089 (PGWatch Prometheus), 59090 (Prometheus)"
266
273
fi
267
274
268
275
log_success " System resources check completed"
@@ -471,6 +478,146 @@ is_demo_mode() {
471
478
return 1
472
479
}
473
480
481
+ # Password Generator Functions
482
+
483
+ # Generate a secure random password
484
+ generate_secure_password () {
485
+ # Generate a 16-character password with mixed case, numbers, and special characters
486
+ local password
487
+ password=$( openssl rand -base64 12 | tr -d " =+/" | cut -c1-16)
488
+
489
+ # Ensure it contains at least one uppercase, one lowercase, one number, and one special character
490
+ local upper=$( echo {A..Z} | tr -d ' ' | fold -w1 | sort -R | head -1)
491
+ local lower=$( echo {a..z} | tr -d ' ' | fold -w1 | sort -R | head -1)
492
+ local number=$( echo {0..9} | tr -d ' ' | fold -w1 | sort -R | head -1)
493
+ local special=$( echo " !@#$%^&*" | fold -w1 | sort -R | head -1)
494
+
495
+ # Replace characters at random positions
496
+ local pos1=$(( RANDOM % 16 ))
497
+ local pos2=$(( RANDOM % 16 ))
498
+ local pos3=$(( RANDOM % 16 ))
499
+ local pos4=$(( RANDOM % 16 ))
500
+
501
+ # Ensure all positions are different
502
+ while [ " $pos2 " -eq " $pos1 " ]; do pos2=$(( RANDOM % 16 )) ; done
503
+ while [ " $pos3 " -eq " $pos1 " ] || [ " $pos3 " -eq " $pos2 " ]; do pos3=$(( RANDOM % 16 )) ; done
504
+ while [ " $pos4 " -eq " $pos1 " ] || [ " $pos4 " -eq " $pos2 " ] || [ " $pos4 " -eq " $pos3 " ]; do pos4=$(( RANDOM % 16 )) ; done
505
+
506
+ # Build the final password
507
+ password=$( echo " $password " | sed " s/./$upper /$(( pos1 + 1 )) " | sed " s/./$lower /$(( pos2 + 1 )) " | sed " s/./$number /$(( pos3 + 1 )) " | sed " s/./$special /$(( pos4 + 1 )) " )
508
+
509
+ echo " $password "
510
+ }
511
+
512
+ # Check if Grafana password exists
513
+ check_grafana_password_exists () {
514
+ if [ -f " $SCRIPT_DIR /.pgwatch-config" ]; then
515
+ local password=$( grep " ^grafana_password=" " $SCRIPT_DIR /.pgwatch-config" 2> /dev/null | cut -d' =' -f2)
516
+ if [ -n " $password " ]; then
517
+ return 0 # Password exists
518
+ fi
519
+ fi
520
+ return 1 # Password doesn't exist
521
+ }
522
+
523
+ # Ensure Grafana password exists (generate if needed)
524
+ ensure_grafana_password () {
525
+ if ! check_grafana_password_exists; then
526
+ log_info " No Grafana password configured - generating secure password..."
527
+ generate_grafana_password
528
+ else
529
+ log_info " Grafana password already configured"
530
+ fi
531
+ }
532
+
533
+ # Generate Grafana password and update configuration
534
+ generate_grafana_password () {
535
+ local password
536
+ password=$( generate_secure_password)
537
+
538
+ # Create config file if it doesn't exist
539
+ touch " $SCRIPT_DIR /.pgwatch-config"
540
+
541
+ # Remove existing grafana_password line if present
542
+ if [ -f " $SCRIPT_DIR /.pgwatch-config" ]; then
543
+ grep -v " ^grafana_password=" " $SCRIPT_DIR /.pgwatch-config" > " $SCRIPT_DIR /.pgwatch-config.tmp" || true
544
+ mv " $SCRIPT_DIR /.pgwatch-config.tmp" " $SCRIPT_DIR /.pgwatch-config"
545
+ fi
546
+
547
+ # Add the new Grafana password
548
+ echo " grafana_password=$password " >> " $SCRIPT_DIR /.pgwatch-config"
549
+
550
+ log_success " Grafana password generated successfully"
551
+ log_info " New password: $password "
552
+ log_info " Username: monitor"
553
+ log_info " Access Grafana at: http://localhost:3000"
554
+
555
+ # Change password via existing Grafana container
556
+ change_grafana_password_via_container " $password "
557
+
558
+ return 0
559
+ }
560
+
561
+ # Change Grafana password via existing container
562
+ change_grafana_password_via_container () {
563
+ local password=" 1ドル "
564
+ local compose_cmd=$( get_compose_cmd)
565
+
566
+ cd " $SCRIPT_DIR "
567
+
568
+ # Check if Grafana container is running
569
+ if ! $compose_cmd -f " $COMPOSE_FILE " ps --services --filter " status=running" | grep -q " grafana" ; then
570
+ log_warning " Grafana container is not running. Starting it first..."
571
+ $compose_cmd -f " $COMPOSE_FILE " up -d grafana
572
+
573
+ # Wait for Grafana to be ready
574
+ log_info " Waiting for Grafana to be ready..."
575
+ sleep 10
576
+ fi
577
+
578
+ # Change password using Grafana CLI inside the container
579
+ log_info " Changing Grafana password via container..."
580
+
581
+ # Use grafana-cli to change the admin password
582
+ if $compose_cmd -f " $COMPOSE_FILE " exec -T grafana grafana-cli admin reset-admin-password " $password " > /dev/null 2>&1 ; then
583
+ log_success " Grafana password changed successfully via container"
584
+ else
585
+ log_warning " Failed to change password via grafana-cli, trying alternative method..."
586
+
587
+ # Alternative: Use SQL to update password directly in database
588
+ if $compose_cmd -f " $COMPOSE_FILE " exec -T grafana sqlite3 /var/lib/grafana/grafana.db " UPDATE user SET password = '$password ' WHERE login = 'monitor';" > /dev/null 2>&1 ; then
589
+ log_success " Grafana password changed successfully via database update"
590
+ else
591
+ log_error " Failed to change Grafana password via container"
592
+ log_info " Password has been saved to .pgwatch-config but may need manual update in Grafana"
593
+ return 1
594
+ fi
595
+ fi
596
+
597
+ log_info " Password saved to .pgwatch-config file"
598
+ }
599
+
600
+ # Show current Grafana credentials
601
+ show_grafana_credentials () {
602
+ if [ -f " $SCRIPT_DIR /.pgwatch-config" ]; then
603
+ local password=$( grep " ^grafana_password=" " $SCRIPT_DIR /.pgwatch-config" 2> /dev/null | cut -d' =' -f2)
604
+ if [ -n " $password " ]; then
605
+ log_info " Current Grafana credentials:"
606
+ echo " Username: monitor"
607
+ echo " Password: $password "
608
+ echo " URL: http://localhost:3000"
609
+ else
610
+ log_warning " No custom Grafana password configured"
611
+ log_info " Using default credentials: monitor/demo"
612
+ log_info " Use '0ドル generate-grafana-password' to set a secure password"
613
+ fi
614
+ else
615
+ log_warning " No Grafana password configured"
616
+ log_info " Using default credentials: monitor/demo"
617
+ log_info " Use '0ドル generate-grafana-password' to set a secure password"
618
+ fi
619
+ }
620
+
474
621
# API Key Management Functions
475
622
476
623
# Add API key to configuration
653
800
654
801
if [ " $demo_mode " = true ]; then
655
802
log_info " You can now start all services (including demo database) with: 0ドル start"
656
- log_info " The demo database will be available at: postgresql://postgres:postgres@localhost:5432 /target_database"
803
+ log_info " The demo database will be available at: postgresql://postgres:postgres@localhost:55432 /target_database"
657
804
else
658
805
log_info " You can now:"
659
806
echo " 1. Add PostgreSQL instances to monitor: 0ドル add-instance 'postgresql://user:pass@host:port/db'"
@@ -872,16 +1019,25 @@ quickstart_setup() {
872
1019
fi
873
1020
update_config
874
1021
875
- # Step 5/4: Start services
1022
+ # Step 5/4: Ensure Grafana password is configured
876
1023
echo
877
1024
if [ " $demo_mode " = true ]; then
878
- log_info " Step 4: Starting monitoring services ..."
1025
+ log_info " Step 4: Configuring Grafana security ..."
879
1026
else
1027
+ log_info " Step 5: Configuring Grafana security..."
1028
+ fi
1029
+ ensure_grafana_password
1030
+
1031
+ # Step 6/5: Start services
1032
+ echo
1033
+ if [ " $demo_mode " = true ]; then
880
1034
log_info " Step 5: Starting monitoring services..."
1035
+ else
1036
+ log_info " Step 6: Starting monitoring services..."
881
1037
fi
882
1038
start_services
883
1039
884
- # Step 6/5 : Final summary
1040
+ # Step 7/6 : Final summary
885
1041
echo
886
1042
log_success " 🎉 Quickstart setup completed successfully!"
887
1043
echo
@@ -890,7 +1046,7 @@ quickstart_setup() {
890
1046
echo " ✅ Demo PostgreSQL database (monitoring target)"
891
1047
fi
892
1048
echo " ✅ PostgreSQL monitoring infrastructure"
893
- echo " ✅ Grafana dashboards"
1049
+ echo " ✅ Grafana dashboards (with secure password) "
894
1050
echo " ✅ Prometheus metrics storage"
895
1051
echo " ✅ Flask API backend"
896
1052
echo " ✅ Automated report generation (every 24h)"
@@ -904,7 +1060,7 @@ quickstart_setup() {
904
1060
else
905
1061
log_info " Demo mode next steps:"
906
1062
echo " • Explore Grafana dashboards at http://localhost:3000"
907
- echo " • Connect to demo database: postgresql://postgres:postgres@localhost:5432 /target_database"
1063
+ echo " • Connect to demo database: postgresql://postgres:postgres@localhost:55432 /target_database"
908
1064
echo " • Generate some load on the demo database to see metrics"
909
1065
fi
910
1066
@@ -925,6 +1081,9 @@ get_compose_cmd() {
925
1081
start_services () {
926
1082
precheck_for_services
927
1083
1084
+ # Ensure Grafana password is configured before starting services
1085
+ ensure_grafana_password
1086
+
928
1087
local compose_cmd=$( get_compose_cmd)
929
1088
930
1089
cd " $SCRIPT_DIR "
@@ -1002,17 +1161,17 @@ health_check() {
1002
1161
log_info " Performing health checks..."
1003
1162
1004
1163
local services=(
1005
- " sink-postgres:5433 :PostgreSQL Sink"
1006
- " pgwatch-postgres:8080 :PGWatch PostgreSQL"
1007
- " pgwatch-prometheus:8089 :PGWatch Prometheus"
1008
- " sink-prometheus:9090 :Prometheus"
1164
+ " sink-postgres:55433 :PostgreSQL Sink"
1165
+ " pgwatch-postgres:58080 :PGWatch PostgreSQL"
1166
+ " pgwatch-prometheus:58089 :PGWatch Prometheus"
1167
+ " sink-prometheus:59090 :Prometheus"
1009
1168
" grafana:3000:Grafana"
1010
- " flask-pgss-api:5000 :Flask API"
1169
+ " flask-pgss-api:55000 :Flask API"
1011
1170
)
1012
1171
1013
1172
# Add target-db only in demo mode
1014
1173
if is_demo_mode; then
1015
- services=(" target-db:5432 :PostgreSQL Target Database" " ${services[@]} " )
1174
+ services=(" target-db:55432 :PostgreSQL Target Database" " ${services[@]} " )
1016
1175
fi
1017
1176
1018
1177
local all_healthy=true
@@ -1514,17 +1673,17 @@ open_shell() {
1514
1673
show_access_info () {
1515
1674
echo
1516
1675
log_info " Technical service URLs (for advanced users):"
1517
- echo " PGWatch Postgres: http://localhost:8080 "
1518
- echo " PGWatch Prometheus: http://localhost:8089 "
1519
- echo " Prometheus: http://localhost:9090 "
1520
- echo " Flask API: http://localhost:5000 "
1676
+ echo " PGWatch Postgres: http://localhost:58080 "
1677
+ echo " PGWatch Prometheus: http://localhost:58089 "
1678
+ echo " Prometheus: http://localhost:59090 "
1679
+ echo " Flask API: http://localhost:55000 "
1521
1680
1522
1681
# Show target database only in demo mode
1523
1682
if is_demo_mode; then
1524
- echo " Target Database: postgresql://postgres:postgres@localhost:5432 /target_database"
1683
+ echo " Target Database: postgresql://postgres:postgres@localhost:55432 /target_database"
1525
1684
fi
1526
1685
1527
- echo " Sink Database: postgresql://postgres:postgres@localhost:5433 /postgres"
1686
+ echo " Sink Database: postgresql://postgres:postgres@localhost:55433 /postgres"
1528
1687
echo
1529
1688
1530
1689
# Show reports information
@@ -1549,7 +1708,18 @@ show_access_info() {
1549
1708
echo " ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1550
1709
echo -e " ${GREEN} 🚀 MAIN ACCESS POINT - Start here:${NC} "
1551
1710
echo -e " ${GREEN} Grafana Dashboard: http://localhost:3000${NC} "
1552
- echo -e " ${GREEN} Login: demo / demo${NC} "
1711
+
1712
+ # Show custom credentials if available
1713
+ if [ -f " $SCRIPT_DIR /.pgwatch-config" ]; then
1714
+ local grafana_password=$( grep " ^grafana_password=" " $SCRIPT_DIR /.pgwatch-config" 2> /dev/null | cut -d' =' -f2)
1715
+ if [ -n " $grafana_password " ]; then
1716
+ echo -e " ${GREEN} Login: monitor / $grafana_password ${NC} "
1717
+ else
1718
+ echo -e " ${GREEN} Login: monitor / demo${NC} "
1719
+ fi
1720
+ else
1721
+ echo -e " ${GREEN} Login: monitor / demo${NC} "
1722
+ fi
1553
1723
echo " ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1554
1724
}
1555
1725
@@ -1620,6 +1790,12 @@ main() {
1620
1790
" remove-key" )
1621
1791
remove_api_key
1622
1792
;;
1793
+ " generate-grafana-password" )
1794
+ generate_grafana_password
1795
+ ;;
1796
+ " show-grafana-credentials" )
1797
+ show_grafana_credentials
1798
+ ;;
1623
1799
" help" |" --help" |" -h" )
1624
1800
show_help
1625
1801
;;
0 commit comments