<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Get Started on Crossplane</title><link>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/</link><description>Recent content in Get Started on Crossplane</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 01 Jan 0001 00:00:00 +0000</lastBuildDate><atom:link href="https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/index.xml" rel="self" type="application/rss+xml"/><item><title>Install Crossplane</title><link>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/install/</link><pubDate/><guid>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/install/</guid><description>&lt;p&gt;Crossplane installs into an existing Kubernetes cluster, creating the
Crossplane pod.&lt;/p&gt;
&lt;p&gt;Installing Crossplane enables the installation of Crossplane &lt;em&gt;Provider&lt;/em&gt;,
&lt;em&gt;Function&lt;/em&gt;, and &lt;em&gt;Configuration&lt;/em&gt; resources.&lt;/p&gt;
&lt;div class="admonition tip d-flex flex-column mx-4 p-0"&gt;
&lt;div class="admonition-title"&gt;
&lt;svg class="bi flex-shrink-0" role="img" aria-label="tip:"&gt;&lt;use
xlink:href="#check"/&gt;&lt;/svg&gt;
&lt;span class="ps-1"&gt;Tip&lt;/span&gt;
&lt;/div&gt;
&lt;div class="admonition-content"&gt;
If you don&amp;rsquo;t have a Kubernetes cluster create one locally with &lt;a href="https://kind.sigs.k8s.io/"&gt;Kind&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="anchor-link" id="prerequisites" href="#prerequisites" aria-label="Link to this section: Prerequisites"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;An actively &lt;a href="https://kubernetes.io/releases/patch-releases/#support-period"&gt;supported Kubernetes version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://helm.sh/docs/intro/install/"&gt;Helm&lt;/a&gt; version &lt;code&gt;v3.2.0&lt;/code&gt; or later&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- vale Google.Headings = NO --&gt;
&lt;!-- vale Microsoft.Headings = NO --&gt;
&lt;h2 id="install-crossplane"&gt;Install Crossplane &lt;a class="anchor-link" id="install-crossplane" href="#install-crossplane" aria-label="Link to this section: Install Crossplane"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;!-- vale Google.Headings = YES --&gt;
&lt;!-- vale Microsoft.Headings = YES --&gt;
&lt;p&gt;Install Crossplane using the &lt;em&gt;Helm chart&lt;/em&gt;.&lt;/p&gt;</description></item><item><title>Get Started With Control Plane Projects</title><link>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/get-started-with-control-plane-projects/</link><pubDate/><guid>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/get-started-with-control-plane-projects/</guid><description>&lt;p&gt;The Crossplane CLI includes development tools that simplify building a platform
on top of Crossplane. You can find a guide to getting started with the
Crossplane CLI developer tools in
&lt;a href="https://deploy-preview-1143--crossplane.netlify.app/cli/latest/get-started/get-started-with-control-plane-projects/"&gt;the CLI documentation&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Get Started With Composition</title><link>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/get-started-with-composition/</link><pubDate/><guid>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/get-started-with-composition/</guid><description>&lt;p&gt;This guide shows how to create a new kind of custom resource named &lt;code&gt;App&lt;/code&gt;. When a
user calls the custom resource API to create an &lt;code&gt;App&lt;/code&gt;, Crossplane creates a
&lt;code&gt;Deployment&lt;/code&gt; and a &lt;code&gt;Service&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Crossplane calls this &lt;em&gt;composition&lt;/em&gt;.&lt;/strong&gt; The &lt;code&gt;App&lt;/code&gt; is &lt;em&gt;composed of&lt;/em&gt; the
&lt;code&gt;Deployment&lt;/code&gt; and the &lt;code&gt;Service&lt;/code&gt;.&lt;/p&gt;
&lt;div class="admonition tip d-flex flex-column mx-4 p-0"&gt;
&lt;div class="admonition-title"&gt;
&lt;svg class="bi flex-shrink-0" role="img" aria-label="tip:"&gt;&lt;use
xlink:href="#check"/&gt;&lt;/svg&gt;
&lt;span class="ps-1"&gt;Tip&lt;/span&gt;
&lt;/div&gt;
&lt;div class="admonition-content"&gt;
The guide shows how to configure composition using YAML, YAML+CEL, templated
YAML, Python, and KCL. You can pick your preferred language.
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;An &lt;code&gt;App&lt;/code&gt; custom resource looks like this:&lt;/p&gt;</description></item><item><title>Get Started With Managed Resources</title><link>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/get-started-with-managed-resources/</link><pubDate/><guid>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/get-started-with-managed-resources/</guid><description>&lt;p&gt;This guide shows how to install and use a new kind of custom resource called
&lt;code&gt;Bucket&lt;/code&gt;. When a user calls the custom resource API to create a &lt;code&gt;Bucket&lt;/code&gt;,
Crossplane creates a bucket in AWS S3.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Crossplane calls this a &lt;em&gt;managed resource&lt;/em&gt;&lt;/strong&gt;. A managed resource is a
ready-made custom resource that manages something outside of the control plane.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;Bucket&lt;/code&gt; managed resource looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-1"&gt;&lt;a class="lnlinks" href="#hl-0-1"&gt;1&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;s3.aws.m.upbound.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-2"&gt;&lt;a class="lnlinks" href="#hl-0-2"&gt;2&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Bucket&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-3"&gt;&lt;a class="lnlinks" href="#hl-0-3"&gt;3&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-4"&gt;&lt;a class="lnlinks" href="#hl-0-4"&gt;4&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-5"&gt;&lt;a class="lnlinks" href="#hl-0-5"&gt;5&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;crossplane-bucket-example&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-6"&gt;&lt;a class="lnlinks" href="#hl-0-6"&gt;6&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-7"&gt;&lt;a class="lnlinks" href="#hl-0-7"&gt;7&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;forProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-8"&gt;&lt;a class="lnlinks" href="#hl-0-8"&gt;8&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;us-east-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="admonition note d-flex flex-column mx-4 p-0"&gt;
&lt;div class="admonition-title"&gt;
&lt;svg class="bi flex-shrink-0" role="img" aria-label="note:"&gt;&lt;use
xlink:href="#info"/&gt;&lt;/svg&gt;
&lt;span class="ps-1"&gt;Note&lt;/span&gt;
&lt;/div&gt;
&lt;div class="admonition-content"&gt;
Kubernetes calls third party API resources &lt;em&gt;custom resources&lt;/em&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="anchor-link" id="prerequisites" href="#prerequisites" aria-label="Link to this section: Prerequisites"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This guide requires:&lt;/p&gt;</description></item><item><title>Get Started With Operations</title><link>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/get-started-with-operations/</link><pubDate/><guid>https://deploy-preview-1143--crossplane.netlify.app/v2.4/get-started/get-started-with-operations/</guid><description>&lt;p&gt;This guide shows how to use Crossplane Operations to automate day-two
operational tasks. You create an &lt;code&gt;Operation&lt;/code&gt; that checks SSL certificate
expiry for a website.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Crossplane calls this &lt;em&gt;Operations&lt;/em&gt;.&lt;/strong&gt; Operations run function pipelines to
perform tasks that don&amp;rsquo;t fit the typical resource creation pattern - like
certificate monitoring, rolling upgrades, or scheduled maintenance.&lt;/p&gt;
&lt;p&gt;An &lt;code&gt;Operation&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-1"&gt;&lt;a class="lnlinks" href="#hl-0-1"&gt; 1&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ops.crossplane.io/v1alpha1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-2"&gt;&lt;a class="lnlinks" href="#hl-0-2"&gt; 2&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Operation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-3"&gt;&lt;a class="lnlinks" href="#hl-0-3"&gt; 3&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-4"&gt;&lt;a class="lnlinks" href="#hl-0-4"&gt; 4&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;check-cert-expiry&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-5"&gt;&lt;a class="lnlinks" href="#hl-0-5"&gt; 5&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-6"&gt;&lt;a class="lnlinks" href="#hl-0-6"&gt; 6&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pipeline&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-7"&gt;&lt;a class="lnlinks" href="#hl-0-7"&gt; 7&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-8"&gt;&lt;a class="lnlinks" href="#hl-0-8"&gt; 8&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;step&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;check-certificate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-9"&gt;&lt;a class="lnlinks" href="#hl-0-9"&gt; 9&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;functionRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-10"&gt;&lt;a class="lnlinks" href="#hl-0-10"&gt;10&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;crossplane-contrib-function-python&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-11"&gt;&lt;a class="lnlinks" href="#hl-0-11"&gt;11&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-12"&gt;&lt;a class="lnlinks" href="#hl-0-12"&gt;12&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;python.fn.crossplane.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-13"&gt;&lt;a class="lnlinks" href="#hl-0-13"&gt;13&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Script&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-14"&gt;&lt;a class="lnlinks" href="#hl-0-14"&gt;14&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-15"&gt;&lt;a class="lnlinks" href="#hl-0-15"&gt;15&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; import ssl
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-16"&gt;&lt;a class="lnlinks" href="#hl-0-16"&gt;16&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; import socket
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-17"&gt;&lt;a class="lnlinks" href="#hl-0-17"&gt;17&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; from datetime import datetime
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-18"&gt;&lt;a class="lnlinks" href="#hl-0-18"&gt;18&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-19"&gt;&lt;a class="lnlinks" href="#hl-0-19"&gt;19&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; from crossplane.function import request, response
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-20"&gt;&lt;a class="lnlinks" href="#hl-0-20"&gt;20&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-21"&gt;&lt;a class="lnlinks" href="#hl-0-21"&gt;21&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; def operate(req, rsp):
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-22"&gt;&lt;a class="lnlinks" href="#hl-0-22"&gt;22&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; hostname = &amp;#34;google.com&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-23"&gt;&lt;a class="lnlinks" href="#hl-0-23"&gt;23&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; port = 443
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-24"&gt;&lt;a class="lnlinks" href="#hl-0-24"&gt;24&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-25"&gt;&lt;a class="lnlinks" href="#hl-0-25"&gt;25&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # Get SSL certificate info
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-26"&gt;&lt;a class="lnlinks" href="#hl-0-26"&gt;26&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; context = ssl.create_default_context()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-27"&gt;&lt;a class="lnlinks" href="#hl-0-27"&gt;27&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; with socket.create_connection((hostname, port)) as sock:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-28"&gt;&lt;a class="lnlinks" href="#hl-0-28"&gt;28&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; with context.wrap_socket(sock, server_hostname=hostname) as ssock:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-29"&gt;&lt;a class="lnlinks" href="#hl-0-29"&gt;29&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; cert = ssock.getpeercert()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-30"&gt;&lt;a class="lnlinks" href="#hl-0-30"&gt;30&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-31"&gt;&lt;a class="lnlinks" href="#hl-0-31"&gt;31&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # Parse expiration date
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-32"&gt;&lt;a class="lnlinks" href="#hl-0-32"&gt;32&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; expiry_date = datetime.strptime(cert[&amp;#39;notAfter&amp;#39;], &amp;#39;%b %d %H:%M:%S %Y %Z&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-33"&gt;&lt;a class="lnlinks" href="#hl-0-33"&gt;33&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; days_until_expiry = (expiry_date - datetime.now()).days
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-34"&gt;&lt;a class="lnlinks" href="#hl-0-34"&gt;34&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-35"&gt;&lt;a class="lnlinks" href="#hl-0-35"&gt;35&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # Return results in operation output
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-36"&gt;&lt;a class="lnlinks" href="#hl-0-36"&gt;36&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; response.set_output(rsp, {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-37"&gt;&lt;a class="lnlinks" href="#hl-0-37"&gt;37&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;hostname&amp;#34;: hostname,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-38"&gt;&lt;a class="lnlinks" href="#hl-0-38"&gt;38&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;certificateExpires&amp;#34;: cert[&amp;#39;notAfter&amp;#39;],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-39"&gt;&lt;a class="lnlinks" href="#hl-0-39"&gt;39&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;daysUntilExpiry&amp;#34;: days_until_expiry,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-40"&gt;&lt;a class="lnlinks" href="#hl-0-40"&gt;40&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;status&amp;#34;: &amp;#34;warning&amp;#34; if days_until_expiry &amp;lt; 30 else &amp;#34;ok&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln" id="hl-0-41"&gt;&lt;a class="lnlinks" href="#hl-0-41"&gt;41&lt;/a&gt;&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; })&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- vale Crossplane.Spelling = NO --&gt;
&lt;p&gt;&lt;strong&gt;The &lt;code&gt;Operation&lt;/code&gt; runs once to completion, like a Kubernetes &lt;code&gt;Job&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>