tkInfra

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2026 License: MIT Imports: 45 Imported by: 3

README

Infrastructure

Infrastructure layer of Infinite Toolkit (TK). It implements I/O: file, shell, network, crypto, and database helpers, plus the repository implementations. It depends on the domain layer and never on presentation. Part of Infinite Toolkit.

Helpers

  • Deserializer: Deserialize JSON and YAML files into maps for configuration handling.

    deserializedMap, deserializationErr := StringDeserializer(
      `{"name": "test", "value": 123}`, SerializationFormatJson,
    )
    
    deserializedMap, deserializationErr := StringDeserializer(
      "name: test\nvalue: 123", SerializationFormatYaml,
    )
    
    deserializedMap, deserializationErr := FileDeserializer("config.json")
    
  • FileClerk: Perform file operations including existence checks, creation, copying, reading content, regex search and replace, atomic overwrite-rename, collision-safe temp file naming, symlink-safe directory listing and search, and symlink handling.

    clerk := FileClerk{}
    
    // ExistenceChecks
    isFileExists := clerk.FileExists("example.txt")
    isRegularFile := clerk.IsFile("example.txt")
    isDirectoryExists := clerk.IsDir("example_dir")
    isSymlink := clerk.IsSymlink("symlink.txt")
    isSymlinkToTarget := clerk.IsSymlinkTo("symlink.txt", "target.txt")
    
    // FileCreation
    fileCreationErr := clerk.TouchFile("example.txt")
    
    // FileContentOperations
    maxContentSize := int64(1024)
    fileContent, fileReadingErr := clerk.ReadFileContent("example.txt", &maxContentSize)
    regexSearchFilePath, regexSearchFilePathErr := tkValueObject.NewUnixAbsoluteFilePath("example.txt", false)
    regexPattern := regexp.MustCompile(`(?m)^error: (.+)$`)
    regexSearchFindings, regexSearchErr := clerk.FileContentRegexSearch(regexSearchFilePath, regexPattern)
    regexReplacement := `warn: $1`
    replacementCount, regexReplaceErr := clerk.FileContentRegexReplace(
      FileRegexReplaceSettings{FilePath: regexSearchFilePath},
      regexPattern, regexReplacement,
    )
    fileAppendErr := clerk.AppendFileContent(
      FileAppendSettings{FilePath: regexSearchFilePath}, "new content",
    )
    fileTruncationErr := clerk.TruncateFileContent(regexSearchFilePath)
    
    // DirectoryReading
    listDirPath, listDirPathErr := tkValueObject.NewUnixAbsoluteFilePath(
      "/var/www", false,
    )
    unixFiles, listDirErr := clerk.ListDir(FileListDirSettings{
      DirPath:  listDirPath,
      MaxDepth: 1,
    })
    namePattern := regexp.MustCompile(`\.conf$`)
    findStartingPathPattern, findStartingPathPatternErr := tkValueObject.NewUnixAbsoluteGlobPath(
      "/var/www/*/conf",
    )
    foundFiles, findErr := clerk.Find(FileFindSettings{
      StartingPathPattern: findStartingPathPattern,
      MaxDepth:            3,
      NamePattern:         namePattern,
    })
    
    // FileManipulation
    fileCopyErr := clerk.CopyFile("source.txt", "destination.txt")
    fileMoveErr := clerk.MoveFile("old.txt", "new.txt")
    fileOverwriteErr := clerk.OverwriteFile("source.tmp", "destination.txt")
    fileDeletionErr := clerk.DeleteFile("example.txt")
    
    // FileAdvancedOperations
    fileOwnershipUpdateErr := clerk.UpdateFileOwnership("example.txt", 1000, 1000)
    filePermissions := 0755
    filePermissionsUpdateErr := clerk.UpdateFilePermissions("example.txt", &filePermissions)
    ownerUsername, ownerUsernameErr := tkValueObject.NewUnixUsername("example")
    serviceFilePath, serviceFilePathErr := tkValueObject.NewUnixAbsoluteFilePath(
      "/home/example/.config/systemd/user/service.service", false,
    )
    serviceFilePermissions := os.FileMode(0644)
    fileUpsertErr := clerk.UpsertFile(FileUpsertSettings{
      FilePath:                 serviceFilePath,
      OverwritePolicy:          &FileClerkOverwritePolicyReplace,
      TrustedDirOwnerUsernames: []tkValueObject.UnixUsername{ownerUsername},
      Permissions:              &serviceFilePermissions,
      OwnerUsername:            &ownerUsername,
    }, []byte("unit content"))
    
    // CompressionOperations
    compressionFormat := "gzip"
    compressedFilePath, compressionErr := clerk.CompressFile(
      "example.txt", &compressionFormat,
    )
    decompressionTargetPath := "decompressed.txt"
    shouldKeepSourceFile := false
    decompressedFilePath, decompressionErr := clerk.DecompressFile(
      "example.txt.tar", &decompressionTargetPath, &shouldKeepSourceFile,
    )
    
    // DirectoryOperations
    directoryCreationErr := clerk.CreateDir("example_dir")
    directoryCopyErr := clerk.CopyDir("source_dir", "dest_dir")
    directoryMoveErr := clerk.MoveDir("old_dir", "new_dir")
    directoryDeletionErr := clerk.DeleteDir("example_dir")
    directoryCompressionFormat := "brotli"
    directoryCompressionErr := clerk.CompressDir(
      "example_dir", &directoryCompressionFormat,
    )
    directoryDecompressionTargetPath := "decompressed_dir"
    shouldKeepSourceDir := true
    directoryDecompressionErr := clerk.DecompressDir(
      "example_dir.tar", &directoryDecompressionTargetPath, &shouldKeepSourceDir,
    )
    
    // SymlinkOperations
    shouldOverwriteSymlink := false
    symlinkCreationErr := clerk.CreateSymlink(
      "target.txt", "symlink.txt", shouldOverwriteSymlink,
    )
    symlinkRemovalErr := clerk.RemoveSymlink("symlink.txt")
    

    UpsertFile Notes

    UpsertFile writes through a held parent-directory handle and defaults to the safe policies: it refuses symlinked paths, refuses to replace an existing target, creates new files as FileClerkDefaultNewFileMode (0600), and inherits the target's mode and owner on replace. Callers opt in with FileClerkSymlinkPolicyResolve, FileClerkOverwritePolicyReplace, and a FileClerkOwnerSource; TrustedDirOwnerUsernames and TrustedDirOwnerUserIds name the trusted directory owners. Every parent component must be owned by root or by one of them (ErrDirectoryOwnerInvalid names the offending component). When the set is empty, the walk trusts the running process account and root. Name a third-party owner only when you trust it. DirChainPolicy defaults to FileClerkDirChainPolicySharedWriteAllowed; FileClerkDirChainPolicySharedWriteRefused also rejects any parent component that group or others can write, unless it is sticky (ErrDirectoryWritableByOthers). A stated owner wins over the existing-file source and conflicts with the other sources (ErrOwnerSourceConflict); a stated group or mode wins, and an omitted mode inherits the target or defaults to 0600 on create. A directory target fails with ErrTargetIsDirectory, and a process that cannot set the resolved owner fails with ErrFileOwnerChangeFailed.

    FileContentRegexReplace and AppendFileContent Notes

    FileContentRegexReplace takes FileRegexReplaceSettings and uses the same trust model as UpsertFile: it walks the parent directory chain through a held handle, opens the target through that handle, verifies the opened inode, and preserves the target's owner, group, and mode (special bits included). It refuses symlinks unless SymlinkPolicy resolves them. Empty files and directories are rejected. AppendFileContent verifies the opened inode and only appends to an existing file through an O_APPEND write, so the target's owner, group, and mode stay untouched and concurrent writers never lose data. A missing target fails with ErrFileMissing; create it with UpsertFile first. FileAppendSettings takes SymlinkPolicy, DirChainPolicy, TrustedDirOwnerUsernames, and TrustedDirOwnerUserIds.

    ListDir and Find Notes

    ListDir and Find read directory trees into []tkEntity.UnixFile entities. They use the same trust model as UpsertFile. The root directory chain is walked through held handles, so a path swap cannot redirect the read. Every opened subdirectory is checked against its inspected inode.

    MaxDepth 0 reads only the root's entries. MaxDepth N reads N levels of subdirectories. MaxFiles caps the returned entities and each directory read. A nil MaxFiles uses FileClerkDefaultMaxFiles (1000). A MaxFiles of 0 reads without a cap. A small cap truncates the result silently. Raise the cap, or pass 0, when the result must be complete.

    Find takes exactly one of two starting points. StartingPath (type UnixAbsoluteFilePath) is a single directory walked as-is. StartingPathPattern (type UnixAbsoluteGlobPath) accepts the glob wildcards *, ?, and [], for example /var/home/*/Downloads, and every directory it matches is walked. A wildcard pattern that matches nothing returns an empty result. A starting path that does not exist fails with ErrDirMissing. Paths that are not directories are skipped. A wildcard match that cannot be read is skipped and a warning names it; a starting path that is named directly fails with its read error. Setting both starting points fails with ErrStartingPathConflict; setting neither fails with ErrStartingPathMissing. A symlinked starting directory fails the search under the default policy; pass a resolving SymlinkPolicy to walk it. Find also takes an optional NamePattern regex. The regex matches the entry name, not the path. A nil NamePattern matches every entry. ListDir sorts by entry name and the path breaks ties. Find sorts by path. The MaxFiles cap counts across all matched starting directories.

    A symlinked root path is refused unless SymlinkPolicy resolves it. The walk reports an entry symlink and never descends into it.

    An entry that cannot become an entity is skipped and logged at debug level. This happens when the value object rejects the name, or when the owner or group has no account. An entry the walk cannot stat, or a subdirectory it cannot open, is skipped and a warning names it. A subdirectory removed during the walk is skipped and logged at debug level. A subdirectory replaced during the walk fails with ErrTargetFileChanged. A missing directory fails with ErrDirMissing.

  • Shell: Execute system commands with configurable user, timeout, environment variables, and output redirection to files.

    shell := NewShell(ShellSettings{
        Command: "echo",
        Args:    []string{"hello world"},
    })
    commandOutput, executionErr := shell.Run()
    fmt.Println(commandOutput)
    

    Set ExecutionTimeoutSecs for a relative timeout, ExecutionDeadline (an absolute UnixTime) for an absolute one, or both. When both are set, the earlier wins. When neither is set, the timeout is 1800 seconds. ShouldDisableTimeout overrides both fields and runs the command without any timeout. UnixTime has 1-second granularity, so a deadline built with NewUnixTimeAfterNow can land up to 1 second earlier than the requested duration. The shell honors the requested value, so a caller that passes an untrusted ExecutionTimeoutSecs must bound it.

    deadline := tkValueObject.NewUnixTimeAfterNow(4 * time.Hour)
    shell := NewShell(ShellSettings{
        Command:              "long-running-task",
        ExecutionTimeoutSecs: 5 * 3600,
        ExecutionDeadline:    &deadline,
    })
    
  • ShellEscape: Quote a string for safe interpolation into a POSIX shell command, or strip non-printable characters.

    escapedArg := ShellEscape{}.Quote("hello world")
    printableStr := ShellEscape{}.StripUnsafe("hello\x00world")
    
  • Synthesizer: Generate cryptographically secure random integers, passwords with charset guarantees, filler usernames/emails, private keys, and TLS certificates (including CA certificates).

    synthesizer := &Synthesizer{}
    
    randomInteger := synthesizer.RandomIntegerGenerator(1, 100)
    
    password := synthesizer.PasswordFactory(16, true)
    
    randomUsername := synthesizer.UsernameFactory()
    randomEmail := synthesizer.MailAddressFactory(nil)
    
    rsaKeyPem, rsaErr := synthesizer.PrivateKeyPemFactory(PrivateKeySettings{
      Algorithm: tkValueObject.PrivateKeyAlgorithmRSA,
      BitSize:   2048,
    })
    
    ecdsaKeyPem, ecdsaErr := synthesizer.PrivateKeyPemFactory(PrivateKeySettings{
      Algorithm: tkValueObject.PrivateKeyAlgorithmECDSA,
      BitSize:   256, // Supports 256, 384, 521
    })
    
    commonName, _ := tkValueObject.NewFqdn("goinfinite.net")
    aliasName, _ := tkValueObject.NewFqdn("goinfinite.com.br")
    altNames := []tkValueObject.Fqdn{aliasName}
    
    certPair, certGenErr := synthesizer.SelfSignedCertificatePairFactory(
      &commonName, altNames,
    )
    
    certPem, keyPem, certPemGenErr := synthesizer.SelfSignedCertificatePairPemFactory(
      &commonName, altNames,
    )
    
    certPem, keyPem, certErr := synthesizer.CertificatePemFactory(CertificateSettings{
      CommonName: &commonName,
      AltNames:   altNames,
    })
    
    maxPathLen := 2
    caCertPem, caKeyPem, caErr := synthesizer.CACertificatePemFactory(CertificateSettings{
      CommonName:       &commonName,
      MaxPathLengthPtr: &maxPathLen,
    })
    
  • ServerIpAddress: Retrieve the server's private and public IP addresses. The public IP read honors SERVER_PUBLIC_IP_ADDR as the primary source of truth before any HTTP lookup.

    privateIpAddress, privateIpReadingErr := ReadServerPrivateIpAddress()
    
    publicIpAddress, publicIpReadingErr := ReadServerPublicIpAddress()
    
  • DnsLookup: Perform DNS queries for various record types using custom resolvers with fallback support. Setting ShouldBypassLocalResolver: true skips Go's net.Resolver and issues raw dnsmessage UDP queries to bypass /etc/hosts and resolv.conf (applies to A/AAAA only).

    hostname, _ := tkValueObject.NewUnixHostname("example.com")
    dnsLookup := NewDnsLookup(DnsLookupSettings{
        ShouldBypassLocalResolver: true,
    })
    
    dnsRecords, lookupErr := dnsLookup.Execute(
        hostname, &tkValueObject.DnsRecordTypeA,
    )
    
  • TrustedCidrsReader: Parse comma-separated trusted entries from both TRUSTED_IPS and TRUSTED_CIDRS environment variables. Accepts plain IP addresses (converted to /32 for IPv4 and /128 for IPv6) and CIDR notation in either variable. Invalid entries are logged and skipped. Returns []CidrBlock.

    trustedCidrBlocks, trustedCidrsReadingErr := TrustedCidrsReader()
    
  • ReadThrough: Read-through utilities for TLS certificate pairs from CERTIFICATE_PAIR_CERT_PATH and CERTIFICATE_PAIR_KEY_PATH env vars, generating self-signed certificates in PKI_DIR if not provided.

    readThrough := &ReadThrough{}
    
    certFilePath, keyFilePath, certPairReadingErr := readThrough.CertPairFilePathsReader()
    
  • Cypher: Encrypt and decrypt strings using AES-GCM for authenticated encryption with base64 encoding.

    encodedSecretKey, keyGenerationErr := NewCypherSecretKey()
    
    cypher, cypherCreationErr := NewCypher(encodedSecretKey)
    
    encryptedText, encryptionErr := cypher.Encrypt("plain text")
    
    decryptedText, decryptionErr := cypher.Decrypt(encryptedText)
    
  • PaginationQueryBuilder: Build paginated database queries with support for page number, items per page, last seen ID, sorting, and total count.

    databaseQuery := db.Model(&YourModel{})
    
    requestPagination := tkDto.Pagination{
        PageNumber:   0,
        ItemsPerPage: 10,
    }
    
    paginatedQuery, responsePagination, paginationBuildingErr := PaginationQueryBuilder(
      databaseQuery, requestPagination, "",
    )
    
    modelRecords := []YourModel{}
    queryExecutionErr := paginatedQuery.Find(&modelRecords).Error
    
  • PaginationPagesTotalResolver: Compute the total page count from an item count and a page size. A zero page size fails with ErrItemsPerPageCannotBeZero; a count above uint32 fails with ErrPagesTotalOverflow. A partial page counts as a page.

    pagesTotal, pagesTotalErr := PaginationPagesTotalResolver(250, 20)
    
  • TrailDatabaseService: Initialize and migrate a SQLite trail database for activity records using GORM, configurable via TRAIL_DATABASE_FILE_PATH environment variable.

    os.Setenv("TRAIL_DATABASE_FILE_PATH", "/path/to/trail.db")
    
    trailDatabaseService, serviceInitializationErr := NewTrailDatabaseService(
      []any{&YourAdditionalModel{}},
    )
    
    activityRecords := []ActivityRecord{}
    trailDatabaseService.Handler.Model(&ActivityRecord{}).Find(&activityRecords)
    
  • TransientDatabaseService: Initialize a shared in-memory SQLite key-value store with Set, Read, and Has. Every instance in the process shares the same data, which vanishes when the process ends; Read returns ErrKeyNotFound for a missing key. Set accepts an optional time-to-live; pass nil to store an entry that never expires. Read and Has treat an expired entry as missing.

    transientDatabaseService, serviceInitializationErr := NewTransientDatabaseService()
    
    ttl := 5 * time.Minute
    setErr := transientDatabaseService.Set("key", "value", &ttl)
    
    value, readErr := transientDatabaseService.Read("key")
    
    keyExists := transientDatabaseService.Has("key")
    

Repositories

  • activityRecord/: GORM implementations of the domain ActivityRecordCmdRepo and ActivityRecordQueryRepo interfaces.

Documentation

Index

Constants

View Source
const (
	SerializationFormatJson = "json"
	SerializationFormatYaml = "yaml"
)
View Source
const (
	ReadThroughCertPairCertPathEnvVarName string = "CERTIFICATE_PAIR_CERT_PATH"
	ReadThroughCertPairKeyPathEnvVarName  string = "CERTIFICATE_PAIR_KEY_PATH"
	ReadThroughPkiDirEnvVarName           string = "PKI_DIR"
)
View Source
const (
	ShellExecutionTimeoutDefaultSecs uint64 = 1800
	ShellExecutionTimeoutGraceSecs   uint64 = 10
	ShellCommandTimeoutExitCode      int    = 124
)
View Source
const (
	CharsetLowercaseLetters string = "abcdefghijklmnopqrstuvwxyz"
	CharsetUppercaseLetters string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	CharsetNumbers          string = "0123456789"
	CharsetSymbols          string = "!@#$%^&*()_+"
)
View Source
const (
	TrustedIpsEnvVarName   string = "TRUSTED_IPS"
	TrustedCidrsEnvVarName string = "TRUSTED_CIDRS"
)
View Source
const CypherNewSecretKeyLength = 32
View Source
const (
	ServerPublicIpAddressEnvVarName string = "SERVER_PUBLIC_IP_ADDR"
)

Variables

View Source
var (
	ErrDnsLookupResponseIdMismatch       = errors.New("DnsLookupResponseIdMismatch")
	ErrDnsLookupResponseNotResponse      = errors.New("DnsLookupResponseNotResponse")
	ErrDnsLookupResponseQuestionMismatch = errors.New("DnsLookupResponseQuestionMismatch")
	ErrDnsLookupResponseNameError        = errors.New("DnsLookupResponseNameError")
	ErrDnsLookupResponseServerFailure    = errors.New("DnsLookupResponseServerFailure")
	ErrDnsLookupResponseRefused          = errors.New("DnsLookupResponseRefused")
	ErrDnsLookupResponseUnknownRCode     = errors.New("DnsLookupResponseUnknownRCode")
	ErrDnsLookupResponseTruncated        = errors.New("DnsLookupResponseTruncated")
)
View Source
var (
	RegexLargeFileThresholdBytes       int64       = 10 * 1024 * 1024
	ReadFileContentDefaultMaxSizeBytes int64       = 500 * 1024 * 1024
	FileClerkDefaultNewFileMode        os.FileMode = 0o600
	FileClerkDefaultMaxFiles           uint64      = 1000

	FileClerkSymlinkPolicyStrictRefuse FileClerkSymlinkPolicy = "strict-refuse"
	FileClerkSymlinkPolicyResolve      FileClerkSymlinkPolicy = "resolve"

	// FileClerkDirChainPolicySharedWriteAllowed is the default policy.
	FileClerkDirChainPolicySharedWriteAllowed FileClerkDirChainPolicy = "shared-write-allowed"

	// FileClerkDirChainPolicySharedWriteRefused rejects a component that
	// is writable by group or others. A sticky component is allowed. The
	// rejection fails with ErrDirectoryWritableByOthers.
	FileClerkDirChainPolicySharedWriteRefused FileClerkDirChainPolicy = "shared-write-refused"

	FileClerkOverwritePolicyStrictRefuse FileClerkOverwritePolicy = "strict-refuse"
	FileClerkOverwritePolicyReplace      FileClerkOverwritePolicy = "replace"

	FileClerkOwnerSourceExistingFile        FileClerkOwnerSource = "existing-file"
	FileClerkOwnerSourceContainingDirectory FileClerkOwnerSource = "containing-directory"
	FileClerkOwnerSourceRunningProcess      FileClerkOwnerSource = "running-process"

	ErrSourceFileMissing            = errors.New("SourceFileNotFound")
	ErrTargetFileExists             = errors.New("TargetFileAlreadyExists")
	ErrFileMissing                  = errors.New("FileNotFound")
	ErrDirMissing                   = errors.New("DirNotFound")
	ErrGlobPatternInvalid           = errors.New("GlobPatternInvalid")
	ErrStartingPathMissing          = errors.New("StartingPathOrPatternMustBeSet")
	ErrStartingPathConflict         = errors.New("StartingPathConflictsWithStartingPathPattern")
	ErrFileEmpty                    = errors.New("FileEmpty")
	ErrReplacementWouldTruncateFile = errors.New("ReplacementWouldTruncateFile")
	ErrDirCompressionWrongFormat    = errors.New("DirectoryCompressionMustUseTarFormat")
	ErrCompressedFileMissing        = errors.New("CompressedFileNotFound")
	ErrSourceDirMissing             = errors.New("SourceDirNotFound")
	ErrTargetDirExists              = errors.New("TargetDirAlreadyExists")
	ErrSourcePathMissing            = errors.New("SourcePathNotFound")
	ErrSymlinkExists                = errors.New("SymlinkAlreadyExists")
	ErrTargetPathExists             = errors.New("TargetPathAlreadyExists")
	ErrRegexPatternMissing          = errors.New("RegexPatternCannotBeNil")
	ErrUnsupportedCompressionFormat = errors.New("UnsupportedCompressionFormat")
	ErrTargetIsDirectory            = errors.New("TargetIsDirectory")
	ErrSourceIsDirectory            = errors.New("SourceIsDirectory")
	ErrFileTooLarge                 = errors.New("FileTooLarge")
	ErrTargetIsSymlink              = errors.New("TargetIsSymlink")
	ErrTargetNotDirectory           = errors.New("TargetNotDirectory")
	ErrTargetNotRegularFile         = errors.New("TargetNotRegularFile")
	ErrDirPathTraversalInvalid      = errors.New("DirPathParentTraversalNotAllowed")
	ErrSymlinkedPathInvalid         = errors.New("PathComponentIsSymlink")
	ErrDirectoryOwnerInvalid        = errors.New("DirectoryNotOwnedByExpectedOwner")
	ErrDirectoryWritableByOthers    = errors.New("DirectoryWritableByOthers")
	ErrFileNameInvalid              = errors.New("FilePathFinalComponentIsNotAFileName")
	ErrTempFileNameTooLong          = errors.New("TempFileNameExceedsNameMax")
	ErrDirChainPolicyInvalid        = errors.New("DirChainPolicyInvalid")
	ErrSymlinkPolicyInvalid         = errors.New("SymlinkPolicyInvalid")
	ErrOverwritePolicyInvalid       = errors.New("OverwritePolicyInvalid")
	ErrOwnerSourceInvalid           = errors.New("OwnerSourceInvalid")
	ErrOwnerSourceConflict          = errors.New("OwnerSourceConflictsWithStatedOwner")
	ErrFileOwnerChangeFailed        = errors.New("FileOwnerChangeFailed")
	ErrTargetFileChanged            = errors.New("TargetFileChanged")
)

Functions

func FileDeserializer added in v0.0.2

func FileDeserializer(
	filePath string,
) (outputMap map[string]any, err error)

func IsStdoutTerminal added in v0.3.3

func IsStdoutTerminal() bool

IsStdoutTerminal is the single interactivity check shared by the CLI logger and response renderer. Both honor one contract: logs go to stderr, stdout carries the JSON response only, and a human at a terminal gets richer formatting. Both sides must agree or the response channel corrupts.

func NewCypherSecretKey added in v0.1.7

func NewCypherSecretKey() (string, error)

NewCypherSecretKey generates a cryptographically secure random 32-byte secret key, encodes it in base64 for safe storage and transmission, and returns it as a string. This key is suitable for AES-GCM encryption and should be kept confidential.

func ReadServerPrivateIpAddress added in v0.0.6

func ReadServerPrivateIpAddress() (ipAddress tkValueObject.IpAddress, err error)

func ReadServerPublicIpAddress added in v0.0.6

func ReadServerPublicIpAddress() (ipAddress tkValueObject.IpAddress, err error)

func StringDeserializer added in v0.0.2

func StringDeserializer(
	serializedString string,
	serializationFormat string,
) (outputMap map[string]any, err error)

func TrustedCidrsReader added in v0.2.7

func TrustedCidrsReader() (trustedCidrBlocks []tkValueObject.CidrBlock, err error)

Types

type CertificateSettings added in v0.2.0

type CertificateSettings struct {
	CommonName           *tkValueObject.Fqdn
	AltNames             []tkValueObject.Fqdn
	IsCA                 bool
	MaxPathLengthPtr     *int
	HasMaxPathLengthZero bool
}

type Cypher added in v0.1.7

type Cypher struct {
	// contains filtered or unexported fields
}

func NewCypher added in v0.1.7

func NewCypher(encodedSecretKey string) (*Cypher, error)

NewCypher creates a new Cypher instance with the provided base64-encoded secret key. The key must be a valid base64 string that decodes to exactly 16, 24, or 32 bytes for AES encryption. Use NewCypherSecretKey to generate a suitable key if needed. Returns an error if the key is invalid, providing fail-fast validation.

func (*Cypher) Decrypt added in v0.1.7

func (cypher *Cypher) Decrypt(encryptedText string) (plainText string, err error)

func (*Cypher) Encrypt added in v0.1.7

func (cypher *Cypher) Encrypt(plainText string) (encryptedText string, err error)

type DnsLookup added in v0.1.8

type DnsLookup struct {
	// contains filtered or unexported fields
}

func NewDnsLookup added in v0.1.8

func NewDnsLookup(settings DnsLookupSettings) *DnsLookup

func (*DnsLookup) Execute added in v0.1.8

func (lookup *DnsLookup) Execute(
	hostname tkValueObject.UnixHostname,
	recordType *tkValueObject.DnsRecordType,
) ([]string, error)

type DnsLookupSettings added in v0.2.9

type DnsLookupSettings struct {
	PrimaryResolver           tkValueObject.IpAddress
	SecondaryResolver         tkValueObject.IpAddress
	QueryTimeoutSecs          uint
	DialTimeoutMs             uint
	ShouldBypassLocalResolver bool
}

type FileAppendSettings added in v0.3.5

type FileAppendSettings struct {
	FilePath tkValueObject.UnixAbsoluteFilePath

	DirChainPolicy *FileClerkDirChainPolicy
	SymlinkPolicy  *FileClerkSymlinkPolicy

	// When empty, the running process account is trusted. Root is
	// always trusted.
	TrustedDirOwnerUsernames []tkValueObject.UnixUsername
	TrustedDirOwnerUserIds   []tkValueObject.UnixUserId
}

type FileClerk added in v0.0.7

type FileClerk struct{}

func (FileClerk) AppendFileContent added in v0.3.4

func (clerk FileClerk) AppendFileContent(
	settings FileAppendSettings,
	content string,
) error

AppendFileContent appends through an O_APPEND write, so concurrent writers never lose data. The target keeps its owner, group, and mode. A swap during the append fails with ErrTargetFileChanged. A missing target fails with ErrFileMissing. Create it with UpsertFile. Symlinks are refused unless the policy resolves them.

func (FileClerk) CompressDir added in v0.0.7

func (clerk FileClerk) CompressDir(
	sourcePath string,
	compressionFormatPtr *string,
) (compressedFilePath string, err error)

func (FileClerk) CompressFile added in v0.0.7

func (clerk FileClerk) CompressFile(
	sourcePath string,
	compressionFormatPtr *string,
	shouldKeepSourceFilePtr *bool,
) (compressedFilePath string, err error)

func (FileClerk) CopyDir added in v0.0.7

func (clerk FileClerk) CopyDir(sourcePath, targetPath string) error

func (FileClerk) CopyFile added in v0.0.7

func (clerk FileClerk) CopyFile(sourcePath, targetPath string) error

func (FileClerk) CreateDir added in v0.0.7

func (clerk FileClerk) CreateDir(dirPath string) error
func (clerk FileClerk) CreateSymlink(
	sourcePath, targetPath string,
	shouldOverwrite bool,
) error

func (FileClerk) DecompressDir added in v0.0.7

func (clerk FileClerk) DecompressDir(
	sourcePath string,
	targetPathPtr *string,
	shouldKeepSourceFilePtr *bool,
) (decompressedDirPath string, err error)

func (FileClerk) DecompressFile added in v0.0.7

func (clerk FileClerk) DecompressFile(
	sourcePath string,
	targetPathPtr *string,
	shouldKeepSourceFilePtr *bool,
) (decompressedFilePath string, err error)

DecompressFile expands sourcePath and removes the archive unless shouldKeepSourceFilePtr requests otherwise. Zip extraction overwrites existing files without warning. Only decompress archives you trust.

func (FileClerk) DeleteDir added in v0.0.7

func (FileClerk) DeleteDir(dirPath string) error

func (FileClerk) DeleteFile added in v0.0.7

func (FileClerk) DeleteFile(filePath string) error

func (FileClerk) FileContentRegexReplace added in v0.3.0

func (clerk FileClerk) FileContentRegexReplace(
	settings FileRegexReplaceSettings,
	regexPattern *regexp.Regexp,
	replacement string,
) (replacementCount int, err error)

FileContentRegexReplace atomically substitutes regex matches. The target keeps its owner, group, and mode, including special bits. A swap during the operation fails with ErrTargetFileChanged. Symlinks are refused unless the policy resolves them. A zero-byte result fails with ErrReplacementWouldTruncateFile. Use TruncateFileContent to empty a file. Files at or above the large-file threshold stream line by line, so a multi-line pattern needs a smaller file.

func (FileClerk) FileContentRegexSearch added in v0.2.9

func (clerk FileClerk) FileContentRegexSearch(
	filePath tkValueObject.UnixAbsoluteFilePath,
	regexPattern *regexp.Regexp,
) (regexSearchFindings []FileContentRegexFindings, err error)

FileContentRegexSearch finds every regex match in a file. Each result has capture groups and a 1-based inclusive line range. Use the (?m) flag for per-line anchors. Files at or above RegexLargeFileThresholdBytes stream line by line, so a multi-line pattern matches within one line only.

func (FileClerk) FileExists added in v0.0.7

func (FileClerk) FileExists(filePath string) bool

func (FileClerk) Find added in v0.4.0

func (clerk FileClerk) Find(
	settings FileFindSettings,
) (unixFiles []tkEntity.UnixFile, err error)

Find walks every directory that StartingPath or StartingPathPattern matches. It returns UnixFile entities sorted by path. The starting directory is not in the results. Exactly one of the two starting points must be set. A missing starting path fails with ErrDirMissing. A wildcard that matches nothing returns an empty result. Non-directories are skipped. A wildcard match that cannot be read is skipped with a warning. A directly named path fails with its read error. NamePattern matches the entry name. A nil NamePattern matches every entry. MaxFiles 0 reads without a cap. The cap counts across all matched starting directories. An unreadable entry is skipped with a warning. A subdirectory replaced mid-walk fails with ErrTargetFileChanged.

func (FileClerk) IsDir added in v0.0.7

func (clerk FileClerk) IsDir(filePath string) bool

func (FileClerk) IsFile added in v0.0.7

func (clerk FileClerk) IsFile(filePath string) bool
func (FileClerk) IsSymlink(sourcePath string) bool

func (FileClerk) IsSymlinkTo added in v0.0.7

func (clerk FileClerk) IsSymlinkTo(sourcePath, targetPath string) bool

func (FileClerk) ListDir added in v0.4.0

func (clerk FileClerk) ListDir(
	settings FileListDirSettings,
) (unixFiles []tkEntity.UnixFile, err error)

ListDir reads a directory tree into UnixFile entities sorted by entry name. The path breaks ties. MaxDepth 0 reads only the root's entries. MaxDepth N reads N levels of subdirectories. MaxFiles 0 reads without a cap. A small MaxFiles truncates silently. An unreadable entry is skipped with a warning. A subdirectory replaced mid-walk fails with ErrTargetFileChanged.

func (FileClerk) MoveDir added in v0.0.7

func (clerk FileClerk) MoveDir(sourcePath, targetPath string) error

func (FileClerk) MoveFile added in v0.0.7

func (clerk FileClerk) MoveFile(sourcePath, targetPath string) error

MoveFile never replaces an existing target. Cross-device moves fall back to copy and delete. An interrupted run leaves a partial target next to an untouched source.

func (FileClerk) OverwriteFile added in v0.3.0

func (clerk FileClerk) OverwriteFile(sourcePath, targetPath string) error

OverwriteFile atomically replaces the underlying file of targetPath with the content of sourcePath. Symlink targets are written through. The original file and every other reference stay in place.

func (FileClerk) ReadFileContent added in v0.0.7

func (clerk FileClerk) ReadFileContent(
	filePath string,
	maxContentSizeBytesPtr *int64,
) (fileContent string, err error)
func (FileClerk) RemoveSymlink(symlinkPath string) error

func (FileClerk) TempFileNameFactory added in v0.3.4

func (FileClerk) TempFileNameFactory(
	targetFileName tkValueObject.UnixFileName,
) string

func (FileClerk) TempFilePathFactory added in v0.3.4

func (clerk FileClerk) TempFilePathFactory(
	targetFilePath tkValueObject.UnixAbsoluteFilePath,
) (string, error)

func (FileClerk) TouchFile added in v0.3.3

func (FileClerk) TouchFile(filePath string) error

TouchFile behaves like touch(1). A dangling symlink fails with ErrTargetIsSymlink instead of creating the file behind the link.

func (FileClerk) TruncateFileContent added in v0.0.7

func (FileClerk) TruncateFileContent(
	filePath tkValueObject.UnixAbsoluteFilePath,
) error

func (FileClerk) UpdateFileOwnership added in v0.0.7

func (clerk FileClerk) UpdateFileOwnership(
	filePath string,
	userId, groupId int,
) error

func (FileClerk) UpdateFilePermissions added in v0.0.7

func (FileClerk) UpdateFilePermissions(
	filePath string,
	permissionsPtr *os.FileMode,
) error

UpdateFilePermissions never chmods through a symlink. Unlike chmod(2), it requires read permission on the target. Root is exempt.

func (FileClerk) UpsertFile added in v0.3.4

func (clerk FileClerk) UpsertFile(
	settings FileUpsertSettings,
	fileContent []byte,
) error

func (FileClerk) WriteNewFile added in v0.3.3

func (clerk FileClerk) WriteNewFile(
	filePath, content string,
	permissions os.FileMode,
) error

type FileClerkDirChainPolicy added in v0.3.5

type FileClerkDirChainPolicy string

FileClerkDirChainPolicy selects how the directory-chain walk treats a component writable by group or others.

type FileClerkOverwritePolicy added in v0.3.5

type FileClerkOverwritePolicy string

type FileClerkOwnerSource added in v0.3.5

type FileClerkOwnerSource string

type FileClerkSymlinkPolicy added in v0.3.5

type FileClerkSymlinkPolicy string

type FileContentRegexFindings added in v0.3.0

type FileContentRegexFindings struct {
	Match        string
	Groups       []string
	LineNumRange []int
}

FileContentRegexFindings holds one regex match and its capture groups. LineNumRange is [start, end] inclusive. A single-line match has start == end.

type FileFindSettings added in v0.4.0

type FileFindSettings struct {
	StartingPath        tkValueObject.UnixAbsoluteFilePath
	StartingPathPattern tkValueObject.UnixAbsoluteGlobPath
	MaxDepth            uint16

	DirChainPolicy *FileClerkDirChainPolicy
	SymlinkPolicy  *FileClerkSymlinkPolicy

	TrustedDirOwnerUsernames []tkValueObject.UnixUsername
	TrustedDirOwnerUserIds   []tkValueObject.UnixUserId

	MaxFiles    *uint64
	NamePattern *regexp.Regexp
}

type FileListDirSettings added in v0.4.0

type FileListDirSettings struct {
	DirPath  tkValueObject.UnixAbsoluteFilePath
	MaxDepth uint16

	DirChainPolicy *FileClerkDirChainPolicy
	SymlinkPolicy  *FileClerkSymlinkPolicy

	TrustedDirOwnerUsernames []tkValueObject.UnixUsername
	TrustedDirOwnerUserIds   []tkValueObject.UnixUserId

	MaxFiles *uint64
}

type FileRegexReplaceSettings added in v0.3.5

type FileRegexReplaceSettings struct {
	FilePath tkValueObject.UnixAbsoluteFilePath

	DirChainPolicy *FileClerkDirChainPolicy
	SymlinkPolicy  *FileClerkSymlinkPolicy

	// When empty, the running process account is trusted. Root is
	// always trusted.
	TrustedDirOwnerUsernames []tkValueObject.UnixUsername
	TrustedDirOwnerUserIds   []tkValueObject.UnixUserId
}

type FileUpsertSettings added in v0.3.4

type FileUpsertSettings struct {
	FilePath tkValueObject.UnixAbsoluteFilePath

	DirChainPolicy  *FileClerkDirChainPolicy
	OverwritePolicy *FileClerkOverwritePolicy
	SymlinkPolicy   *FileClerkSymlinkPolicy

	// When empty, the running process account is trusted. Root is
	// always trusted.
	TrustedDirOwnerUsernames []tkValueObject.UnixUsername
	TrustedDirOwnerUserIds   []tkValueObject.UnixUserId

	Permissions *os.FileMode

	OwnerSource   *FileClerkOwnerSource
	OwnerUsername *tkValueObject.UnixUsername
	OwnerUserId   *tkValueObject.UnixUserId
	OwnerGroupId  *tkValueObject.UnixGroupId
}

type PrivateKeySettings added in v0.2.0

type PrivateKeySettings struct {
	Algorithm tkValueObject.PrivateKeyAlgorithm
	BitSize   int
}

type PublicIpAddressResolver added in v0.2.9

type PublicIpAddressResolver struct {
	// contains filtered or unexported fields
}

func NewPublicIpAddressResolver added in v0.2.9

func NewPublicIpAddressResolver() *PublicIpAddressResolver

func (*PublicIpAddressResolver) Resolve added in v0.2.9

func (resolver *PublicIpAddressResolver) Resolve() (
	ipAddress tkValueObject.IpAddress, err error,
)

type ReadThrough added in v0.1.0

type ReadThrough struct {
}

Provides methods for reading information that when not found, are generated on the fly.

func (*ReadThrough) CertPairFilePathsReader added in v0.1.0

func (rt *ReadThrough) CertPairFilePathsReader() (
	certPath tkValueObject.UnixAbsoluteFilePath,
	keyPath tkValueObject.UnixAbsoluteFilePath,
	err error,
)

Attempts to retrieve the certificate pair file paths from the environment variables "CERTIFICATE_PAIR_CERT_PATH" and "CERTIFICATE_PAIR_KEY_PATH", otherwise generates a self-signed certificate pair on local 'pki' directory (or the directory specified by the environment variable "PKI_DIR") and returns the absolute paths to the generated files.

type Shell added in v0.0.6

type Shell struct {
	// contains filtered or unexported fields
}

func NewShell added in v0.0.6

func NewShell(settings ShellSettings) Shell

NewShell returns a value, not a pointer. Run copies the settings per call, so the sub-shell rewrite during preparation never compounds. A pointer receiver was rejected: it would leak that rewrite across calls and double-wrap the command on the second Run.

func (Shell) Run added in v0.0.6

func (shell Shell) Run() (stdoutStr string, err error)

type ShellError added in v0.0.6

type ShellError struct {
	StdErr   string `json:"stdErr"`
	ExitCode int    `json:"exitCode"`
}

func (*ShellError) Error added in v0.0.6

func (e *ShellError) Error() string

type ShellEscape added in v0.0.7

type ShellEscape struct {
}

func (ShellEscape) Quote added in v0.0.7

func (ShellEscape) Quote(inputStr string) string

func (ShellEscape) StripUnsafe added in v0.0.7

func (ShellEscape) StripUnsafe(inputStr string) string

type ShellSettings added in v0.0.6

type ShellSettings struct {
	Command                         string
	Args                            []string
	ShouldUseSubShell               bool
	ShouldUseCleanEnv               bool
	ShouldDisableTimeout            bool
	ShouldIgnoreUsernameLookupError bool
	Username                        string
	UserId                          *uint32
	WorkingDirectory                string
	ExecutionTimeoutSecs            uint64
	ExecutionDeadline               *tkValueObject.UnixTime
	Envs                            []string
	StdoutFilePath                  string
	StderrFilePath                  string
}

type Synthesizer

type Synthesizer struct{}

func (*Synthesizer) CACertificatePemFactory added in v0.2.0

func (synth *Synthesizer) CACertificatePemFactory(
	settings CertificateSettings,
) (certPem string, keyPem string, err error)

func (*Synthesizer) CertificatePemFactory added in v0.2.0

func (synth *Synthesizer) CertificatePemFactory(
	settings CertificateSettings,
) (certPem string, keyPem string, err error)

func (*Synthesizer) CharsetPresenceGuarantor

func (synth *Synthesizer) CharsetPresenceGuarantor(
	originalString []byte,
	charset string,
) []byte

func (*Synthesizer) MailAddressFactory

func (synth *Synthesizer) MailAddressFactory(username *string) string

func (*Synthesizer) PasswordFactory

func (synth *Synthesizer) PasswordFactory(
	desiredLength int,
	shouldIncludeSymbols bool,
) string

func (*Synthesizer) PrivateKeyPemFactory added in v0.2.0

func (synth *Synthesizer) PrivateKeyPemFactory(
	settings PrivateKeySettings,
) (keyPem string, err error)

func (*Synthesizer) RandomIntegerGenerator added in v0.3.4

func (synth *Synthesizer) RandomIntegerGenerator(
	lowestValue, highestValue int,
) int

func (*Synthesizer) SelfSignedCertificatePairFactory added in v0.1.0

func (synth *Synthesizer) SelfSignedCertificatePairFactory(
	commonName *tkValueObject.Fqdn,
	altNames []tkValueObject.Fqdn,
) (certPair tls.Certificate, err error)

func (*Synthesizer) SelfSignedCertificatePairPemFactory added in v0.1.0

func (synth *Synthesizer) SelfSignedCertificatePairPemFactory(
	commonName *tkValueObject.Fqdn,
	altNames []tkValueObject.Fqdn,
) (certPem string, keyPem string, err error)

func (*Synthesizer) UsernameFactory

func (synth *Synthesizer) UsernameFactory() string

Directories

Path Synopsis
db

Jump to

Keyboard shortcuts

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