mirror of
https://github.com/hassio-addons/addon-ubuntu-base.git
synced 2025-05-07 04:11:26 +00:00
⬆️ Updates Hassio Bash library to the latest
This commit is contained in:
parent
e6adb872e7
commit
c2c7d91d90
14 changed files with 609 additions and 87 deletions
|
@ -15,11 +15,14 @@ ENV \
|
|||
# Copy root filesystem
|
||||
COPY rootfs /
|
||||
|
||||
# Copy yq
|
||||
ARG BUILD_ARCH=amd64
|
||||
COPY bin/yq_${BUILD_ARCH} /usr/bin/yq
|
||||
|
||||
# Set shell
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
# Install base system
|
||||
ARG BUILD_ARCH=amd64
|
||||
RUN \
|
||||
apt-get update \
|
||||
\
|
||||
|
|
BIN
base/bin/yq_aarch64
Executable file
BIN
base/bin/yq_aarch64
Executable file
Binary file not shown.
BIN
base/bin/yq_amd64
Executable file
BIN
base/bin/yq_amd64
Executable file
Binary file not shown.
BIN
base/bin/yq_armhf
Executable file
BIN
base/bin/yq_armhf
Executable file
Binary file not shown.
BIN
base/bin/yq_i386
Executable file
BIN
base/bin/yq_i386
Executable file
Binary file not shown.
|
@ -33,6 +33,8 @@ source "${__LIB_DIR}/modules/config.sh"
|
|||
source "${__LIB_DIR}/modules/jq.sh"
|
||||
#shellcheck source=base/rootfs/usr/lib/hassio-addons/modules/log.sh
|
||||
source "${__LIB_DIR}/modules/log.sh"
|
||||
#shellcheck source=base/rootfs/usr/lib/hassio-addons/modules/pwned.sh
|
||||
source "${__LIB_DIR}/modules/pwned.sh"
|
||||
#shellcheck source=base/rootfs/usr/lib/hassio-addons/modules/string.sh
|
||||
source "${__LIB_DIR}/modules/string.sh"
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ readonly HASS_API_ENDPOINT='http://hassio'
|
|||
source "${__LIB_DIR}/modules/api/addons.sh"
|
||||
# shellcheck source=base/rootfs/usr/lib/hassio-addons/modules/api/hardware.sh
|
||||
source "${__LIB_DIR}/modules/api/hardware.sh"
|
||||
# shellcheck source=base/rootfs/usr/lib/hassio-addons/modules/api/hassos.sh
|
||||
source "${__LIB_DIR}/modules/api/hassos.sh"
|
||||
# shellcheck source=base/rootfs/usr/lib/hassio-addons/modules/api/homeassistant.sh
|
||||
source "${__LIB_DIR}/modules/api/homeassistant.sh"
|
||||
# shellcheck source=base/rootfs/usr/lib/hassio-addons/modules/api/host.sh
|
||||
|
@ -72,8 +74,8 @@ hass.api.call() {
|
|||
|
||||
hass.log.debug "Requested API resource: ${HASS_API_ENDPOINT}${resource}"
|
||||
hass.log.debug "API HTTP Response code: ${status}"
|
||||
hass.log.debug "API Response: ${response}"
|
||||
|
||||
hass.log.debug "API Response: ${response}"
|
||||
|
||||
if [[ "${status}" -eq 401 ]]; then
|
||||
hass.log.error "Unable to authenticate with the API, permission denied"
|
||||
return "${EX_NOK}"
|
||||
|
|
|
@ -400,20 +400,6 @@ hass.api.addons.info.privileged() {
|
|||
hass.api.addons.info "${addon}" ".privileged // empty"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the current seccomp state of this add-on
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Add-on slug
|
||||
# Returns:
|
||||
# Seccomp state: disable, default or profile
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.addons.info.seccomp() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.addons.info "${addon}" ".seccomp"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the current apparmor state of this add-on
|
||||
#
|
||||
|
@ -568,6 +554,34 @@ hass.api.addons.info.gpio() {
|
|||
hass.api.addons.info "${addon}" ".gpio // false"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns whether or not this add-on can access the devicetree
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Add-on slug
|
||||
# Returns:
|
||||
# Whether or not this add-on can access the devicetree
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.addons.info.devicetree() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.addons.info "${addon}" ".devicetree // false"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns whether or not this add-on can access the Docker socket
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Add-on slug
|
||||
# Returns:
|
||||
# Whether or not this add-on can access the Docker socket
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.addons.info.docker_api() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.addons.info "${addon}" ".docker_api // false"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns whether or not this add-on can access an audio device
|
||||
#
|
||||
|
@ -638,34 +652,6 @@ hass.api.addons.info.discovery() {
|
|||
hass.api.addons.info "${addon}" ".discovery // empty"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Install an add-on onto your Hass.io instance
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Add-on slug
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.addons.install() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call POST "/addons/${addon}/install"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Uninstall an add-on from your Hass.io instance
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Add-on slug
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.addons.uninstall() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call POST "/addons/${addon}/uninstall"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Starts an add-on
|
||||
#
|
||||
|
@ -695,17 +681,31 @@ hass.api.addons.stop() {
|
|||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Restarts an add-on
|
||||
# Install an add-on onto your Hass.io instance
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Add-on slug
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.addons.restart() {
|
||||
hass.api.addons.install() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call POST "/addons/${addon}/restart"
|
||||
hass.api.call POST "/addons/${addon}/install"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Uninstall an add-on from your Hass.io instance
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Add-on slug
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.addons.uninstall() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call POST "/addons/${addon}/uninstall"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -722,20 +722,6 @@ hass.api.addons.update() {
|
|||
hass.api.call POST "/addons/${addon}/update"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Rebuilds an add-on locally
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Add-on slug
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.addons.rebuild() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call POST "/addons/${addon}/rebuild"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the logs created by an add-on
|
||||
#
|
||||
|
@ -750,6 +736,34 @@ hass.api.addons.logs() {
|
|||
hass.api.call GET "/addons/${addon}/logs" true
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Restarts an add-on
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Add-on slug
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.addons.restart() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call POST "/addons/${addon}/restart"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Rebuilds an add-on locally
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Add-on slug
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.addons.rebuild() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call POST "/addons/${addon}/rebuild"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Checks if there is an update available for an add-on
|
||||
#
|
||||
|
@ -815,7 +829,7 @@ hass.api.addons.stats.cpu_percent() {
|
|||
hass.api.addons.stats.memory_usage() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.addons.stats "${addon}" ".memory_usage"
|
||||
hass.api.addons.stats "${addon}" ".memory_usage"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -829,7 +843,7 @@ hass.api.addons.stats.memory_usage() {
|
|||
hass.api.addons.stats.memory_limit() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.addons.stats "${addon}" ".memory_limit"
|
||||
hass.api.addons.stats "${addon}" ".memory_limit"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -843,7 +857,7 @@ hass.api.addons.stats.memory_limit() {
|
|||
hass.api.addons.stats.network_tx() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.addons.stats "${addon}" ".network_tx"
|
||||
hass.api.addons.stats "${addon}" ".network_tx"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -857,7 +871,7 @@ hass.api.addons.stats.network_tx() {
|
|||
hass.api.addons.stats.network_rx() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.addons.stats "${addon}" ".network_rx"
|
||||
hass.api.addons.stats "${addon}" ".network_rx"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -871,7 +885,7 @@ hass.api.addons.stats.network_rx() {
|
|||
hass.api.addons.stats.blk_read() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.addons.stats "${addon}" ".blk_read"
|
||||
hass.api.addons.stats "${addon}" ".blk_read"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -885,5 +899,5 @@ hass.api.addons.stats.blk_read() {
|
|||
hass.api.addons.stats.blk_write() {
|
||||
local addon=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.addons.stats "${addon}" ".blk_write"
|
||||
hass.api.addons.stats "${addon}" ".blk_write"
|
||||
}
|
||||
|
|
128
base/rootfs/usr/lib/hassio-addons/modules/api/hassos.sh
Normal file
128
base/rootfs/usr/lib/hassio-addons/modules/api/hassos.sh
Normal file
|
@ -0,0 +1,128 @@
|
|||
#!/usr/bin/env bash
|
||||
# ==============================================================================
|
||||
# Community Hass.io Add-ons: Bash functions library
|
||||
#
|
||||
# Provides access to the API functions of Hass.io: HassOS
|
||||
# ==============================================================================
|
||||
|
||||
# ==============================================================================
|
||||
# FUNCTIONS
|
||||
# ==============================================================================
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# List all available information about the HassOS host system
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# JSON object with HassOS information
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.hassos.info() {
|
||||
local filter=${1:-}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call GET /hassos/info false "${filter}"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the version of HassOS
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# Version
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.hassos.info.version() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.hassos.info ".version"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the CLI version of HassOS
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# CLI version
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.hassos.info.version_cli() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.hassos.info ".version_cli"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the latest version of HassOS
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# Latest version
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.hassos.info.version_latest() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.hassos.info ".version_latest"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the latest CLI version of HassOS
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# Latest CLI version
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.hassos.info.version_cli_latest() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.hassos.info ".version_cli_latest"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the board running HassOS
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# The board
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.hassos.info.board() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.hassos.info ".board"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Updates HassOS to the latest version
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.hassos.update() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.call POST /hassos/update
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Updates HassOS CLI to the latest version
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.hassos.update.cli() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.call POST /hassos/update/cli
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Load HassOS host configuration from USB stick
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.hassos.config.sync() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.call POST /hassos/config/sync
|
||||
}
|
|
@ -49,6 +49,19 @@ hass.api.homeassistant.info.last_version() {
|
|||
hass.api.homeassistant.info ".last_version"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the machine info runningHome Assistant
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# Machine
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.homeassistant.info.machine() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.homeassistant.info ".machine"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the Docker image of Home Assistant
|
||||
#
|
||||
|
@ -254,7 +267,7 @@ hass.api.homeassistant.stats.cpu_percent() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.homeassistant.stats.memory_usage() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.homeassistant.stats ".memory_usage"
|
||||
hass.api.homeassistant.stats ".memory_usage"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -267,7 +280,7 @@ hass.api.homeassistant.stats.memory_usage() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.homeassistant.stats.memory_limit() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.homeassistant.stats ".memory_limit"
|
||||
hass.api.homeassistant.stats ".memory_limit"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -280,7 +293,7 @@ hass.api.homeassistant.stats.memory_limit() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.homeassistant.stats.network_tx() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.homeassistant.stats ".network_tx"
|
||||
hass.api.homeassistant.stats ".network_tx"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -293,7 +306,7 @@ hass.api.homeassistant.stats.network_tx() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.homeassistant.stats.network_rx() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.homeassistant.stats ".network_rx"
|
||||
hass.api.homeassistant.stats ".network_rx"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -306,7 +319,7 @@ hass.api.homeassistant.stats.network_rx() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.homeassistant.stats.blk_read() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.homeassistant.stats ".blk_read"
|
||||
hass.api.homeassistant.stats ".blk_read"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -319,5 +332,5 @@ hass.api.homeassistant.stats.blk_read() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.homeassistant.stats.blk_write() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.homeassistant.stats ".blk_write"
|
||||
hass.api.homeassistant.stats ".blk_write"
|
||||
}
|
||||
|
|
|
@ -114,6 +114,19 @@ hass.api.host.info.deployment() {
|
|||
hass.api.host.info ".deployment"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the cpe of the system
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# Version
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.host.info.deployment() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.host.info ".cpe"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns the version of the software running on the host
|
||||
#
|
||||
|
@ -191,3 +204,58 @@ hass.api.host.reload() {
|
|||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.call POST /host/reload
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns host services
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# List of host services.
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.host.services() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.call GET /host/services false ".services[]"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Stops a host service
|
||||
#
|
||||
# Arguments:
|
||||
# $1 unit name
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.host.service.stop() {
|
||||
local unit=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call POST "/host/service/${unit}/stop"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Starts a host service
|
||||
#
|
||||
# Arguments:
|
||||
# $1 unit name
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.host.service.start() {
|
||||
local unit=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call POST "/host/service/${unit}/start"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Reloads a host service
|
||||
#
|
||||
# Arguments:
|
||||
# $1 unit name
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.host.service.reload() {
|
||||
local unit=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}" "$@"
|
||||
hass.api.call POST "/host/service/${unit}/reload"
|
||||
}
|
||||
|
|
|
@ -59,16 +59,16 @@ hass.api.supervisor.info.last_version() {
|
|||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Returns whether or not the Supervisor is on the beta channel
|
||||
# Returns the stability channel of the setup.
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# Whether or not the Supervisor is on the beta channel
|
||||
# The currently in use stability channel
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.api.supervisor.info.beta_channel() {
|
||||
hass.api.supervisor.info.channel() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.supervisor.info ".beta_channel // false"
|
||||
hass.api.supervisor.info ".channel // false"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -212,7 +212,7 @@ hass.api.supervisor.stats.cpu_percent() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.supervisor.stats.memory_usage() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.supervisor.stats ".memory_usage"
|
||||
hass.api.supervisor.stats ".memory_usage"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -225,7 +225,7 @@ hass.api.supervisor.stats.memory_usage() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.supervisor.stats.memory_limit() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.supervisor.stats ".memory_limit"
|
||||
hass.api.supervisor.stats ".memory_limit"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -238,7 +238,7 @@ hass.api.supervisor.stats.memory_limit() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.supervisor.stats.network_tx() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.supervisor.stats ".network_tx"
|
||||
hass.api.supervisor.stats ".network_tx"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -251,7 +251,7 @@ hass.api.supervisor.stats.network_tx() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.supervisor.stats.network_rx() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.supervisor.stats ".network_rx"
|
||||
hass.api.supervisor.stats ".network_rx"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -264,7 +264,7 @@ hass.api.supervisor.stats.network_rx() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.supervisor.stats.blk_read() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.supervisor.stats ".blk_read"
|
||||
hass.api.supervisor.stats ".blk_read"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -277,5 +277,5 @@ hass.api.supervisor.stats.blk_read() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.api.supervisor.stats.blk_write() {
|
||||
hass.log.trace "${FUNCNAME[0]}"
|
||||
hass.api.supervisor.stats ".blk_write"
|
||||
hass.api.supervisor.stats ".blk_write"
|
||||
}
|
||||
|
|
|
@ -30,6 +30,11 @@ hass.config.get() {
|
|||
return "${EX_OK}"
|
||||
fi
|
||||
|
||||
if hass.config.is_secret "${key}"; then
|
||||
hass.config.get_secret "${key}"
|
||||
return "${EX_OK}"
|
||||
fi
|
||||
|
||||
if hass.jq.is_string "${ADDON_CONFIG_PATH}" ".${key}"; then
|
||||
hass.jq "${ADDON_CONFIG_PATH}" ".${key} // empty"
|
||||
return "${EX_OK}"
|
||||
|
@ -49,16 +54,95 @@ hass.config.get() {
|
|||
|
||||
if hass.jq.is_object "${ADDON_CONFIG_PATH}" ".${key}"; then
|
||||
if hass.jq.has_value "${ADDON_CONFIG_PATH}" ".${key}"; then
|
||||
hass.jq "${ADDON_CONFIG_PATH}" ".${key}{}"
|
||||
hass.jq "${ADDON_CONFIG_PATH}" ".${key}[]"
|
||||
fi
|
||||
return "${EX_OK}"
|
||||
fi
|
||||
|
||||
|
||||
if hass.jq.is_number "${ADDON_CONFIG_PATH}" ".${key}"; then
|
||||
hass.jq "${ADDON_CONFIG_PATH}" ".${key}"
|
||||
return "${EX_OK}"
|
||||
fi
|
||||
|
||||
|
||||
return "${EX_NOK}"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Gets a configuration option value by getting it from secrets.yaml
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Key of the config option
|
||||
# Returns:
|
||||
# Value of the key in the referenced to the secrets file
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.config.get_secret() {
|
||||
local key=${1}
|
||||
local secret
|
||||
local value
|
||||
|
||||
hass.log.trace "${FUNCNAME[0]}:" "$@"
|
||||
|
||||
if ! hass.directory_exists "/config"; then
|
||||
hass.log.error "This add-on does not support secrets!"
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
if ! hass.file_exists "/config/secrets.yaml"; then
|
||||
hass.log.error "A secret was requested, but could not find a secrets.yaml"
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
if ! hass.config.is_secret "${key}"; then
|
||||
hass.log.error "The requested secret does not reference the secrets.yaml"
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
secret=$(hass.jq "${ADDON_CONFIG_PATH}" ".${key} // empty")
|
||||
secret="${secret#'!secret '}"
|
||||
|
||||
value=$(yq read "/config/secrets.yaml" "${secret}" )
|
||||
|
||||
if [[ "${value}" = "null" ]]; then
|
||||
hass.log.error "Secret ${secret} not found in secrets.yaml file."
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
echo "${value}"
|
||||
return "${EX_OK}"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Checks if a password is safe to use, using IHaveBeenPwned
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Key of the config option
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.config.is_safe_password() {
|
||||
local key=${1}
|
||||
local password
|
||||
|
||||
hass.log.trace "${FUNCNAME[0]}:" "$@"
|
||||
|
||||
# If the password is safe, we'll accept it anyways.
|
||||
password=$(hass.config.get "${key}")
|
||||
if hass.pwned.is_safe_password "${password}"; then
|
||||
return "${EX_OK}"
|
||||
fi
|
||||
|
||||
# If the bypass is not configured, we'll fail.
|
||||
if ! hass.config.exists "i_like_to_be_pwned"; then
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
# If the bypass is enabled, we'll return OK.
|
||||
if hass.config.true "i_like_to_be_pwned"; then
|
||||
hass.log.warning "Have I Been Pwned bypass enabled."
|
||||
return "${EX_OK}"
|
||||
fi
|
||||
|
||||
# If we reach this point, we'll just fail.
|
||||
return "${EX_NOK}"
|
||||
}
|
||||
|
||||
|
@ -78,6 +162,12 @@ hass.config.exists() {
|
|||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
if hass.config.is_secret "${key}" \
|
||||
&& ! hass.config.get_secret "${key}" > /dev/null;
|
||||
then
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
return "${EX_OK}"
|
||||
}
|
||||
|
||||
|
@ -91,12 +181,25 @@ hass.config.exists() {
|
|||
# ------------------------------------------------------------------------------
|
||||
hass.config.has_value() {
|
||||
local key=${1}
|
||||
local value
|
||||
hass.log.trace "${FUNCNAME[0]}:" "$@"
|
||||
|
||||
if ! hass.jq.has_value "${ADDON_CONFIG_PATH}" ".${key}"; then
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
if hass.config.is_secret "${key}"; then
|
||||
# Could not retrieve secret
|
||||
if ! value=$(hass.config.get_secret "${key}"); then
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
# Resolved secret does not contain a value
|
||||
if ! hass.has_value "${value}"; then
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
fi
|
||||
|
||||
return "${EX_OK}"
|
||||
}
|
||||
|
||||
|
@ -145,3 +248,28 @@ hass.config.false() {
|
|||
|
||||
return "${EX_NOK}"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Checks if a configuration option is refering to a secret
|
||||
#
|
||||
# Arguments:
|
||||
# $1 Key of the config option
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
hass.config.is_secret() {
|
||||
local key=${1}
|
||||
hass.log.trace "${FUNCNAME[0]}:" "$@"
|
||||
|
||||
if ! hass.jq.is_string "${ADDON_CONFIG_PATH}" ".${key}"; then
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
if [[
|
||||
"$(hass.jq "${ADDON_CONFIG_PATH}" ".${key} // empty")" != '!secret '*
|
||||
]]; then
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
return "${EX_OK}"
|
||||
}
|
||||
|
|
164
base/rootfs/usr/lib/hassio-addons/modules/pwned.sh
Normal file
164
base/rootfs/usr/lib/hassio-addons/modules/pwned.sh
Normal file
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env bash
|
||||
# ==============================================================================
|
||||
# Community Hass.io Add-ons: Bash functions library
|
||||
#
|
||||
# Provides interface with the password checks from HaveIBeenPwned.com
|
||||
# ==============================================================================
|
||||
|
||||
# ==============================================================================
|
||||
# GLOBALS
|
||||
# ==============================================================================
|
||||
readonly HIBP_ENDPOINT='https://api.pwnedpasswords.com/range'
|
||||
declare -A CACHE
|
||||
|
||||
# ==============================================================================
|
||||
# FUNCTIONS
|
||||
# ==============================================================================
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Checks if a given password is safe to use
|
||||
#
|
||||
# Arguments:
|
||||
# $1 The password to check
|
||||
# Returns:
|
||||
# None
|
||||
# ------------------------------------------------------------------------------
|
||||
function hass.pwned.is_safe_password () {
|
||||
local password="${1}"
|
||||
local occurances
|
||||
|
||||
hass.log.trace "${FUNCNAME[0]}" "<REDACTED PASSWORD>"
|
||||
|
||||
if ! occurances=$(hass.pwned.call "${password}"); then
|
||||
hass.log.warning "Could not check password, assuming it is safe."
|
||||
return "${EX_OK}"
|
||||
fi
|
||||
|
||||
if [[ "${occurances}" -ne 0 ]]; then
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
return "${EX_OK}"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Gets the number of occurances of the password in the list.
|
||||
#
|
||||
# Arguments:
|
||||
# $1 The password to check
|
||||
# Returns:
|
||||
# Number of occurance.
|
||||
# ------------------------------------------------------------------------------
|
||||
function hass.pwned.occurances() {
|
||||
local password="${1}"
|
||||
local occurances
|
||||
|
||||
hass.log.trace "${FUNCNAME[0]}" "<REDACTED PASSWORD>"
|
||||
|
||||
if ! occurances=$(hass.pwned.call "${password}"); then
|
||||
occurances="0"
|
||||
fi
|
||||
|
||||
echo "${occurances}"
|
||||
return "${EX_OK}"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Makes a call to the Have I Been Pwned password database
|
||||
#
|
||||
# Arguments:
|
||||
# $1 The password to check
|
||||
# Returns:
|
||||
# Number of occurances
|
||||
# ------------------------------------------------------------------------------
|
||||
function hass.pwned.call() {
|
||||
local password="${1}"
|
||||
local response
|
||||
local status
|
||||
local hibp_hash
|
||||
local count
|
||||
|
||||
hass.log.trace "${FUNCNAME[0]}" "${password//./x}"
|
||||
|
||||
# Do not check empty password
|
||||
if ! hass.has_value "${password}"; then
|
||||
hass.log.warning 'Cannot check empty password against HaveIBeenPwned.'
|
||||
return "${EX_OK}"
|
||||
fi
|
||||
|
||||
# Has the password
|
||||
password=$(echo -n "${password}" \
|
||||
| sha1sum \
|
||||
| tr '[:lower:]' '[:upper:]' \
|
||||
| awk -F' ' '{ print $1 }'
|
||||
)
|
||||
hass.log.debug "Password SHA1: ${password}"
|
||||
|
||||
# Check if response is cached
|
||||
if [[ "${CACHE[${password}]+isset}" ]]; then
|
||||
echo "${CACHE[${password}]}"
|
||||
return "${EX_OK}"
|
||||
fi
|
||||
|
||||
# Check with have I Been Powned, only send the first 5 chars of the hash
|
||||
if ! response=$(curl \
|
||||
--silent \
|
||||
--show-error \
|
||||
--write-out '\n%{http_code}' \
|
||||
--request GET \
|
||||
"${HIBP_ENDPOINT}/${password:0:5}"
|
||||
); then
|
||||
hass.log.debug "${response}"
|
||||
hass.log.error "Something went wrong contacting the HIBP API"
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
status=${response##*$'\n'}
|
||||
response=${response%$status}
|
||||
|
||||
hass.log.debug "Requested API resource: ${HIBP_ENDPOINT}/${password:0:5}"
|
||||
hass.log.debug "API HTTP Response code: ${status}"
|
||||
hass.log.trace "API Response: ${response}"
|
||||
|
||||
if [[ "${status}" -eq 429 ]]; then
|
||||
hass.log.error "HIBP Rate limit exceeded."
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
if [[ "${status}" -eq 503 ]]; then
|
||||
hass.log.error "HIBP Service unavailable."
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
if [[ "${status}" -ne 200 ]]; then
|
||||
hass.log.error "Unknown HIBP HTTP error occured."
|
||||
return "${EX_NOK}"
|
||||
fi
|
||||
|
||||
# Check the list of returned hashes for a match
|
||||
for hibp_hash in ${response}; do
|
||||
if [[ "${password:5:35}" == "${hibp_hash%%:*}" ]]; then
|
||||
# Found a match! This is bad :(
|
||||
count=$(echo "${hibp_hash#*:}" | tr -d '\r')
|
||||
|
||||
hass.log.warning \
|
||||
"Password is in the Have I Been Pwned database!"
|
||||
hass.log.warning \
|
||||
"Password appeared ${count} times!"
|
||||
echo "${count}"
|
||||
|
||||
# Store response in case it is asked again
|
||||
CACHE[${password}]="${count}"
|
||||
|
||||
# Well, at least the execution of this function succeeded.
|
||||
return "${EX_OK}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Password was not found
|
||||
echo "0"
|
||||
CACHE[${password}]="0"
|
||||
hass.log.info "Password is NOT in the Have I Been Pwned database! Nice!"
|
||||
|
||||
return "${EX_OK}"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue