Posts


Let us say we have a bunch of status checks being recorded by promethues. These status checks are similar to tools such as pingdom. To provide a simple up/down status check dashboard the grafana state timeline panel can be used along with prometheus probe_success.

Tools required

Grafana state timeline

I won’t go into the details of installing prometheus and grafana. There is plenty of information on their respective sites that will be up to date and much more accurate.

Assuming prometheus and grafana are installed with the proper configs the rest of this section will describe configuring a state timeline using probe_success. The data collection can be as simple as using the prmoetheus blackbox exporter.

Add a new state timeline panel to a dashboard. For the query set the data source to a configured prometheus server. If there are a lot of health checks the panel must be manually dragged for a larger height to make the panel readable.

In the options panel set the Legend

  • Visible -> true
  • Mode -> List
  • Placement -> Bottom

In the options panel set the Color scheme

  • From thresholds (by value)

In the options panel set the Value mappings

  • 1 -> UP
  • 0 -> DOWN

In the options panel set the Thresholds

  • 1 -> green
  • Base -> red

Example queries

Visualize status for a production environment:

avg_over_time(probe_success{env="production"}[1m])

Visualize the status of a production environment but exclude certain instances:

avg_over_time(probe_success{env="production", instance!~".*ignoreme.*|.*ignorethis.*"}[1m])

Visualize status for a staging environment:

avg_over_time(probe_success{env="staging"}[1m])


Set kubectl path

# Set the path to kubectl
# Example path if using microk8s "/snap/bin/microk8s kubectl"
k="/usr/bin/kubectl"

Set Rolling Update Strategy maxUnavailable - Patch

Set the rolling update strategy to have a maxUnavailable to avoid outages.

echo "https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"
NAMESPACE="PLACEHOLDER"
DEPLOYMENT_NAME="PLACEHOLDER"

$k -n $NAMESPACE patch deployment $DEPLOYMENT_NAME -p "{\"spec\":{\"strategy\":{\"rollingUpdate\":{\"maxSurge\": 0, \"maxUnavailable\": \"25%\"}, \"type\": \"RollingUpdate\"}}}"

Health Checks - Patch

Health checks are important to managing a cluster. They are used to determine if pods are online and healthy or offline and needs disposal and new pods spun up.

startup probe

Has the pod started?

echo "https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/"
NAMESPACE="PLACEHOLDER"
DEPLOYMENT_NAME="PLACEHOLDER"
STARTUPPROBE="/healthz"
PORT="443"
SCHEME="HTTPS"

$k -n $NAMESPACE patch deployment $DEPLOYMENT_NAME -p "{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"$DEPLOYMENT_NAME\",\"startupProbe\":{\"httpGet\": {\"path\":\"$STARTUPPROBE\", \"port\": $PORT, \"scheme\": \"$SCHEME\"}, \"failureThreshold\": 30, \"periodSeconds\": 10}}]}}}}"

livenessProbe

Is the pod alive.

echo "https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/"
NAMESPACE="PLACEHOLDER"
DEPLOYMENT_NAME="PLACEHOLDER"
LIVEPROBE="/healthz/live"
PORT="443"
SCHEME="HTTPS"

$k -n $NAMESPACE patch deployment $DEPLOYMENT_NAME -p "{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"$DEPLOYMENT_NAME\",\"livenessProbe\":{\"httpGet\": {\"path\":\"$LIVEPROBE\", \"port\": $PORT, \"scheme\": \"$SCHEME\"}, \"initialDelaySeconds\": 30, \"failureThreshold\": 3, \"timeoutSeconds\": 5}}]}}}}"

readinessProbe

Is the pod alive and ready to serve traffic.

echo "https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/"
NAMESPACE="PLACEHOLDER"
DEPLOYMENT_NAME="PLACEHOLDER"
READYPROBE="/healthz/ready"
PORT="443"
SCHEME="HTTPS"

$k -n $NAMESPACE patch deployment $DEPLOYMENT_NAME -p "{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"$DEPLOYMENT_NAME\",\"readinessProbe\":{\"httpGet\": {\"path\":\"$READYPROBE\", \"port\": $PORT, \"scheme\": \"$SCHEME\"}, \"initialDelaySeconds\": 30, \"failureThreshold\": 30, \"timeoutSeconds\": 15}}]}}}}"

Change Image Name/Version - Patch

Upgrade or downgrade images.

echo "https://kubernetes.io/docs/reference/kubectl/cheatsheet/"
NAMESPACE="PLACEHOLDER"
DEPLOYMENT_NAME="PLACEHOLDER"
IMAGE_NAME="PLACEHOLDER"

$k -n $NAMESPACE patch deployment $DEPLOYMENT_NAME -p "{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"$DEPLOYMENT_NAME\",\"image\":\"$IMAGE_NAME\"}]}}}}"

Reserve Memory and RAM Resources - Patch

Request a set reservation of memory and cpu. This helps kubernetes properly schedule pods across clusters.

echo "https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/"
NAMESPACE="PLACEHOLDER"
DEPLOYMENT_NAME="PLACEHOLDER"
RAM="128Mi"
CPU="500m"

$k -n $NAMESPACE patch deployment $DEPLOYMENT_NAME -p "{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"$DEPLOYMENT_NAME\",\"resources\":{\"requests\": {\"memory\":\"$RAM\", \"cpu\": \"$CPU\"}}}]}}}}"

Limit Memory and RAM Resources - Patch

Set a limit on memory and cpu.

echo "https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/"
NAMESPACE="PLACEHOLDER"
DEPLOYMENT_NAME="PLACEHOLDER"
RAM="2048Mi"
CPU="2500m"

$k -n $NAMESPACE patch deployment $DEPLOYMENT_NAME -p "{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"$DEPLOYMENT_NAME\",\"resources\":{\"limits\": {\"memory\":\"$RAM\", \"cpu\": \"$CPU\"}}}]}}}}"

References


As of June 2023 code signing requires that hardware tokens must be used. The following documentation is an opinionated way to to make this work using digicert. This document does not cover initial setup and purchase of ev code signing cert. This document will only cover using an ev hardware token with SafeNet.

DigiCert’s SafeNet instructions.

Sign a dotnet assembly

The hardware token must be attached to the computer. The SafeNet Authentication client tool must be running in the user session and logged in.

WILL NOT WORK IN RDP/SSH SESSION.

Example command syntax as of March 25, 2023.

.\signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /n "Certs Subject Name Goes Here" "C:\path\to\fileToSign.exe"

The above example will prompt you with for the hardwares signing token and it must be manually entered for each file signed.

Enable batch signing files

How to Enable Single Logon for a SafeNet Token

  1. Open SafeNet Authentication Client Tools.

Navigate to Start > Program Files > Safenet > Safenet Authentication Client Tools.

  1. Click the Advanced View icon (gold gear).
  2. In the menu tree in the left pane, select Client Settings.
  3. In the right pane, select the Advanced tab.
  4. On the Advanced tab, select the Enable single logon option.
  5. Click Save.
  6. To activate the single logon feature, log off from the computer and log on again.

With the above done SafeNet will only prompt once per session for the hardware signing token password.

Automated EV signing using signtool /kc

Export the certificate. See Automate Extended Validation (EV) code signing. The examples below is taken from that stackoverflow post. It has screenshots. Read it.

Ensure that the ** characters remain just replace the characters **THE_PASSWORD.


& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool.exe" sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /n "Certs Subject Name Goes Here" /f "C:\the\path\to\exported\cert.cer" /csp "eToken Base Cryptographic Provider" /kc "[THE_READER{{THE_TOKEN_PASSWORD}}]=THE_CONTAINER_NAME" "C:\path\to\fileToSign.exe"

For /kc the value should be in the format below:


[reader{{password}}]=name

Where:

  • reader (THE_READER) is the “Reader name” from the SafeNet Client UI
  • password (THE_TOKEN_PASSWORD) is your token password
  • name (THE_CONTAINER_NAME) is the “Container name” from the SafeNet Client UI

References


WARNING. Do not use. This is one big experiment.

crystalcmd is a:

Java and c# program to load json files into crystal reports and produce PDFs.

Server side hosting

IIS

Client side

Curl example

curl https://c.majorsilence.com/status

curl -F "reportdata=@test.json" -F "reporttemplate=@report.rpt" https:///export --output testout.pdf

# test localhost
curl -F "reportdata=@test.json" -F "reporttemplate=@report.rpt" https:///export --output testout.pdf

C# example

Add the package Majorsilence.CrystalCmd.Client to your project.

dotnet add package Majorsilence.CrystalCmd.Client 

cs code

DataTable dt = new DataTable();

// init reprt data
var reportData = new Majorsilence.CrystalCmd.Client.Data()
{
    DataTables = new Dictionary<string, string>(),
    MoveObjectPosition = new List<Majorsilence.CrystalCmd.Client.MoveObjects>(),
    Parameters = new Dictionary<string, object>(),
    SubReportDataTables = new List<Majorsilence.CrystalCmd.Client.SubReports>()
};

// add as many data tables as needed.  The client library will do the necessary conversions to json/csv.
reportData.AddData("report name goes here", "table name goes here", dt);

// export to pdf
var crystalReport = System.IO.File.ReadAllBytes("The rpt template file path goes here");
using (var instream = new MemoryStream(crystalReport))
using (var outstream = new MemoryStream())
{
    var rpt = new Majorsilence.CrystalCmd.Client.Report(serverUrl, username: "The server username goes here", password: "The server password goes here");
    using (var stream = await rpt.GenerateAsync(reportData, instream, _httpClient))
    {
        stream.CopyTo(outstream);
        return outstream.ToArray();
    }
}