Skip to content

Commit

Permalink
Merge pull request #86 from duplocloud/feature/DUPLO-19210
Browse files Browse the repository at this point in the history
DUPLO-19210: Tenant Start/Stop Commands
  • Loading branch information
kferrone authored Aug 5, 2024
2 parents 0d3c532 + 219667b commit 73f7ca9
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- remove_user_from_tenant command
- Added support for tenant start/stop

### Updates
- changed handling of tenant arg in user resource
Expand Down
16 changes: 16 additions & 0 deletions src/duplo_resource/rds.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ def wait_check():
"message": "DB instance stopped"
}

@Command()
def start(self,
name: args.NAME,
wait: args.WAIT=False):
"""Start a DB instance."""
def wait_check():
i = self.find(name)
if i["InstanceStatus"] in ["starting"]:
raise DuploError(f"DB instance {name} is still starting")
self.duplo.post(self.endpoint(name, "start"))
if wait:
self.wait(wait_check, 1800, 10)
return {
"message": "DB instance started"
}

@Command()
def reboot(self,
name: args.NAME,
Expand Down
120 changes: 120 additions & 0 deletions src/duplo_resource/tenant.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,3 +402,123 @@ def region(self,
return {
"region": response.json()
}

@Command()
def start(self, name: args.NAME = None, wait: args.WAIT=False, exclude: args.EXCLUDE=None):
"""Start Tenant All Resources
Starts all resources of a tenant.
Usage: Basic CLI Use
```bash
duploctl tenant start
```
Args:
wait: Wait for the resources to start.
exclude (optional): A list of resources to exclude from starting. Can include:
- hosts/<host_name>: Exclude a specific host.
- rds/<rds_name>: Exclude a specific RDS instance.
- hosts/at/<allocation_tags>: Exclude hosts with specific allocation tags.
Returns:
message: A success message.
"""
service_types = {"hosts": [], "rds": []}
host_at = []
if exclude:
for item in exclude:
category, value = item.split('/', 1)
if 'at/' in value:
_, at_name = value.split('at/', 1)
host_at.append(at_name)
elif category in {"hosts", "rds"}:
tenant_name = self.find(name)['AccountName']
if category == "hosts":
prefix = f"duploservices-{tenant_name}"
value = f"{prefix}-{value}" if not value.startswith(prefix) else value
elif category == "rds":
value = f"duplo{value}" if not value.startswith("duplo") else value
service_types[category].append(value)
else:
print(f"Unknown service: {category}")

host_at_exclude = self.get_hosts_to_exclude(host_at)
service_types['hosts'] = list(set(service_types['hosts']) | set(host_at_exclude))

for service_type in service_types.keys():
service = self.duplo.load(service_type)
for item in service.list():
service_name = service.name_from_body(item)
if service_name not in service_types[service_type]:
service.start(service_name, wait)
return {
"message": "Successfully started all resources for tenant"
}

@Command()
def stop(self, name: args.NAME = None, wait: args.WAIT=False, exclude: args.EXCLUDE=None):
"""Stop Tenant All Resources
Stops all resources of a tenant.
Usage: Basic CLI Use
```bash
duploctl tenant stop
```
Args:
wait: Wait for the resources to stop.
exclude (optional): A list of resources to exclude from stopping. Can include:
- hosts/<host_name>: Exclude a specific host.
- rds/<rds_name>: Exclude a specific RDS instance.
- hosts/at/<allocation_tags>: Exclude hosts with specific allocation tags.
Returns:
message: A success message.
"""
service_types = {"hosts": [], "rds": []}
host_at = []
if exclude:
for item in exclude:
category, value = item.split('/', 1)
if 'at/' in value:
_, at_name = value.split('at/', 1)
host_at.append(at_name)
elif category in {"hosts", "rds"}:
tenant_name = self.find(name)['AccountName']
if category == "hosts":
prefix = f"duploservices-{tenant_name}"
value = f"{prefix}-{value}" if not value.startswith(prefix) else value
elif category == "rds":
value = f"duplo{value}" if not value.startswith("duplo") else value
service_types[category].append(value)
else:
print(f"Unknown service: {category}")

host_at_exclude = self.get_hosts_to_exclude(host_at)
service_types['hosts'] = list(set(service_types['hosts']) | set(host_at_exclude))

for service_type in service_types.keys():
service = self.duplo.load(service_type)
for item in service.list():
service_name = service.name_from_body(item)
if service_name not in service_types[service_type]:
service.stop(service_name, wait)
return {
"message": "Successfully stopped all resources for tenant"
}

def get_hosts_to_exclude(self, host_at):
host_at_exclude = []
hosts = self.duplo.load('hosts').list()
for host in hosts:
allocation_tags_value = ''
minion_tags = host.get('MinionTags', [])
for tag in minion_tags:
if tag.get('Key') == 'AllocationTags':
allocation_tags_value = tag.get('Value')

if allocation_tags_value in host_at:
host_at_exclude.append(host['FriendlyName'])
return host_at_exclude
4 changes: 4 additions & 0 deletions src/duplocloud/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@
version=f"%(prog)s {VERSION}",
type=bool)

EXCLUDE = Arg("exclude", '--exclude',
action='append',
help='Exclude from the command')

# The rest are resource level args for commands
SERVICE = Arg('service',
help='The service to run',
Expand Down

0 comments on commit 73f7ca9

Please sign in to comment.