Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions actions/auto_remediate_satellite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: auto_remediate_satellite
runner_type: orquesta
description: "Remediate satellite hosts"
enabled: true
entry_point: workflows/auto_remediate_satellite.yaml
name: auto_remediate_satellite
pack: foreman
parameters:
server_name:
type: string
description: "Server name of host"
required: true
username:
type: string
description: "Username"
required: true
default: "{{ st2kv.system.linux.username }}"
password:
type: string
description: "Password"
required: true
secret: true
default: "{{ st2kv.system.linux.password | decrypt_kv }}"
89 changes: 89 additions & 0 deletions actions/workflows/auto_remediate_satellite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
version: 1.0

description: Remediate Satellite hosts that haven't checked in

input:
- server_name
- username
- password

output:
- username: <% ctx().username %>
- password: <% ctx().password %>
- server_name: <% ctx().server_name %>

tasks:

task1:
action: core.echo
input:
message: <% ctx().server_name %>
next:
- when: <% succeeded() %>
publish: <% result().stdout() %>
do:
- task2
task2:
action: core.remote
input:
hosts: <% ctx().server_name %>
username: <% ctx().username %>
password: <% ctx().password %>
cmd: subscription-manager status
next:
- when: <% succeeded() %>
publish: <% result() %>
do:
- task3
task3:
action: core.remote
input:
hosts: <% ctx().server_name %>
username: <% ctx().username %>
password: <% ctx().password %>
cmd: subscription-manager identity
next:
- when: <% succeeded() %>
publish: <% result() %>
do:
- task4

task4:
action: core.remote
input:
hosts: <% ctx().server_name %>
username: <% ctx().username %>
password: <% ctx().password %>
cmd: subscription-manager unregister
next:
- when: <% succeeded() %>
publish: <% result() %>
do:
- task5

task5:
action: core.remote
input:
hosts: <% ctx().server_name %>
username: <% ctx().username %>
password: <% ctx().password %>
cmd: subscription-manager register --org="EMS" --activationkey="RHEL_7"
next:
- when: <% succeeded() %>
publish: <% result() %>
do:
- task6

task6:
action: core.remote
input:
hosts: <% ctx().server_name %>
username: <% ctx().username %>
password: <% ctx().password %>
cmd: subscription-manager list --consumed
next:
- when: <% succeeded() %>
publish: <% result() %>
do:
- noop
13 changes: 11 additions & 2 deletions config.schema.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
foreman:
type: "object"
type: object
required: true
patternProperties:
"^\\w+":
"$ref": "#/properties/connections"
additionalProperties: false

connections:
type: "object"
type: object
properties:
server:
type: string
Expand All @@ -24,3 +24,12 @@ connections:
required: true
secret: true
additionalProperties: false

query:
type: object
required: true
properties:
days:
type: string
description: "Days since last response"
required: true
14 changes: 14 additions & 0 deletions rules/remediate_satellite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
name: "remediate_satellite"
pack: "foreman"
description: "Remediate Satellite hosts that haven't checked in"
enabled : true

trigger:
type: "foreman.auto_remediate_satellite"
parameters: {}

action:
ref: "foreman.auto_remediate_satellite"
parameters:
server_name: "{{ trigger.server_name }}"
94 changes: 94 additions & 0 deletions sensors/foreman_auto_remediate_sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import json
import requests
from st2reactor.sensor.base import PollingSensor
from datetime import datetime, timedelta, date


class ForemanAutoRemediateSensor(PollingSensor):
def __init__(self, sensor_service, config=None, poll_interval=None):

super(ForemanAutoRemediateSensor, self).__init__(
sensor_service=sensor_service, config=config, poll_interval=poll_interval
)
self._logger = self._sensor_service.get_logger(__name__)
self._trigger_ref = "foreman.auto_remediate_satellite"

def setup(self):

self._USERNAME = self._config["foreman"]["dev"]["username"]
self._PASSWORD = self._config["foreman"]["dev"]["password"]
self._SERVER = self._config["foreman"]["dev"]["server"]
self._SSL_VERIFY = False
self._query = self._config["query"]["days"]
self._url = "http://{}/".format(self._SERVER)
self._url = self._url + "api/hosts"

def poll(self):

session = requests.Session()
session.auth = (self._USERNAME, self._PASSWORD)
session.verify = self._SSL_VERIFY
response = session.get(self._url)
if response.status_code != 200:
print(response.raise_for_status)
exit()

result = response.json()
result_json = json.dumps(result)
parsed = json.loads(result_json)

output_parse = json.dumps(parsed, indent=4, sort_keys=True)
parsed_list = parsed["results"]

query_date = int(self._query)

count = 0

for obj in parsed_list:

if "subscription_facet_attributes" in obj:
server_checkin_date_uni = obj["subscription_facet_attributes"][
"last_checkin"
]
# print(type(server_checkin_date))
query_checkin_date = date.today() - timedelta(days=query_date)
# print(type(query_checkin_date))

server_checkin_date = datetime.strptime(
server_checkin_date_uni.split()[0], "%Y-%m-%d"
).date()
# print(type(server_checkin_date))

if query_checkin_date < server_checkin_date:
print("This server responded within the query timeframe")
else:
# print("This server didn't respond since before query checkin date")
self.dispatch_trigger(obj["certname"], server_checkin_date)
count += 1
else:
print("Subscription facet attributes don't exist")
print("This is count: " + str(count))

def dispatch_trigger(self, server_name, last_checkin):

trigger = self._trigger_ref
payload = {"server_name": server_name, "last_checkin": last_checkin.strftime("%m/%d/%Y")}

self.sensor_service.dispatch(trigger=trigger, payload=payload)

def cleanup(self):
# This is called when the st2 system goes down. You can perform cleanup operations like
# closing the connections to external system here.
pass

def add_trigger(self, trigger):
# This method is called when trigger is created
pass

def update_trigger(self, trigger):
# This method is called when trigger is updated
pass

def remove_trigger(self, trigger):
# This method is called when trigger is deleted
pass
17 changes: 17 additions & 0 deletions sensors/foreman_auto_remediate_sensor.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
class_name: "ForemanAutoRemediateSensor"
entry_point: "foreman_auto_remediate_sensor.py"
description: "Sensor to check to make sure servers are responding"
poll_interval: 100000
trigger_types:
-
name: "auto_remediate_satellite"
description: "Trigger to remediate hosts that aren't responding"

payload_schema:
type: "object"
properties:
server_name:
type: "string"
last_checkin:
type: "string"