cicada

package module
v0.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 15, 2024 License: BSD-2-Clause-Views Imports: 18 Imported by: 0

README

cicada: Long Term Support Analyzer

cicada molt

Shed your skin anew.

SUMMARY

cicada scans computers for software nearing the end of their support timelines. This helps everyone keep up with shifting market trends, adopting new capabilities and important security updates at a sustainable pace.

Our scans provide actionable results, which you can use to increase the security and reliability of your systems.

Other security tools act like canaries in the coal mine. But by the time the canary dies, it may be too late. cicada takes a different approach. cicada is active, not passive. It provides shrill warnings before the mine tumbles.

EXAMPLE

$ cicada
warning: end of life for ruby 2.6.8 on 2022-03-31
warning: end of life for ubuntu hirsute on 2022-01-20
warning: end of life for debian stretch on 2022-06-30

See cicada -help for more detail.

ABOUT

Many software components offer Long Term Support (LTS) releases, which receive security updates, bugfixes, and new features more rapidly than older releases. Unfortunately, it is often left up to the developer to opt into LTS releases. That is not an easy proposition, because software tends to grow in complexity over time. The dependency tree tends to get bigger and bigger. Meaning the risk of accidentally consuming a dead package is high. And the likelihood of spotting a dead package is low.

This is where cicada steps in. cicada helps engineers to identify more non-LTS software components. In an entirely automated fashion. cicada provides focused, actionable information for developers to implement. So that the larger software system remains robust, mature, and well supported by industry standards.

DOCUMENTATION

https://godoc.org/github.com/mcandre/cicada

DOWNLOAD

https://github.com/mcandre/cicada/releases

INSTALL FROM SOURCE

$ go install github.com/mcandre/cicada/cmd/cicada@latest

CONFIGURATION

See CONFIGURATION.md.

LICENSE

BSD-2-Clause

RUNTIME REQUIREMENTS

(None)

CONTRIBUTING

For more information about developing cicada itself, see DEVELOPMENT.md.

COMMON USAGE

Following classical UNIX conventions, cicada often emits no output of any kind, and returns zero exit status, in the case where no non-LTS components are identified. To see a list of supported versions that cicada identifies on your machine, you may run cicada -debug to show additional logs. cicada is designed to integrate easily into full linter suites for CI/CD usage. Especially for Docker image builds. With a simple tweak to your base images, you can unlock more productive, more predictable SDLC workflows.

Some false positives may arise from stock components. Critically, stock components are less open to taking action. Only a suitable operating system (OS) update can fully remove these old components. Yet, OS development cycles are particularly long on desktop and laptop workstations, even for users enthusiastic about applying all available updates. And so stock components may not represent actionable items; You may run cicada -quiet to skip them.

For hybrid host / Docker workflows, you may want to configure a local shell alias like alias cicada='cicada -quiet', in order to reduce noise. When running cicada during Docker builds, be advised to not apply -quiet mode, as components there are more eligible for resolution by way of updating the base image tag. It is much easier to replace a Docker base image OS than to replace a workstation OS.

For enterprise systems, a variety of tools are available to identify specific vulnerabilities. But by then, it may be too late to migrate and keep up with cyberattacks. This is why cicada takes a more aggressive approach. We want to ward off entire major versions of software that do not receive ongoing patches. So that we can be one step ahead of attackers.

cicada is future compatible: Any software components targeting developmental, git HEAD versions should not trigger false alarms. Maybe you're already consuming clang tip, for example, which is well ahead of the pack. For the rest of us, we can relax and enjoy stable, LTS releases. Rest well on islands of stability. Let cicada guide you to successful operation.

cicada can even scan direct parent base images in Dockerfiles in terms of FROM OS support timelines.

For a deeper level of scanning, run cicada inside your containers, VM's, or other pre-production environments. Such as part of a linter phase in a CI/CD pipeline.

Ultimately, how you use cicada is up to you. We try to strike a balance between comprehensiveness and practicality, so that you can tailor cicada to your team's particular needs.

SEE ALSO

  • dependabot scans GitHub repositories for vulnerabilities
  • endoflife.date for support lifetime data
  • npm scans Node.js projects for vulnerabilities
  • RubyGems scans Ruby projects for vulnerabilities
  • safety scans Python projects for vulnerabilities
  • Snyk scans software projects and Docker images for vulnerabilities

Documentation

Index

Constants

View Source
const DefaultLeadMonths = 1

DefaultLeadMonths provides additional time for engineers to implement version migrations prior to final end of life.

Not too short that developers fail to migrate, not too long that developers forget to migrate.

View Source
const EndOfLifeBaseURL = "https://endoflife.date/api"

EndOfLifeBaseURL denotes the base location of the endoflife.date service.

View Source
const IndexCacheBase = "cicada.yaml"

IndexCacheBase denotes the base path of the cached LTS index, relative to the current working directory.

For example, a software project top level directory.

View Source
const IndexCacheRoot = ".cicada"

IndexCacheRoot denotes the cicada metadata directory base path, relative to the home directory.

