feat(ansible): add blockinfile backups
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
2b12b8f860
commit
4387cab0cb
3 changed files with 58 additions and 2 deletions
|
|
@ -931,12 +931,24 @@ func moduleBlockinfileWithClient(_ *Executor, client sshFileRunner, args map[str
|
|||
marker := getStringArg(args, "marker", "# {mark} ANSIBLE MANAGED BLOCK")
|
||||
state := getStringArg(args, "state", "present")
|
||||
create := getBoolArg(args, "create", false)
|
||||
backup := getBoolArg(args, "backup", false)
|
||||
prependNewline := getBoolArg(args, "prepend_newline", false)
|
||||
appendNewline := getBoolArg(args, "append_newline", false)
|
||||
|
||||
beginMarker := replaceN(marker, "{mark}", "BEGIN", 1)
|
||||
endMarker := replaceN(marker, "{mark}", "END", 1)
|
||||
|
||||
var backupPath string
|
||||
if backup {
|
||||
before, hasBefore := mockRemoteFileText(client, path)
|
||||
if hasBefore {
|
||||
backupPath = sprintf("%s.%s.bak", path, time.Now().UTC().Format("20060102T150405Z"))
|
||||
if err := client.Upload(context.Background(), bytes.NewReader([]byte(before)), backupPath, 0600); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if state == "absent" {
|
||||
// Remove block
|
||||
cmd := sprintf("sed -i '/%s/,/%s/d' %q",
|
||||
|
|
@ -975,7 +987,12 @@ BLOCK_EOF
|
|||
return &TaskResult{Failed: true, Msg: stderr, Stdout: stdout, RC: rc}, nil
|
||||
}
|
||||
|
||||
return &TaskResult{Changed: true}, nil
|
||||
result := &TaskResult{Changed: true}
|
||||
if backupPath != "" {
|
||||
result.Data = map[string]any{"backup_file": backupPath}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func mockInsertLineRelativeToMatch(ctx context.Context, client commandRunner, path, line, insertBefore, insertAfter string, firstMatch bool) (bool, error) {
|
||||
|
|
|
|||
17
modules.go
17
modules.go
|
|
@ -2371,12 +2371,22 @@ func (e *Executor) moduleBlockinfile(ctx context.Context, client sshExecutorClie
|
|||
marker := getStringArg(args, "marker", "# {mark} ANSIBLE MANAGED BLOCK")
|
||||
state := getStringArg(args, "state", "present")
|
||||
create := getBoolArg(args, "create", false)
|
||||
backup := getBoolArg(args, "backup", false)
|
||||
prependNewline := getBoolArg(args, "prepend_newline", false)
|
||||
appendNewline := getBoolArg(args, "append_newline", false)
|
||||
|
||||
beginMarker := replaceN(marker, "{mark}", "BEGIN", 1)
|
||||
endMarker := replaceN(marker, "{mark}", "END", 1)
|
||||
|
||||
var backupPath string
|
||||
if backup {
|
||||
var hasBefore bool
|
||||
backupPath, hasBefore, _ = backupRemoteFile(ctx, client, path)
|
||||
if !hasBefore {
|
||||
backupPath = ""
|
||||
}
|
||||
}
|
||||
|
||||
if state == "absent" {
|
||||
// Remove block
|
||||
cmd := sprintf("sed -i '/%s/,/%s/d' %q",
|
||||
|
|
@ -2415,7 +2425,12 @@ BLOCK_EOF
|
|||
return &TaskResult{Failed: true, Msg: stderr, Stdout: stdout, RC: rc}, nil
|
||||
}
|
||||
|
||||
return &TaskResult{Changed: true}, nil
|
||||
result := &TaskResult{Changed: true}
|
||||
if backupPath != "" {
|
||||
result.Data = map[string]any{"backup_file": backupPath}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (e *Executor) moduleIncludeVars(args map[string]any) (*TaskResult, error) {
|
||||
|
|
|
|||
|
|
@ -705,6 +705,30 @@ func TestModulesFile_ModuleBlockinfile_Good_CreateFile(t *testing.T) {
|
|||
assert.True(t, mock.hasExecuted(`touch "/etc/new-config"`))
|
||||
}
|
||||
|
||||
func TestModulesFile_ModuleBlockinfile_Good_BackupExistingDest(t *testing.T) {
|
||||
e, mock := newTestExecutorWithMock("host1")
|
||||
mock.addFile("/etc/config", []byte("old block contents"))
|
||||
|
||||
result, err := moduleBlockinfileWithClient(e, mock, map[string]any{
|
||||
"path": "/etc/config",
|
||||
"block": "new block contents",
|
||||
"backup": true,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.True(t, result.Changed)
|
||||
require.NotNil(t, result.Data)
|
||||
|
||||
backupPath, ok := result.Data["backup_file"].(string)
|
||||
require.True(t, ok)
|
||||
assert.Contains(t, backupPath, "/etc/config.")
|
||||
assert.Equal(t, 1, mock.uploadCount())
|
||||
|
||||
backupContent, err := mock.Download(context.Background(), backupPath)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []byte("old block contents"), backupContent)
|
||||
}
|
||||
|
||||
func TestModulesFile_ModuleBlockinfile_Bad_MissingPath(t *testing.T) {
|
||||
e, mock := newTestExecutorWithMock("host1")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue