|
|
| Line 76: |
Line 76: |
| split --lines=10000 --numeric-suffixes --additional-suffix='.txt' BIG_FILE.txt little_file. | | split --lines=10000 --numeric-suffixes --additional-suffix='.txt' BIG_FILE.txt little_file. |
| </source> | | </source> |
|
| |
| == "BASH is better" ==
| |
| Most job postings that focus on DevOps have requirements for [[Python]], [[Go]] programming or some other programming language. I disagree that a [[DevOps]] Engineer should also be a programmer. I prioritize quality and workmanship (craftsmanship) which is '''informed''' by broad experience, but '''honed''' by specialization. As a construction analogy, I prefer individual skilled trades over the general handyman approach. Simply put: DevOps is DevOps, it is not programming. Worse, the requirement for the hot language of the day is a bigger tell-tale sign that the company is either posturing or doesn't know what they're doing. Back when when I first learned Perl (which isn't the hot new language anymore), there was a hilarious t-shirt that said "Be careful or I'll replace you with a line of code"<ref>Dave Jacoby agrees with me on the broad point that (programming) languages are just different domain dialects, and also cites the ThinkGeek t-shirt phrase "Go Away Or I Will Replace You With a Small Shell Script"
| |
|
| |
| https://jacoby.github.io/2021/11/16/i-will-replace-you-with-a-small-shell-script.html</ref>. Although you ''could'' write the Python example more concisely, it is a real-world example of code that I found that does the same thing as 5 lines of BASH that I wrote.
| |
|
| |
| [[BASH]] code to concatenate [[certbot]] certificates:<syntaxhighlight lang="bash">
| |
| #!/bin/bash
| |
|
| |
| # $RENEWED_DOMAINS will contain a space-delimited list of renewed
| |
| # certificate domains (for example, "example.com www.example.com"
| |
| # loop through a dynamic list of directories in 'live'
| |
| # for SITE in $(find /etc/letsencrypt/live -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
| |
| # $RENEWED_LINEAGE will contain the live subdirectory
| |
| for SITE in $RENEWED_DOMAINS
| |
| do
| |
| # move to correct let's encrypt directory
| |
| cd $RENEWED_LINEAGE
| |
| # cat files to make combined .pem for haproxy
| |
| cat fullchain.pem privkey.pem > /etc/haproxy/certs/$SITE.pem
| |
| done
| |
| # reload haproxy
| |
| # systemctl reload haproxy
| |
| </syntaxhighlight>Python code to concatenate certbot certificates:<syntaxhighlight lang="python3">
| |
| #!/usr/bin/env python3
| |
|
| |
| import os
| |
| import re
| |
| import sys
| |
|
| |
| # Certbot sets an environment variable RENEWED_LINEAGE, which points to the
| |
| # path of the renewed certificate. We use that path to determine and find
| |
| # the files for the currently renewed certificated
| |
| lineage=os.environ.get('RENEWED_LINEAGE')
| |
|
| |
| # If nothing renewed, exit
| |
| if not lineage:
| |
| sys.exit()
| |
|
| |
| # From the linage, we strip the 'domain name', which is the last part
| |
| # of the path.
| |
| result = re.match(r'.*/live/(.+)$', lineage)
| |
|
| |
| # If we can not recognize the path, we exit with 1
| |
| if not result:
| |
| sys.exit(1)
| |
|
| |
| # Extract the domain name
| |
| domain = result.group(1)
| |
|
| |
| # Define a path for HAproxy where you want to write the .pem file.
| |
| deploy_path="/etc/haproxy/ssl/" + domain + ".pem"
| |
|
| |
| # The source files can be found in below paths, constructed with the lineage
| |
| # path
| |
| source_key = lineage + "/privkey.pem"
| |
| source_chain = lineage + "/fullchain.pem"
| |
|
| |
| # HAproxy requires to combine the key and chain in one .pem file
| |
| with open(deploy_path, "w") as deploy, \
| |
| open(source_key, "r") as key, \
| |
| open(source_chain, "r") as chain:
| |
| deploy.write(key.read())
| |
| deploy.write(chain.read())
| |
|
| |
| # Here you can add your service reload command. Which will be executed after
| |
| # every renewal, which is fine if you only have a few domains.
| |
|
| |
| # Alternative is to add the reload to the --post-hook. In that case it is only
| |
| # run once after all renewals. That would be the use-case if you have a large
| |
| # number of different certificates served by HAproxy.
| |
| </syntaxhighlight>
| |
|
| |
|
| {{References}} | | {{References}} |