View Source
const IndexProductsDirBase = "products"

IndexProductsDirBase denotes the base path of the products directory, relative to IndexCacheRoot.

View Source
const IndexProductsListBase = "products.json"

IndexProductsListBase denotes the base path of the products list file, relative to IndexCacheRoot.

View Source
const IndexURL = "https://raw.githubusercontent.com/mcandre/cicada/main/cicada.yaml"

IndexURL denotes the location of the LTS index resource.

View Source
const ProductsListResourceBase = "all.json"

ProductsListResourceBase denotes the location of the products list resource.

View Source
const RFC3339DateFormat = "2006-01-02"

RFC3339DateFormat presents a prefix of the RFC3339 timestamp format.

View Source
const Version = "0.0.13"

Version is semver.

Variables

View Source
var DockerfileBaseImagePattern = regexp.MustCompile(`^FROM\s+((?P<registry>.+)/)?(?P<image>[^:\s]+)(:(?P<tag>[^\s]+))?(\s+as\s+(?P<stage>[^\s]+))?$`)

DockerfileBaseImagePattern extracts base image names from Dockerfiles.

View Source
var DockerfilePattern = regexp.MustCompile(`(Dockerfile.*)|(.*\.[Dd]ockerfile)`)

DockerfilePattern matches Docker image definition files.

View Source
var EnvironmentIsLinux bool = true
View Source
var Ignores = []string{
	".git",
	"vendor",
	"node_modules",
}

Ignores is a poor man's gitignore.

TODO: https://github.com/mcandre/stank/issues/1

View Source
var OperatingSystems = []string{
	"almalinux",
	"alpine",
	"amazon-linux",
	"android",
	"centos",
	"debian",
	"fedora",
	"freebsd",
	"iphone",
	"kindle",
	"linux",
	"linuxmint",
	"macos",
	"nixos",
	"openbsd",
	"opensuse",
	"rhel",
	"rocky-linux",
	"ros",
	"ubuntu",
	"windows",
	"windowsembedded",
	"windowsserver",
	"yocto",
}

OperatingSystems enumerates OS endoflife.date products.

View Source
var SemVerPattern = regexp.MustCompile(`^(?P<semver>[0-9]+(\.[0-9](\.[0-9])?)?).*$`)

SemVerPattern matches semantic versions.

View Source
var SystemPaths = []string{
	"/bin",
	"/usr/bin",
	"/usr/sbin",
	"/usr/share/bin",
	"/sbin",
	"c:\\Windows",
	"c:\\Windows\\system32",
	"c:\\Windows\\System32\\Wbem",
	"/mnt/c/Windows",
	"/mnt/c/Windows/system32",
	"/mnt/c/Windows/System32/Wbem",
}

SystemPaths documents common stock executable directories, which are eligible for skipping in quiet mode.

Functions

func CacheLifetimeData

func CacheLifetimeData(indexProductsListFilePath string, indexProductsDirPath string) error

CacheLifetimeData ensures a local copy of endoflife.date records.

func Clean

func Clean() error

Clean removes artifacts created during cicada runs.

func Ignore added in v0.0.10

func Ignore(pth string) bool

Ignore is a poor man's gitignore.

TODO: https://github.com/mcandre/stank/issues/1

func IndexCacheConfigPath

func IndexCacheConfigPath(cwd string) (*string, error)

IndexCacheConfigPath yields the location of the cicada configuration.

func IndexCacheDirPath

func IndexCacheDirPath(cwd string) (*string, error)

IndexCacheDirPath yields the location of cicada metadata directory.

func IsOperatingSystem added in v0.0.3

func IsOperatingSystem(product string) bool

IsOperatingSystem returns true for known OS endoflife.date products.

Otherwise, returns false.

func IsSystemExecutable added in v0.0.2

func IsSystemExecutable(executablePath string) bool

IsSystemExecutable returns true when the given executable path is a child of a system directory in SystemPaths.

Otherwise, returns false.

func RecognizeOs

func RecognizeOs() (*string, error)

RecognizeOs identifies the environment, as an endoflife.date product name.

func ScanComponent

func ScanComponent(name string, version *semver.Version, codename string, schedules []Schedule, t time.Time) *string

ScanComponent checks whether the given component is end of life.

Types

type DockerWarnings added in v0.0.10

type DockerWarnings struct {
	// Debug controls whether additional logging is enabled.
	Debug bool

	// Warninges denotes any dead base images.
	Warnings []string
	// contains filtered or unexported fields
}

func (*DockerWarnings) Walk added in v0.0.10

func (o *DockerWarnings) Walk(pth string, info os.FileInfo, err error) error

Walk is a callback for filepath.Walk to lint shell scripts.

type Dockerfile added in v0.0.10

type Dockerfile struct {
	Stages []string

	BaseImages []Image
}

type Image added in v0.0.10

type Image struct {
	Registry string

	Name string

	Tag string

	Stage string
}

Image models a Docker base image identifier.

