Add "create" and "remove" events for secrets.

This commit adds the "secret" Event type and emits
"create" and "remove" events for this Event type
when Secret is created or removed.

This can be used for example by podman interfaces to
view and manage secrets.

Fixes: #24030

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
This commit is contained in:
Jan Kaluza
2025-02-28 11:04:36 +01:00
parent 350429cc3c
commit 20523152f8
8 changed files with 42 additions and 2 deletions

View File

@ -1522,7 +1522,7 @@ func AutocompleteEventFilter(cmd *cobra.Command, args []string, toComplete strin
}
eventTypes := func(_ string) ([]string, cobra.ShellCompDirective) {
return []string{events.Container.String(), events.Image.String(), events.Network.String(),
events.Pod.String(), events.System.String(), events.Volume.String(),
events.Pod.String(), events.System.String(), events.Volume.String(), events.Secret.String(),
}, cobra.ShellCompDirectiveNoFileComp
}
kv := keyValueCompletion{

View File

@ -79,6 +79,10 @@ The *volume* type reports the following statuses:
* prune
* remove
The *secret* type reports the following statuses:
* create
* remove
#### Verbose Create Events
Setting `events_container_create_inspect_data=true` in containers.conf(5) instructs Podman to create more verbose container-create events which include a JSON payload with detailed information about the containers. The JSON payload is identical to the one of podman-container-inspect(1). The associated field in journald is named `PODMAN_CONTAINER_INSPECT_DATA`.

View File

@ -191,6 +191,16 @@ func (v *Volume) newVolumeEvent(status events.Status) {
}
}
// NewSecretEvent creates a new event for a libpod secret
func (r *Runtime) NewSecretEvent(status events.Status, secretID string) {
e := events.NewEvent(status)
e.ID = secretID
e.Type = events.Secret
if err := r.eventer.Write(e); err != nil {
logrus.Errorf("Unable to write secret event: %q", err)
}
}
// Events is a wrapper function for everyone to begin tailing the events log
// with options
func (r *Runtime) Events(ctx context.Context, options events.ReadOptions) error {

View File

@ -131,6 +131,8 @@ const (
Volume Type = "volume"
// Machine - event is related to machine VM's
Machine Type = "machine"
// Secret - event is related to secrets
Secret Type = "secret"
// Attach ...
Attach Status = "attach"

View File

@ -92,6 +92,8 @@ func (e *Event) ToHumanReadable(truncate bool) string {
}
case Volume, Machine:
humanFormat = fmt.Sprintf("%s %s %s %s", e.Time, e.Type, e.Status, e.Name)
case Secret:
humanFormat = fmt.Sprintf("%s %s %s %s", e.Time, e.Type, e.Status, id)
}
return humanFormat
}
@ -133,6 +135,8 @@ func StringToType(name string) (Type, error) {
return System, nil
case Volume.String():
return Volume, nil
case Secret.String():
return Secret, nil
case "":
return "", ErrEventTypeBlank
}

View File

@ -173,7 +173,7 @@ func (e EventLogFile) Read(ctx context.Context, options ReadOptions) error {
continue
}
switch event.Type {
case Image, Volume, Pod, Container, Network:
case Image, Volume, Pod, Container, Network, Secret:
// no-op
case System:
begin, end, err := e.readRotateEvent(event)

View File

@ -11,6 +11,7 @@ import (
"strings"
"github.com/containers/common/pkg/secrets"
"github.com/containers/podman/v5/libpod/events"
"github.com/containers/podman/v5/pkg/domain/entities"
"github.com/containers/podman/v5/pkg/domain/utils"
)
@ -56,6 +57,8 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader
return nil, err
}
ic.Libpod.NewSecretEvent(events.Create, secretID)
return &entities.SecretCreateReport{
ID: secretID,
}, nil
@ -146,6 +149,9 @@ func (ic *ContainerEngine) SecretRm(ctx context.Context, nameOrIDs []string, opt
continue
}
reports = append(reports, &entities.SecretRmReport{Err: err, ID: deletedID})
if err == nil {
ic.Libpod.NewSecretEvent(events.Remove, deletedID)
}
}
return reports, nil

View File

@ -29,6 +29,13 @@ var _ = Describe("Podman secret", func() {
secrID := session.OutputToString()
Expect(session).Should(ExitCleanly())
result := podmanTest.Podman([]string{"events", "--stream=false"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
events := result.OutputToStringArray()
Expect(events).ToNot(BeEmpty(), "Number of events")
Expect(events).To(ContainElement(ContainSubstring(" secret create %s", secrID)))
inspect := podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.ID}}", secrID})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
@ -305,6 +312,13 @@ var _ = Describe("Podman secret", func() {
Expect(removed).Should(ExitCleanly())
Expect(removed.OutputToString()).To(Equal(secrID))
result := podmanTest.Podman([]string{"events", "--stream=false"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
events := result.OutputToStringArray()
Expect(events).ToNot(BeEmpty(), "Number of events")
Expect(events).To(ContainElement(ContainSubstring(" secret remove %s", secrID)))
session = podmanTest.Podman([]string{"secret", "ls"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())