Skip to content

Commit

Permalink
Update Readme and add example yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
etesami committed Aug 31, 2024
1 parent 234504f commit 137dfa2
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 17 deletions.
125 changes: 119 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,130 @@
# provider-ssh

## Overview

The `provider-ssh` is a Crossplane provider designed for executing scripts on a remote machine over SSH.

The SSH provider adds support for `Script` resources with a `managementPolicy` of `Observe`. This means `Script` resources do not manage any external resources, instead they are used only to execute scripts on and fetch data from an external source.
The SSH provider introduces support for `Script` resources. The `Script` resources manages execution
of a primary script, a status check script, and a cleanup script. The purpose of this provider
is to retrieve data and apply configurations on a remote machine in accordance to the
managed resources.

The `provider-ssh` requires:

- A `ProviderConfig` type that references a credentials `Secret`, which contains the remote machine's `IP`, `Port`, and `Username` and `Private Key`.
- A `Script` resource type that includes the script to be executed and any variables
with their corresponding values. These variables will be replaced with actual values
before the script is sent to the remote machine.
- A `ProviderConfig` type that references a credentials `Secret`, which contains a json file with
connection details for the remote machine (see an example below).
- A `Script` resource type that includes the `initScript`, `statusCheckScript` and `cleanupScript`.
It also contains a list of `variables` and their corresponding values, which should be replaced
within the scripts before they are sent to the remote machine.
- A managed resource controller that reconciles `Script` objects, by connecting
to the target machine, executing the scripts, and writing the output (`stdout` and `stderr`)
back to the respective status fields of the object.

> Feel free to submit any issues you encounter.
![image](./provider-ssh-crossplane-diagram.png)

## Getting Started

To begin, you'll need to create a `ProviderConfig` and a `Secret`.
To initiate a connection to the remote host, either a `password` or `privateKey` is required.
The `privateKey` should be provided as a single-line, base64-encoded string.
To generate the base64 version of a private key, use the following command:

```bash
# In Linux
cat .ssh/id_rsa | base64 -w0
```
The `knownHosts` file is required to verify the identity of the server.
You can generate and verify it using the command below:

```bash
ssh-keyscan <HOST-REMOTE-IP>
```

Next, construct the `ProviderConfig` and `Secret` as shown below:

```yaml
apiVersion: v1
kind: Secret
metadata:
namespace: crossplane-system
name: providerssh-secret
type: Opaque
stringData:
config: |
{
"username": "ubuntu",
"password": "password",
"privateKey": "5XUUNPV2tSd0ptTFp...wbTNFKzhqMkYzdXc5ClNRZ09QO",
"hostIP": "10.29.30.5",
"hostPort": "22",
"knownHosts": "10.29.30.5 ecdsa-sha2-nistp256 AAAAE2VjZHN...UpvT57WP45MDBAV4CxQ="
}
---
apiVersion: ssh.crossplane.io/v1alpha1
kind: ProviderConfig
metadata:
name: providerssh-config
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: providerssh-secret
key: config
```
### Script
A `Script` object supports the following:

- `initScript`: This script is executed for the first time and whenever the resource is detected as not existing,
or the `statusCheckScript` returns an error.
- `statusCheckScript`: This script is executed to check the status after running the `initScript`.
- `cleanupScript`: This script is executed when the managed resource is deleted.

When any of these scripts are executed, the `statusCode` field reflects the returned status code of the script execution.
The `stdout` and `stderr` fields capture the standard output and standard error,
respectively, of the last execution of the `statusCheckScript`.

Here is a sample `Script` yaml file:

```yaml
apiVersion: ssh.crossplane.io/v1alpha1
kind: Script
metadata:
name: sample-script
spec:
forProvider:
variables:
- name: VPN_SERVER_URL
value: "199.199.199.10"
initScript: |
touch /tmp/new_file.txt
# echo current date and time to the file
echo {{VPN_SERVER_URL}} >> /tmp/new_file.txt
date >> /tmp/new_file.txt
echo "--- --- --- ---" >> /tmp/new_file.txt
cat /tmp/new_file.txt
statusCheckScript: |
# check if the file exists
if [ -f /tmp/new_file.txt ]; then
echo "File exists"
# check if the file has the correct content
if grep -q {{VPN_SERVER_URL}} /tmp/new_file.txt; then
echo "File has the correct content"
exit 0
else
echo "File does not have the correct content"
exit 1
fi
else
echo "File does not exist"
exit 1
fi
cleanupScript: |
rm /tmp/new_file.txt
sudoEnabled: false
providerConfigRef:
name: providerssh-config
```

30 changes: 19 additions & 11 deletions examples/provider/config.yaml
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
apiVersion: v1
kind: Namespace
metadata:
name: crossplane-system
---
# apiVersion: v1
# kind: Namespace
# metadata:
# name: crossplane-system
# ---
apiVersion: v1
kind: Secret
metadata:
namespace: crossplane-system
name: example-provider-secret
name: providerssh-secret
type: Opaque
data:
# credentials: BASE64ENCODED_PROVIDER_CREDS
stringData:
config: |
{
"username": "",
"password": "",
"privateKey": "",
"hostIP": "",
"hostPort": "22",
"knownHosts": ""
}
---
apiVersion: ssh.crossplane.io/v1alpha1
kind: ProviderConfig
metadata:
name: example
name: providerssh-config
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: example-provider-secret
key: credentials
name: providerssh-secret
key: config
37 changes: 37 additions & 0 deletions examples/script.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
apiVersion: ssh.crossplane.io/v1alpha1
kind: Script
metadata:
name: sample-script
spec:
forProvider:
variables:
- name: VPN_SERVER_URL
value: "199.199.199.10"
initScript: |
touch /tmp/new_file.txt
# echo current date and time to the file
echo {{VPN_SERVER_URL}} >> /tmp/new_file.txt
date >> /tmp/new_file.txt
echo "--- --- --- ---" >> /tmp/new_file.txt
cat /tmp/new_file.txt
statusCheckScript: |
# check if the file exists
if [ -f /tmp/new_file.txt ]; then
echo "File exists"
# check if the file has the correct content
if grep -q {{VPN_SERVER_URL}} /tmp/new_file.txt; then
echo "File has the correct content"
exit 0
else
echo "File does not have the correct content"
exit 1
fi
else
echo "File does not exist"
exit 1
fi
cleanupScript: |
rm /tmp/new_file.txt
sudoEnabled: false
providerConfigRef:
name: providerssh-config
Binary file added provider-ssh-crossplane-diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 137dfa2

Please sign in to comment.