aboutsummaryrefslogtreecommitdiffstats
path: root/arthur/exts/kubernetes/nodes.py
diff options
context:
space:
mode:
Diffstat (limited to 'arthur/exts/kubernetes/nodes.py')
-rw-r--r--arthur/exts/kubernetes/nodes.py102
1 files changed, 102 insertions, 0 deletions
diff --git a/arthur/exts/kubernetes/nodes.py b/arthur/exts/kubernetes/nodes.py
new file mode 100644
index 0000000..b5cfc29
--- /dev/null
+++ b/arthur/exts/kubernetes/nodes.py
@@ -0,0 +1,102 @@
+"""The Nodes cog helps with managing Kubernetes nodes."""
+import textwrap
+
+from discord import Embed
+from discord.ext import commands
+
+from arthur.apis.kubernetes import nodes
+from arthur.bot import KingArthur
+from arthur.utils import datetime_to_discord
+
+
+class Nodes(commands.Cog):
+ """Commands for working with Kubernetes nodes."""
+
+ def __init__(self, bot: KingArthur) -> None:
+ self.bot = bot
+
+ @commands.group(name="nodes", aliases=["node"], invoke_without_command=True)
+ async def nodes(self, ctx: commands.Context) -> None:
+ """Commands for working with Kubernetes nodes."""
+ await ctx.send_help(ctx.command)
+
+ @nodes.command(name="list", aliases=["ls"])
+ async def nodes_list(self, ctx: commands.Context) -> None:
+ """List Kubernetes nodes in the cluster."""
+ cluster_nodes = await nodes.list_nodes()
+
+ return_embed = Embed(title="Cluster nodes")
+
+ for node in cluster_nodes.items:
+ statuses = []
+
+ for condition in node.status.conditions:
+ if condition.type == "Ready" and condition.status == "True":
+ statuses.append("Ready")
+ break
+ else:
+ statuses.append("Unready")
+
+ for condition in node.status.conditions:
+ if condition.type == "Ready":
+ pass
+
+ if condition.status is True:
+ statuses.append(condition.type)
+
+ if node.spec.taints:
+ for taint in node.spec.taints:
+ statuses.append(taint.effect)
+
+ node_creation = node.metadata.creation_timestamp
+
+ return_embed.add_field(
+ name=node.metadata.name,
+ value=textwrap.dedent(
+ f"""
+ **Status:** {", ".join(statuses)}
+ **Kubernetes version:** {node.status.node_info.kubelet_version}
+ **Created**: {datetime_to_discord(node_creation, "R")}
+ """
+ ),
+ inline=False,
+ )
+
+ await ctx.send(embed=return_embed)
+
+ @nodes.command(name="cordon")
+ async def nodes_cordon(self, ctx: commands.Context, *, node: str) -> None:
+ """
+ Cordon a node in the cluster.
+
+ Cordoning a node has the effect of preventing any new deployments from being scheduled.
+ """
+ await nodes.cordon_node(node)
+
+ await ctx.send(
+ embed=Embed(
+ title=f"Cordoned {node}",
+ description=f"`{node}` is now cordoned and no pods will be scheduled to it.",
+ )
+ )
+
+ @nodes.command(name="uncordon")
+ async def nodes_uncordon(self, ctx: commands.Context, *, node: str) -> None:
+ """
+ Uncordon a node in the cluster.
+
+ Cordoning a node has the effect of preventing any new deployments from being scheduled.
+ """
+ await nodes.uncordon_node(node)
+
+ await ctx.send(
+ embed=Embed(
+ title=f"Uncordoned {node}",
+ description=f"`{node}` is now uncordoned, future pods may be scheduled to it.",
+ )
+ )
+
+
+def setup(bot: KingArthur) -> None:
+ """Add the extension to the bot."""
+ bot.add_cog(Nodes(bot))