func ExtractBaseImages added in v0.0.10

func ExtractBaseImages(pth string) ([]Image, error)

func (Image) String added in v0.0.10

func (o Image) String() string

String formats Docker image identifiers.

type Index

type Index struct {
	// Debug enables additional logging (default: false).
	Debug bool `json:"debug,omitempty" yaml:"debug,omitempty"`

	// Quiet skips system executables (default: false).
	Quiet bool `json:"quiet,omitempty" yaml:"quiet,omitempty"`

	// LeadMonths provides a margin of time to migrate
	// before a support timeline formally ends.
	//
	// Not too short that developers fail to migrate,
	// not too long that developers forget to migrate.
	//
	// Negative values are treated as a reset to default value.
	//
	// (default: 1)
	LeadMonths int `json:"lead_months,omitempty" yaml:"lead_months,omitempty"`

	// VersionQueries denotes command line queries for retrieving component versions, in exec-like format,
	// keyed on executable base path.
	VersionQueries map[string]VersionQuery `json:"version_queries" yaml:"version_queries"`
	// contains filtered or unexported fields
}

Index models a catalog of LTS schedules.

func Load

func Load(update bool) (*Index, error)

Load generates a partial LTS index.

func (Index) Scan

func (o Index) Scan() ([]string, error)

Scan generates reports.

func (Index) ScanApplication

func (o Index) ScanApplication(app string, schedules []Schedule, t time.Time) (*string, error)

ScanApplication checks executables for non-LTS versions.

If a semver cannot be queried, then the application is considered to not be installed.

func (Index) ScanApplications

func (o Index) ScanApplications(t time.Time) ([]string, error)

ScanApplications analyzes applications for any LTS concerns.

func (Index) ScanDockerfiles added in v0.0.10

func (o Index) ScanDockerfiles(t time.Time) ([]string, error)

func (Index) ScanKernel added in v0.0.12

func (o Index) ScanKernel(t time.Time) (*string, error)

ScanKernel analyzes certain operating system kernels for any LTS concerns.

func (Index) ScanOs

func (o Index) ScanOs(t time.Time) (*string, error)

ScanOs analyzes operating system for any LTS concerns.

func (Index) Validate

func (o Index) Validate() error

Validate ensures data integrity.

func (Index) ValidateVersionQueries

func (o Index) ValidateVersionQueries() error

ValidateVersionQueries ensures version query data integrity.

type ProductRecords

type ProductRecords []map[string]interface{}

ProductRecords models endoflife.date product detail records.

type Schedule

type Schedule struct {
	// Name denotes a software component:
	// Either a GOOS value or an executable base path.
	Name string `json:"name" yaml:"name"`

	// Codename denotes a version nickname.
	Codename string `json:"codename" yaml:"codename"`

	// Version denotes a software release series.
	// Only the major and minor are included in end of life calculations.
	// Zero minor is treated as matching any minor.
	Version semver.Version `json:"version" yaml:"version"`

	// Expiration denotes a termination timestamp.
	//
	// nil indicates no known expiration.
	//
	// (default: nil)
	Expiration *time.Time `json:"expiration,omitempty" yaml:"expiration,omitempty"`
}

Schedule models LTS series.

func ProductRecordsToSchedules

func ProductRecordsToSchedules(name string, records ProductRecords) ([]Schedule, error)

ProductRecordsToSchedules converts ProductRecords to Schedule arrays.

func (Schedule) MarshalYAML

func (o Schedule) MarshalYAML() (interface{}, error)

MarshalYAML encodes schedules.

func (Schedule) Match

func (o Schedule) Match(version *semver.Version, specificity int, codename string) bool

Match reports whether a schedule applies to the given software component version or codename.

specificity indicates the number of elements in the original v string.

For example, original version string "1" has specificity 1. Original version string "1.1" has specificity 2. Original version string "1.1.1" has specificity 3. And so on.

Note that degenerate versions may not necessarily behave as expected. For example, ".1" (corresponding with "0.1"), Or "1." (corresponding with "1.0").

func (*Schedule) UnmarshalYAML

func (o *Schedule) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML decodes schedules.

type VersionQuery

type VersionQuery struct {
	// Command denotes an exec-like command line instruction.
	//
	// Command output is always right trimmed.
	Command []string `yaml:"command"`

	// Pattern denotes an optional expression for
	// capturing version strings within
	// larger, complex output buffers.
	//
	// nil indicates the full command output,
	// sans right trim,
	// is treated as a semver version string.
	//
	// (default: nil)
	Pattern *regexp.Regexp `yaml:"pattern,omitempty"`
}

VersionQuery models commands for extracting software component version information.

func (VersionQuery) Execute

func (o VersionQuery) Execute() (*string, error)

Execute retrieves software component versions.

func (VersionQuery) MarshalYAML

func (o VersionQuery) MarshalYAML() (interface{}, error)

MarshalYAML encodes version queries.

func (*VersionQuery) UnmarshalYAML

func (o *VersionQuery) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML decodes version queries.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL