ez-ip-updater


Nameez-ip-updater JSON
Version 2.0.0 PyPI version JSON
download
home_pageNone
SummaryTự động phát hiện IP công cộng và cập nhật vào Google Cloud / AWS
upload_time2025-10-08 10:23:22
maintainerNone
docs_urlNone
authorLe Quyet Tien
requires_python>=3.7
licenseMIT License Copyright (c) 2025 Tien Le Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords gcp aws ip firewall security-groups
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # IP Updater v2.0 - Tự Động Cập Nhật IP Công Cộng

[![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

IP Updater là script tự động phát hiện thay đổi IP công cộng và cập nhật vào:

- **Google Cloud Platform**: Firewall Rules, Cloud SQL Authorized Networks
- **Amazon Web Services**: Security Groups (SSH, MySQL, custom ports)

---

## 🚀 Tính Năng Mới v2.0

- **Kiến trúc OOP**: Tách lớp rõ ràng, dễ mở rộng
- **CLI Arguments**: Hỗ trợ `--dry-run`, `--force`, `--verbose`
- **Xử lý lỗi chi tiết**
- **Logging nâng cao**: Console & file, nhiều cấp độ
- **Không lặp code**: Tuân thủ nguyên tắc DRY
- **Test coverage >85%**
- **Cài đặt phụ thuộc linh hoạt**: Chỉ cần SDK bạn sử dụng

---

## 📋 Yêu Cầu

- Python 3.7+
- Phụ thuộc (tùy provider):
  - GCP: `google-cloud-compute`, `google-api-python-client`
  - AWS: `boto3`
  - Chung: `requests`

---

## ⚡ Cài Đặt Nhanh

### 1. Clone & Cài Dependencies

```bash
git clone https://github.com/lequyettien/ip-updater.git
cd ip-updater
python3 -m pip install -r requirements.txt
```

### 2. Tạo & Chỉnh Sửa File Cấu Hình

```bash
cp config.json.example config.json
# Sửa config.json theo thông tin của bạn
```

### 3. Cấu Hình Credentials

#### Google Cloud Platform

```bash
# Cách 1: Biến môi trường (khuyến nghị)
export GOOGLE_APPLICATION_CREDENTIALS="$PWD/gcp-credentials.json"

# Cách 2: Gcloud ADC
gcloud auth application-default login
```

#### Amazon Web Services

```bash
# Cách 1: AWS CLI
aws configure

# Cách 2: Biến môi trường
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
```

### 4. Chạy Script

```bash
python3 auto_update_ip.py                # Chạy bình thường
python3 auto_update_ip.py --dry-run      # Chạy thử, không thay đổi thật
python3 auto_update_ip.py --force        # Buộc cập nhật kể cả IP không đổi
python3 auto_update_ip.py --verbose      # Hiển thị log chi tiết
```

---

## 🛠️ Sử Dụng

### CLI Options

```bash
usage: auto_update_ip.py [-h] [-c CONFIG] [--dry-run] [--force] [-v] [--version]

options:
  -h, --help            Hiển thị help
  -c, --config CONFIG   Đường dẫn file cấu hình (default: config.json)
  --dry-run             Chạy thử, không thực hiện thay đổi thực tế
  --force               Buộc cập nhật kể cả khi IP không thay đổi
  -v, --verbose         Hiển thị log chi tiết (DEBUG level)
  --version             Hiển thị version
```

**Ví dụ:**

```bash
python3 auto_update_ip.py                          # Chạy với config mặc định
python3 auto_update_ip.py --config prod.json       # Dùng config file khác
python3 auto_update_ip.py --dry-run                # Chạy thử
python3 auto_update_ip.py --force                  # Buộc cập nhật
python3 auto_update_ip.py --verbose                # Log chi tiết
```

---

### Cấu Trúc config.json

```json
{
  "gcp": {
    "project_id": "your-gcp-project",
    "credentials_file": "gcp-credentials.json",
    "firewall_rules": ["allow-office-ssh", "allow-office-https"],
    "sql_instances": ["production-mysql", "staging-postgres"]
  },
  "aws": {
    "region": "ap-southeast-1",
    "security_groups_ssh": [
      {
        "group_id": "sg-xxxxxxxxx",
        "description": "Office SSH Access"
      }
    ],
    "security_groups_mysql": [
      {
        "group_id": "sg-yyyyyyyyy",
        "description": "Office MySQL Access"
      }
    ],
    "ports_ssh": [
      {"protocol": "tcp", "port": 22, "description": "SSH"}
    ],
    "ports_mysql": [
      {"protocol": "tcp", "port": 3306, "description": "MySQL"}
    ]
  },
  "ip_cache_file": "last_known_ip.txt"
}
```

---

## ⏰ Chạy Định Kỳ

### Cron

Chạy mỗi 5 phút:

```cron
*/5 * * * * cd /path/to/ip-updater && /usr/bin/python3 auto_update_ip.py >> /var/log/ip_update.log 2>&1
```

Chạy mỗi giờ:

```cron
0 * * * * cd /path/to/ip-updater && /usr/bin/python3 auto_update_ip.py
```

### Systemd Timer (Linux)

Tạo service file `/etc/systemd/system/ip-updater.service`:

```ini
[Unit]
Description=IP Updater Service
After=network-online.target

[Service]
Type=oneshot
WorkingDirectory=/path/to/ip-updater
ExecStart=/usr/bin/python3 /path/to/ip-updater/auto_update_ip.py
User=your-user
Environment="GOOGLE_APPLICATION_CREDENTIALS=/path/to/gcp-credentials.json"

[Install]
WantedBy=multi-user.target
```

Tạo timer file `/etc/systemd/system/ip-updater.timer`:

```ini
[Unit]
Description=IP Updater Timer
Requires=ip-updater.service

[Timer]
OnBootSec=5min
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target
```

Kích hoạt timer:

```bash
sudo systemctl daemon-reload
sudo systemctl enable ip-updater.timer
sudo systemctl start ip-updater.timer
sudo systemctl status ip-updater.timer
```

---

## 🧪 Testing

### Chạy tests

```bash
python3 -m pip install pytest pytest-cov
pytest -v
pytest --cov=auto_update_ip --cov-report=html
```

**Coverage hiện tại:** >85%

- IP detection & caching
- Load & validate config
- Update GCP Firewall & Cloud SQL
- Update AWS Security Groups
- Error handling
- Dry-run mode

---

## 📂 Cấu Trúc Thư Mục

```
ip-updater/
├── auto_update_ip.py          # Main script (v2.0)
├── config.json                # Config cá nhân (gitignored)
├── config.json.example        # Mẫu config
├── gcp-credentials.json       # GCP credentials (gitignored)
├── requirements.txt           # Python dependencies
├── pytest.ini                 # Pytest config
├── .gitignore                 # Git ignore rules
├── README.md                  # Tài liệu này
├── CHANGELOG.md               # Lịch sử phiên bản
├── LICENSE                    # MIT License
├── tests/
│   ├── conftest.py
│   └── test_auto_update_ip.py
└── ip_update.log              # Log file (tự động tạo)
```

---

## 🔐 Security Best Practices

### Credentials

- Không commit credentials vào git
- Dùng `.gitignore` để loại trừ file nhạy cảm
- Sử dụng environment variables khi có thể
- Set quyền file: `chmod 600 gcp-credentials.json`

### IAM Permissions

#### GCP

- Roles: `roles/compute.securityAdmin`, `roles/cloudsql.admin`
- Hoặc custom role:

```yaml
compute.firewalls.get
compute.firewalls.update
cloudsql.instances.get
cloudsql.instances.update
```

#### AWS

IAM policy tối thiểu:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:AuthorizeSecurityGroupIngress",
        "ec2:RevokeSecurityGroupIngress",
        "ec2:DescribeSecurityGroups"
      ],
      "Resource": "*"
    }
  ]
}
```

### Network Security

- Chỉ mở port cần thiết
- Sử dụng CIDR `/32` cho IP đơn
- Kiểm tra log thường xuyên
- Thiết lập cảnh báo khi có thay đổi

---

## 🐛 Troubleshooting

### Lỗi cấu hình

```bash
cp config.json.example config.json
# Sửa lại config.json
```

### Lỗi GCP credentials

```bash
ls -la gcp-credentials.json
export GOOGLE_APPLICATION_CREDENTIALS="$PWD/gcp-credentials.json"
gcloud auth application-default login
```

### Lỗi AWS credentials

```bash
aws configure
cat ~/.aws/credentials
aws sts get-caller-identity
```

### Không phát hiện thay đổi IP

```bash
rm last_known_ip.txt
python3 auto_update_ip.py --force --verbose
```

### Test dry-run

```bash
python3 auto_update_ip.py --dry-run --verbose
```

### Kiểm tra logs

```bash
tail -f ip_update.log
tail -f ip_update.log | grep "ERROR\|WARNING"
```

---

## 📝 Changelog

### v2.0.0 (2025-10-08)

- Refactor OOP
- Thêm CLI arguments
- Logging & error handling nâng cao
- Loại bỏ lặp code
- Optional dependencies
- Test suite đầy đủ
- Cập nhật tài liệu

### v1.0.0

- Ra mắt ban đầu
- Update IP cho GCP Firewall, Cloud SQL, AWS Security Groups

---

## 🤝 Đóng Góp

Chào mừng mọi đóng góp!

1. Fork repo
2. Tạo branch mới (`git checkout -b feature/AmazingFeature`)
3. Commit thay đổi (`git commit -m 'Add AmazingFeature'`)
4. Push lên branch (`git push origin feature/AmazingFeature`)
5. Mở Pull Request

---

## 📄 License

Dự án theo MIT License - xem [LICENSE](LICENSE) để biết chi tiết.

---

## 👥 Tác Giả

- **Le Quyet Tien**

---

## 🙏 Cảm Ơn

- Google Cloud Python SDK
- AWS Boto3
- Python Requests library
- Các contributor

---

## 📞 Hỗ Trợ

- 📧 Email: [lequyettien.it@gmail.com](mailto:lequyettien.it@gmail.com)
- 🐛 Issues: [GitHub Issues](https://github.com/lequyettien/ip-updater/issues)
- 📖 Docs: [Wiki](https://github.com/lequyettien/ip-updater/wiki)

---

Made with ❤️ by Le Quyet Tien

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "ez-ip-updater",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "gcp, aws, ip, firewall, security-groups",
    "author": "Le Quyet Tien",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/f4/89/759134ab1532795804d96d2aa933656f8b2d838866c8c9fc067a6edf2c42/ez_ip_updater-2.0.0.tar.gz",
    "platform": null,
    "description": "# IP Updater v2.0 - T\u1ef1 \u0110\u1ed9ng C\u1eadp Nh\u1eadt IP C\u00f4ng C\u1ed9ng\n\n[![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\nIP Updater l\u00e0 script t\u1ef1 \u0111\u1ed9ng ph\u00e1t hi\u1ec7n thay \u0111\u1ed5i IP c\u00f4ng c\u1ed9ng v\u00e0 c\u1eadp nh\u1eadt v\u00e0o:\n\n- **Google Cloud Platform**: Firewall Rules, Cloud SQL Authorized Networks\n- **Amazon Web Services**: Security Groups (SSH, MySQL, custom ports)\n\n---\n\n## \ud83d\ude80 T\u00ednh N\u0103ng M\u1edbi v2.0\n\n- **Ki\u1ebfn tr\u00fac OOP**: T\u00e1ch l\u1edbp r\u00f5 r\u00e0ng, d\u1ec5 m\u1edf r\u1ed9ng\n- **CLI Arguments**: H\u1ed7 tr\u1ee3 `--dry-run`, `--force`, `--verbose`\n- **X\u1eed l\u00fd l\u1ed7i chi ti\u1ebft**\n- **Logging n\u00e2ng cao**: Console & file, nhi\u1ec1u c\u1ea5p \u0111\u1ed9\n- **Kh\u00f4ng l\u1eb7p code**: Tu\u00e2n th\u1ee7 nguy\u00ean t\u1eafc DRY\n- **Test coverage >85%**\n- **C\u00e0i \u0111\u1eb7t ph\u1ee5 thu\u1ed9c linh ho\u1ea1t**: Ch\u1ec9 c\u1ea7n SDK b\u1ea1n s\u1eed d\u1ee5ng\n\n---\n\n## \ud83d\udccb Y\u00eau C\u1ea7u\n\n- Python 3.7+\n- Ph\u1ee5 thu\u1ed9c (t\u00f9y provider):\n  - GCP: `google-cloud-compute`, `google-api-python-client`\n  - AWS: `boto3`\n  - Chung: `requests`\n\n---\n\n## \u26a1 C\u00e0i \u0110\u1eb7t Nhanh\n\n### 1. Clone & C\u00e0i Dependencies\n\n```bash\ngit clone https://github.com/lequyettien/ip-updater.git\ncd ip-updater\npython3 -m pip install -r requirements.txt\n```\n\n### 2. T\u1ea1o & Ch\u1ec9nh S\u1eeda File C\u1ea5u H\u00ecnh\n\n```bash\ncp config.json.example config.json\n# S\u1eeda config.json theo th\u00f4ng tin c\u1ee7a b\u1ea1n\n```\n\n### 3. C\u1ea5u H\u00ecnh Credentials\n\n#### Google Cloud Platform\n\n```bash\n# C\u00e1ch 1: Bi\u1ebfn m\u00f4i tr\u01b0\u1eddng (khuy\u1ebfn ngh\u1ecb)\nexport GOOGLE_APPLICATION_CREDENTIALS=\"$PWD/gcp-credentials.json\"\n\n# C\u00e1ch 2: Gcloud ADC\ngcloud auth application-default login\n```\n\n#### Amazon Web Services\n\n```bash\n# C\u00e1ch 1: AWS CLI\naws configure\n\n# C\u00e1ch 2: Bi\u1ebfn m\u00f4i tr\u01b0\u1eddng\nexport AWS_ACCESS_KEY_ID=\"your-key\"\nexport AWS_SECRET_ACCESS_KEY=\"your-secret\"\n```\n\n### 4. Ch\u1ea1y Script\n\n```bash\npython3 auto_update_ip.py                # Ch\u1ea1y b\u00ecnh th\u01b0\u1eddng\npython3 auto_update_ip.py --dry-run      # Ch\u1ea1y th\u1eed, kh\u00f4ng thay \u0111\u1ed5i th\u1eadt\npython3 auto_update_ip.py --force        # Bu\u1ed9c c\u1eadp nh\u1eadt k\u1ec3 c\u1ea3 IP kh\u00f4ng \u0111\u1ed5i\npython3 auto_update_ip.py --verbose      # Hi\u1ec3n th\u1ecb log chi ti\u1ebft\n```\n\n---\n\n## \ud83d\udee0\ufe0f S\u1eed D\u1ee5ng\n\n### CLI Options\n\n```bash\nusage: auto_update_ip.py [-h] [-c CONFIG] [--dry-run] [--force] [-v] [--version]\n\noptions:\n  -h, --help            Hi\u1ec3n th\u1ecb help\n  -c, --config CONFIG   \u0110\u01b0\u1eddng d\u1eabn file c\u1ea5u h\u00ecnh (default: config.json)\n  --dry-run             Ch\u1ea1y th\u1eed, kh\u00f4ng th\u1ef1c hi\u1ec7n thay \u0111\u1ed5i th\u1ef1c t\u1ebf\n  --force               Bu\u1ed9c c\u1eadp nh\u1eadt k\u1ec3 c\u1ea3 khi IP kh\u00f4ng thay \u0111\u1ed5i\n  -v, --verbose         Hi\u1ec3n th\u1ecb log chi ti\u1ebft (DEBUG level)\n  --version             Hi\u1ec3n th\u1ecb version\n```\n\n**V\u00ed d\u1ee5:**\n\n```bash\npython3 auto_update_ip.py                          # Ch\u1ea1y v\u1edbi config m\u1eb7c \u0111\u1ecbnh\npython3 auto_update_ip.py --config prod.json       # D\u00f9ng config file kh\u00e1c\npython3 auto_update_ip.py --dry-run                # Ch\u1ea1y th\u1eed\npython3 auto_update_ip.py --force                  # Bu\u1ed9c c\u1eadp nh\u1eadt\npython3 auto_update_ip.py --verbose                # Log chi ti\u1ebft\n```\n\n---\n\n### C\u1ea5u Tr\u00fac config.json\n\n```json\n{\n  \"gcp\": {\n    \"project_id\": \"your-gcp-project\",\n    \"credentials_file\": \"gcp-credentials.json\",\n    \"firewall_rules\": [\"allow-office-ssh\", \"allow-office-https\"],\n    \"sql_instances\": [\"production-mysql\", \"staging-postgres\"]\n  },\n  \"aws\": {\n    \"region\": \"ap-southeast-1\",\n    \"security_groups_ssh\": [\n      {\n        \"group_id\": \"sg-xxxxxxxxx\",\n        \"description\": \"Office SSH Access\"\n      }\n    ],\n    \"security_groups_mysql\": [\n      {\n        \"group_id\": \"sg-yyyyyyyyy\",\n        \"description\": \"Office MySQL Access\"\n      }\n    ],\n    \"ports_ssh\": [\n      {\"protocol\": \"tcp\", \"port\": 22, \"description\": \"SSH\"}\n    ],\n    \"ports_mysql\": [\n      {\"protocol\": \"tcp\", \"port\": 3306, \"description\": \"MySQL\"}\n    ]\n  },\n  \"ip_cache_file\": \"last_known_ip.txt\"\n}\n```\n\n---\n\n## \u23f0 Ch\u1ea1y \u0110\u1ecbnh K\u1ef3\n\n### Cron\n\nCh\u1ea1y m\u1ed7i 5 ph\u00fat:\n\n```cron\n*/5 * * * * cd /path/to/ip-updater && /usr/bin/python3 auto_update_ip.py >> /var/log/ip_update.log 2>&1\n```\n\nCh\u1ea1y m\u1ed7i gi\u1edd:\n\n```cron\n0 * * * * cd /path/to/ip-updater && /usr/bin/python3 auto_update_ip.py\n```\n\n### Systemd Timer (Linux)\n\nT\u1ea1o service file `/etc/systemd/system/ip-updater.service`:\n\n```ini\n[Unit]\nDescription=IP Updater Service\nAfter=network-online.target\n\n[Service]\nType=oneshot\nWorkingDirectory=/path/to/ip-updater\nExecStart=/usr/bin/python3 /path/to/ip-updater/auto_update_ip.py\nUser=your-user\nEnvironment=\"GOOGLE_APPLICATION_CREDENTIALS=/path/to/gcp-credentials.json\"\n\n[Install]\nWantedBy=multi-user.target\n```\n\nT\u1ea1o timer file `/etc/systemd/system/ip-updater.timer`:\n\n```ini\n[Unit]\nDescription=IP Updater Timer\nRequires=ip-updater.service\n\n[Timer]\nOnBootSec=5min\nOnUnitActiveSec=5min\n\n[Install]\nWantedBy=timers.target\n```\n\nK\u00edch ho\u1ea1t timer:\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable ip-updater.timer\nsudo systemctl start ip-updater.timer\nsudo systemctl status ip-updater.timer\n```\n\n---\n\n## \ud83e\uddea Testing\n\n### Ch\u1ea1y tests\n\n```bash\npython3 -m pip install pytest pytest-cov\npytest -v\npytest --cov=auto_update_ip --cov-report=html\n```\n\n**Coverage hi\u1ec7n t\u1ea1i:** >85%\n\n- IP detection & caching\n- Load & validate config\n- Update GCP Firewall & Cloud SQL\n- Update AWS Security Groups\n- Error handling\n- Dry-run mode\n\n---\n\n## \ud83d\udcc2 C\u1ea5u Tr\u00fac Th\u01b0 M\u1ee5c\n\n```\nip-updater/\n\u251c\u2500\u2500 auto_update_ip.py          # Main script (v2.0)\n\u251c\u2500\u2500 config.json                # Config c\u00e1 nh\u00e2n (gitignored)\n\u251c\u2500\u2500 config.json.example        # M\u1eabu config\n\u251c\u2500\u2500 gcp-credentials.json       # GCP credentials (gitignored)\n\u251c\u2500\u2500 requirements.txt           # Python dependencies\n\u251c\u2500\u2500 pytest.ini                 # Pytest config\n\u251c\u2500\u2500 .gitignore                 # Git ignore rules\n\u251c\u2500\u2500 README.md                  # T\u00e0i li\u1ec7u n\u00e0y\n\u251c\u2500\u2500 CHANGELOG.md               # L\u1ecbch s\u1eed phi\u00ean b\u1ea3n\n\u251c\u2500\u2500 LICENSE                    # MIT License\n\u251c\u2500\u2500 tests/\n\u2502   \u251c\u2500\u2500 conftest.py\n\u2502   \u2514\u2500\u2500 test_auto_update_ip.py\n\u2514\u2500\u2500 ip_update.log              # Log file (t\u1ef1 \u0111\u1ed9ng t\u1ea1o)\n```\n\n---\n\n## \ud83d\udd10 Security Best Practices\n\n### Credentials\n\n- Kh\u00f4ng commit credentials v\u00e0o git\n- D\u00f9ng `.gitignore` \u0111\u1ec3 lo\u1ea1i tr\u1eeb file nh\u1ea1y c\u1ea3m\n- S\u1eed d\u1ee5ng environment variables khi c\u00f3 th\u1ec3\n- Set quy\u1ec1n file: `chmod 600 gcp-credentials.json`\n\n### IAM Permissions\n\n#### GCP\n\n- Roles: `roles/compute.securityAdmin`, `roles/cloudsql.admin`\n- Ho\u1eb7c custom role:\n\n```yaml\ncompute.firewalls.get\ncompute.firewalls.update\ncloudsql.instances.get\ncloudsql.instances.update\n```\n\n#### AWS\n\nIAM policy t\u1ed1i thi\u1ec3u:\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"ec2:AuthorizeSecurityGroupIngress\",\n        \"ec2:RevokeSecurityGroupIngress\",\n        \"ec2:DescribeSecurityGroups\"\n      ],\n      \"Resource\": \"*\"\n    }\n  ]\n}\n```\n\n### Network Security\n\n- Ch\u1ec9 m\u1edf port c\u1ea7n thi\u1ebft\n- S\u1eed d\u1ee5ng CIDR `/32` cho IP \u0111\u01a1n\n- Ki\u1ec3m tra log th\u01b0\u1eddng xuy\u00ean\n- Thi\u1ebft l\u1eadp c\u1ea3nh b\u00e1o khi c\u00f3 thay \u0111\u1ed5i\n\n---\n\n## \ud83d\udc1b Troubleshooting\n\n### L\u1ed7i c\u1ea5u h\u00ecnh\n\n```bash\ncp config.json.example config.json\n# S\u1eeda l\u1ea1i config.json\n```\n\n### L\u1ed7i GCP credentials\n\n```bash\nls -la gcp-credentials.json\nexport GOOGLE_APPLICATION_CREDENTIALS=\"$PWD/gcp-credentials.json\"\ngcloud auth application-default login\n```\n\n### L\u1ed7i AWS credentials\n\n```bash\naws configure\ncat ~/.aws/credentials\naws sts get-caller-identity\n```\n\n### Kh\u00f4ng ph\u00e1t hi\u1ec7n thay \u0111\u1ed5i IP\n\n```bash\nrm last_known_ip.txt\npython3 auto_update_ip.py --force --verbose\n```\n\n### Test dry-run\n\n```bash\npython3 auto_update_ip.py --dry-run --verbose\n```\n\n### Ki\u1ec3m tra logs\n\n```bash\ntail -f ip_update.log\ntail -f ip_update.log | grep \"ERROR\\|WARNING\"\n```\n\n---\n\n## \ud83d\udcdd Changelog\n\n### v2.0.0 (2025-10-08)\n\n- Refactor OOP\n- Th\u00eam CLI arguments\n- Logging & error handling n\u00e2ng cao\n- Lo\u1ea1i b\u1ecf l\u1eb7p code\n- Optional dependencies\n- Test suite \u0111\u1ea7y \u0111\u1ee7\n- C\u1eadp nh\u1eadt t\u00e0i li\u1ec7u\n\n### v1.0.0\n\n- Ra m\u1eaft ban \u0111\u1ea7u\n- Update IP cho GCP Firewall, Cloud SQL, AWS Security Groups\n\n---\n\n## \ud83e\udd1d \u0110\u00f3ng G\u00f3p\n\nCh\u00e0o m\u1eebng m\u1ecdi \u0111\u00f3ng g\u00f3p!\n\n1. Fork repo\n2. T\u1ea1o branch m\u1edbi (`git checkout -b feature/AmazingFeature`)\n3. Commit thay \u0111\u1ed5i (`git commit -m 'Add AmazingFeature'`)\n4. Push l\u00ean branch (`git push origin feature/AmazingFeature`)\n5. M\u1edf Pull Request\n\n---\n\n## \ud83d\udcc4 License\n\nD\u1ef1 \u00e1n theo MIT License - xem [LICENSE](LICENSE) \u0111\u1ec3 bi\u1ebft chi ti\u1ebft.\n\n---\n\n## \ud83d\udc65 T\u00e1c Gi\u1ea3\n\n- **Le Quyet Tien**\n\n---\n\n## \ud83d\ude4f C\u1ea3m \u01a0n\n\n- Google Cloud Python SDK\n- AWS Boto3\n- Python Requests library\n- C\u00e1c contributor\n\n---\n\n## \ud83d\udcde H\u1ed7 Tr\u1ee3\n\n- \ud83d\udce7 Email: [lequyettien.it@gmail.com](mailto:lequyettien.it@gmail.com)\n- \ud83d\udc1b Issues: [GitHub Issues](https://github.com/lequyettien/ip-updater/issues)\n- \ud83d\udcd6 Docs: [Wiki](https://github.com/lequyettien/ip-updater/wiki)\n\n---\n\nMade with \u2764\ufe0f by Le Quyet Tien\n",
    "bugtrack_url": null,
    "license": "MIT License\n        \n        Copyright (c) 2025 Tien Le\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE.",
    "summary": "T\u1ef1 \u0111\u1ed9ng ph\u00e1t hi\u1ec7n IP c\u00f4ng c\u1ed9ng v\u00e0 c\u1eadp nh\u1eadt v\u00e0o Google Cloud / AWS",
    "version": "2.0.0",
    "project_urls": null,
    "split_keywords": [
        "gcp",
        " aws",
        " ip",
        " firewall",
        " security-groups"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "da24e4e01fb4e68aaaaf4dd5ca012954dc5220ff57dd3dedacd2c76de6840a79",
                "md5": "c0b4956195adac745443a9a321158584",
                "sha256": "5f1cdc58ec594f82b71ac7131b3c14a4a4e1fecce4575f4d3aa993106b006cdc"
            },
            "downloads": -1,
            "filename": "ez_ip_updater-2.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c0b4956195adac745443a9a321158584",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 12314,
            "upload_time": "2025-10-08T10:23:20",
            "upload_time_iso_8601": "2025-10-08T10:23:20.946958Z",
            "url": "https://files.pythonhosted.org/packages/da/24/e4e01fb4e68aaaaf4dd5ca012954dc5220ff57dd3dedacd2c76de6840a79/ez_ip_updater-2.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f489759134ab1532795804d96d2aa933656f8b2d838866c8c9fc067a6edf2c42",
                "md5": "0f5f6bf4580a592c3eb170dccda2a4e2",
                "sha256": "ff01cefc7243908cddff20cc2ef1f5ff6a6f02bb42b942a04814d0e3357361f6"
            },
            "downloads": -1,
            "filename": "ez_ip_updater-2.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "0f5f6bf4580a592c3eb170dccda2a4e2",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 24453,
            "upload_time": "2025-10-08T10:23:22",
            "upload_time_iso_8601": "2025-10-08T10:23:22.656710Z",
            "url": "https://files.pythonhosted.org/packages/f4/89/759134ab1532795804d96d2aa933656f8b2d838866c8c9fc067a6edf2c42/ez_ip_updater-2.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-08 10:23:22",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "ez-ip-updater"
}
        
Elapsed time: 2.36388s