1
// Copyright 2016 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
4
// Package audit records auditable events
10
"github.com/juju/errors"
11
"github.com/juju/utils"
12
"github.com/juju/version"
15
// AuditEntrySinkFn defines a function which will send an
16
// AuditEntry to a backing store and return an error upon failure.
17
type AuditEntrySinkFn func(AuditEntry) error
19
// AuditEntry represents an auditted event.
20
type AuditEntry struct {
21
// JujuServerVersion is the version of the jujud that recorded
23
JujuServerVersion version.Number
24
// ModelUUID is the ID of the model the audit entry was written
27
// Timestamp is when the audit entry was generated. It must be
28
// stored with the UTC locale.
30
// RemoteAddress is the IP of the machine from which the
31
// audit-event was triggered.
33
// OriginType is the type of entity (e.g. model, user, action)
34
// which triggered the audit event.
36
// OriginName is the name of the origin which triggered the
39
// Operation is the operation that was performed that triggered
42
// Data is a catch-all for storing random data.
43
Data map[string]interface{}
46
// Validate ensures that the entry considers itself to be in a
47
// complete and valid state.
48
func (e AuditEntry) Validate() error {
49
if e.JujuServerVersion == version.Zero {
50
return errors.NewNotValid(errors.NotAssignedf("JujuServerVersion"), "")
52
if e.ModelUUID == "" {
53
return errors.NewNotValid(errors.NotAssignedf("ModelUUID"), "")
55
if utils.IsValidUUIDString(e.ModelUUID) == false {
56
return errors.NotValidf("ModelUUID")
58
if e.Timestamp.IsZero() {
59
return errors.NewNotValid(errors.NotAssignedf("Timestamp"), "")
61
if e.Timestamp.Location() != time.UTC {
62
return errors.NewNotValid(errors.NotValidf("Timestamp"), "must be set to UTC")
64
if e.RemoteAddress == "" {
65
return errors.NewNotValid(errors.NotAssignedf("RemoteAddress"), "")
67
if e.OriginType == "" {
68
return errors.NewNotValid(errors.NotAssignedf("OriginType"), "")
70
if e.OriginName == "" {
71
return errors.NewNotValid(errors.NotAssignedf("OriginName"), "")
73
if e.Operation == "" {
74
return errors.NewNotValid(errors.NotAssignedf("Operation"), "")
77
// Data remains unchecked as it is always optional.