# Upclapi
## Declarative & command-line interface for [UpCloud](https://upcloud.com) resources
This was created since December 2020 to:
- to use YAML config definition files for resources and services
- create,delete,start,stop [UpCloud servers](https://upcloud.com/products/cloud-servers/).
- modify, delete [UpCloud storages](https://upcloud.com/products/maxiops-storage/).
- Run commands with **ssh** in [UpCloud servers](https://upcloud.com/products/cloud-servers/).
- create servers [Ansible inventories](https://docs.ansible.com/ansible/latest/index.html)
> TskSrvcs can be declared and grouped together in [YAML](https://en.wikipedia.org/wiki/YAML) files, some of them can use target resource UUID
All in a [GO](https://golang.org/) binary program thanks to [Official UpCloudLtd GO API](https://github.com/UpCloudLtd/upcloud-go-api)
It clearly does not try to replace tools like [Terraform](https://www.terraform.io/) or [Ansible](https://docs.ansible.com/),etc to manage **Infraestructure** rather as an alternative for some cases, like:
- simple servers provisioning
- servers tsksrvcs: start, stop, delete
- modify network interfaces
- float ip management
- modify storage
- automatic resources scale
- run commands on servers via **ssh** (output is captured)
- create [Ansible inventories](https://docs.ansible.com/ansible/latest/index.html)
- resources lists in **json**
- prototyping
...
- As a provider tool for other **LibreClouds** [Klouds](https://rlung.librecloud.online/LibreCloud/Klouds#klouds) tools: [CloudMandala](https://rlung.librecloud.online/LibreCloud/CloudMandala#cloudmandala) and [Zteron](https://rlung.librecloud.online/LibreCloud/CloudMandala#cloudmandala)
Since March 2021 [UpCloud](https://github.com/UpCloudLtd) made available a [UpCloud CLI - upctl](https://github.com/UpCloudLtd/upcloud-cli#upcloud-cli---upctl) to allow resources control from command line.
[UpClapi](https://rlung.librecloud.online/LibreCloud/Upclapi#upclapi) was create to be used with a [Declarative](https://en.wikipedia.org/wiki/Declarative_programming) approach to manage infrastructures although some tasks can be solved with imperative command calls, resources relationship and their dependencies should be set and declared somewhere at least for monitoring,management,etc.
Both developments ([upctl](https://github.com/UpCloudLtd/upcloud-cli#upcloud-cli---upctl) and [upclapi](https://rlung.librecloud.online/LibreCloud/Upclapi#upclapi)) use [Official UpCloudLtd GO API](https://github.com/UpCloudLtd/upcloud-go-api) extensively.
> [UpClapi](https://rlung.librecloud.online/LibreCloud/Upclapi#upclapi) is used as a tool to provision and manage **UpCloud** ressources for **LibreClouds** [Klouds](https://rlung.librecloud.online/LibreCloud/Klouds#klouds) with [CloudMandala](https://rlung.librecloud.online/LibreCloud/CloudMandala#cloudmandala) and [Zteron](https://rlung.librecloud.online/LibreCloud/CloudMandala#cloudmandala) as major tools.
## Requirements for build
- Go `1.16+`
- Go Modules defined in [go.mod](https://rlung.librecloud.online/LibreCloud/Upclapi/src/branch/master/go.mod)
## Build from source
- Clone this repository and go to folder:
```bash
git clone https://rlung.librecloud.online/LibreCloud/Upclapi.git
cd Upclapi
```
- Build:
```bash
make
```
- Install ($GOPATH/bin):
```bash
make install
```
#### Run examples
- [UpCloud](https://upcloud.com) Credentilas
Use evironment variables like this:
```bash
export UPCLOUD_USERNAME="api-username"
export UPCLOUD_PASSWORD="api-password"
```
As an alternative this can be set as in an enviroment file with paths:
/etc/upcloud/.env or /usr/local/etc/upcloud/.env
Another alternative is to use default [UpCloud CLI - upctl](https://github.com/UpCloudLtd/upcloud-cli#quick-start) config set path:
$HOME/.config/upctl.yaml
If creadentials are not found, this message will be displayed:
```txt
Auth info: Username must be specified
or
Auth info: Password must be specified
```
As a more secure option it is possible to encrypt sensitive informations like:
- Credentials (username/password)
- Data config file in yaml
- Help
```bash
# Getting help
go run ./... --help
```
```txt
Usage of upclapi:
-c string
command to run [
createserver, infoserver, restartserver, startserver, stopserver, modifyserver, deleteserver,
infofloatip, movefloatip, modifyip,
infotags, addtags, deletetags (use -t keep to keep storages)
liststorages, fixstorage (-t size | part0 | part1 | final), deletestorage, modifystorage, createstorageimage (-t title),
inventory, pubhosts, prvhosts
runssh, runcmd
] (default "infoserver")
-cmd string
run [ssh] command
-f string
path to data file (default "datacfg.yaml")
-id string
resource name or uuid
-kdr string
use coder
-o string
output format (json|yaml)
-t string
target item for command
```
- Create Server
```bash
./build/upclapi -c createserver -f [yaml-config-file]
```
- Info Server
```bash
./build/upclapi -c infoserver -f [yaml-config-file]
```
```bash
./build/upclapi -c infoserver -id server-hostname
```
- Move a Float IP
```bash
./build/upclapi -c movefloatip -f [yaml-config-file]
```
- Get attached IP to Float IP
```bash
./build/upclapi -c infofloatip -id float-ip ( or -f [yaml-config-file] ) -o attached
```
```bash
./build/upclapi -c movefloatip -id float-ip-address::target-hostname
```
- Run SSH on Server
(yaml-config-file has to include *ssh** config section)
```bash
./build/upclapi -c runssh -f [yaml-config-file] -ssh remote-command-to-execute
```
- Create Servers [Ansible Inventory](https://docs.ansible.com/ansible/latest/index.html)
(yaml-config-file has to include **cluster** config section)
```bash
./build/upclapi -c inventory -f [yaml-config-file]
```
> User account persmissions may not allow some tsksrvcs to create or deleted
> To fully manage, UpCloud owner account is mandatory
- To show info about coverage (will open in browser):
```bash
make show_coverage
```
- That's all! 🎉
## YAML Config Example
```yaml
# Controller to manage and monitor
cntrllrs:
- cldPath: relative-path-for-controller
host: hostname
masterPath: ''
sshaccess:
host: hostname
keyPath: ''
password: ''
port: 22
user: ssh-user
utype: key
domainName: domain-name
floatIP: ''
group: group-name
group_path: relative-group-path
hostPrefix: hostprefix-
mainName: main-name
# UpCloud as provider
provider: upcloud
resolvDNS: ''
servers:
# Apps to install
- apps:
- critical: no
liveness: ''
name: none
path: ''
req: ''
target: ''
arch: linux_amd64
backup:
- ''
clients:
- ''
cluster:
role: role-tag
hostname: hostname
loginUser:
sshKeys:
- ''
metadata: 1
networks:
- access: utility
family: IPv4
source_ip_filtering: yes
- access: public
family: IPv4
source_ip_filtering: yes
# If use SDN
- access: private
family: IPv4
ipaddress: 'ip-for-sdn'
network: "sdn-uuid"
source_ip_filtering: no
# UpCloud server plan
plan: "1xCPU-1GB"
rules:
- ''
sshAccess:
host: hostname
keyPath: ''
password: ''
port: 22
user: "ssh-user"
utype: key
storages:
- action: clone
size: 20
# this can be used to create partitions
finalSize: 20
makefs: ""
partSizes: ''
source: source-name
storage: UUID-for-source-image
tier: maxiops
title: Title-for-this-storage
tags:
- cd
- ci
timeZone: UTC
title: titls-of-this-host
# Tasks & Services to install,maintain,monitor, etc.
tsksrvcs:
- critical: no
liveness: ''
name: sysconfig
path: ''
req: ''
target: ''
useFloatIP: false
userData: ''
# UpCloud Zone
zone: es-mad1
floatIP: float-ip-for-servers
# "hostname" should start with hostPrefix or comment/remove this setting
hostPrefix: prefix-for-severs
# Could be same as hostPrefix, like "server" for server01, server02, etc
mainName: main-global/cluster/floatIP-name
servers:
# Repeat this section for each host
- hostname: test.example.com
title: "Host title"
# Cluster definition for this server not mandatory
cluster:
role: master # role in ansible inventory
## SSH credentials to run commands not mandatory
ssh:
host: hostName-or-ip
user: root
password: ""
type: key # can use password
keyPath: path-to-id_rsa-key-file
port: 22
# List of Tags (management can be restricted for user account)
tags:
- server
loginUser:
sshKeys: # ssh-rsa public keys to add
- ssh-rsa ....
plan: "1xCPU-1GB" # UpCloud Plan if is using an UpCloud "Simple Plan"
metaData: 1
timeZone: "UTC"
userData: ""
zone: nl-ams1 # UpCloud Zone
# List of Storage Devices, at least one
storageDevices:
- action: clone # UpCloud Storage Action
title: "storage-title"
storage: "UpCloud Storage UUID"
size: 25 # Volume Size in GB
tier: maxiops
# If this sever can use floatIP set to 1
useFloatIP: 1
# List of Networks, at least one
networks:
- access: utility # only if is need it
family: IPv4
- access: public # only if is need it
family: IPv4
- access: private # if is going to use SDN or remove
family: IPv4
network: UUID-SDN-NETWORK
ipaddress: SDN-ip-address-or-use-SDN-DHCP
```
## Environment
Main vars:
[UpCloud API](https://developers.upcloud.com) connetions
- UPCLOUD_USERNAME with username
- UPCLOUD_PASSWORD with password
- KUPCLAPI includes user + password encrypted
Use to preset settings:
| Arg | Env. var |
|---|---|
|-c|UPCLAPI_COMMAND|
|-f| UPCLAPI_DATACFG|
|-id|UPCLAPI_ID|
|-cmd|UPCLAPI_RUNCMD|
|-kdr|UPCLAPI_ENCODER|
|-o|UPCLAPI_OUT|
## Coders and encoders
It is possible to encrypt sensitive informations like:
- Credentials (username/password)
- Data config file in yaml
Coders are called using operating system command (exec)
> [Tecoder]() from [ZTerton]()
> backend developments is fully supported
Coder definition to be used:
| var | content |
|---|---|
| cmd | command-path |
| abbrv | abbreviation |
| decoder | decoder-args |
| fdecoder | file-decoder-args |
| encoder | encoder-args |
| fencoder | file-encoder-args |
## Author
- [Jesús Pérez](https://github.com/jesusperez).
## Article assistance
If you want to say «thank you»:
1. Twit about article [on your Twitter](https://twitter.com/intent/tweet?text=Let%27s%20write%20config%20for%20your%20Golang%20web%20app%20on%20right%20way%20%E2%80%94%20YAML%20%F0%9F%91%8C%20https%3A%2F%2Fdev.to%2Fkoddr%2Flet-s-write-config-for-your-golang-web-app-on-right-way-yaml-5ggp).
2. Add a GitHub Star and make Fork to this repository.
3. Donate some money to project author via PayPal: [@paypal.me/](https://paypal.me/).
4. Join UpCloud at my [referral link](https://upcloud.com/signup/?promo=CVR337) (your profit is **\$25** credits and I will receive \$50 worth of free credits).
Thanks for your support! 😘
## References
[UpCloudLtd go API](https://github.com/UpCloudLtd/upcloud-go-api)
[Let's write config for your Golang web app on right way — YAML 👌](https://dev.to/koddr/let-s-write-config-for-your-golang-web-app-on-right-way-yaml-5ggp). Published @ 13 Feb 2020.
[Go language: crypto / SSH executes remote commands](https://developpaper.com/go-language-crypto-ssh-executes-remote-commands/)
[golang-enter-ssh-sudo-password-on-prompt-or-exit](https://gist.github.com/boyzhujian/73b5ecd37efd6f8dd38f56e7588f1b58)
## License
MIT