Skip to content

Instantly share code, notes, and snippets.

@decklord
Last active October 9, 2019 10:47
Show Gist options
  • Save decklord/0224fb885ca7222940de9e970e00c675 to your computer and use it in GitHub Desktop.
Save decklord/0224fb885ca7222940de9e970e00c675 to your computer and use it in GitHub Desktop.
This gist shows how to calculate the diff in seconds between host UTC time and Google Cloud remote machine creation UTC time and use it to wait_for SSH only if the machine is new to avoid being blocked by SSH Guard
#!/usr/bin/python
import datetime
class FilterModule(object):
def filters(self):
return {
'rfc3339_to_utc': self.rfc3339_to_utc
}
def rfc3339_to_utc(self, rfc3339_date):
# Test
# f = FilterModule()
# assert str(f.rfc3339_to_utc("2019-10-08T16:39:57.097+07:00")) == "2019-10-08 09:39:57"
# assert str(f.rfc3339_to_utc("2019-10-08T16:39:57.097-07:00")) == "2019-10-08 23:39:57"
date, time = rfc3339_date.split("T")
op = "-"
if "+" in time:
op = "+"
time, offset = time.split(op)
offset_hour = op + offset.split(":")[0]
dt = "T".join([date, time])[:19]
dt = datetime.datetime.strptime(dt, "%Y-%m-%dT%H:%M:%S")
dt -= datetime.timedelta(hours=int(offset_hour))
return dt
# ################################################
# start seconds_since_instance_creation
#
# This fact is important to avoid random SHH Time Out!
# wait_for SSH if done too many times will block host IP (ie, experimenting on playbook)
# because it will think that it's an SSH attack, given that this call to SSH doesn't provide credentials.
# This param will be used to run wait_for just if the instance was created recently. If not,
# we will asume SSH is already running and skip
- name: host_dt_now_utc
set_fact:
# -u param in date returns UTC datetime on host. Then parsed to dt with no timezone info.
host_dt_now_utc: "{{ ( lookup('pipe','date -u +%Y-%m-%dT%H:%M:%S') | to_datetime('%Y-%m-%dT%H:%M:%S') ) }}"
- name: gcp_rfc3339_to_utc
set_fact:
# GCP machines return their timestamps in rfc3339 format containing timezone info.
# This custom filter will return a python datetime in UTC with no tz info.
gcp_rfc3339_to_utc: "{{ instance.creationTimestamp | rfc3339_to_utc }}"
- name: seconds_since_instance_creation
set_fact:
seconds_since_instance_creation: "{{ ( host_dt_now_utc | to_datetime - gcp_rfc3339_to_utc | to_datetime ).total_seconds() }}"
# end seconds_since_instance_creation
# ################################################
- name: Wait for SSH to come up
wait_for:
host: "{{ instance.networkInterfaces[0].accessConfigs[0].natIP }}"
port: 22
delay: 5
sleep: 5
timeout: 100
state: started
when: "seconds_since_instance_creation|int < 240"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment