Example #1
0
func (s *auditLogFileSuite) TestLogging(c *gc.C) {
	dir := c.MkDir()
	sink := audit.NewLogFileSink(dir)

	modelUUID := coretesting.ModelTag.Id()
	t0 := time.Date(2015, time.June, 1, 23, 2, 1, 0, time.UTC)
	t1 := time.Date(2015, time.June, 1, 23, 2, 2, 0, time.UTC)

	err := sink(audit.AuditEntry{
		Timestamp:     t0,
		ModelUUID:     modelUUID,
		RemoteAddress: "10.0.0.1",
		OriginType:    "API",
		OriginName:    "user-admin",
		Operation:     "deploy",
		Data:          map[string]interface{}{"foo": "bar"},
	})
	c.Assert(err, jc.ErrorIsNil)
	err = sink(audit.AuditEntry{
		Timestamp:     t1,
		ModelUUID:     modelUUID,
		RemoteAddress: "10.0.0.2",
		OriginType:    "API",
		OriginName:    "user-admin",
		Operation:     "status",
	})
	c.Assert(err, jc.ErrorIsNil)

	// Check that the audit log file was populated as expected
	logPath := filepath.Join(dir, "audit.log")
	logContents, err := ioutil.ReadFile(logPath)
	c.Assert(err, jc.ErrorIsNil)
	line0 := "2015-06-01 23:02:01," + modelUUID + ",10.0.0.1,user-admin,API,deploy,map[foo:bar]\n"
	line1 := "2015-06-01 23:02:02," + modelUUID + ",10.0.0.2,user-admin,API,status,map[]\n"
	c.Assert(string(logContents), gc.Equals, line0+line1)

	// Check the file mode is as expected. This doesn't work on
	// Windows (but this code is very unlikely to run on Windows so
	// it's ok).
	if runtime.GOOS != "windows" {
		info, err := os.Stat(logPath)
		c.Assert(err, jc.ErrorIsNil)
		c.Assert(info.Mode(), gc.Equals, os.FileMode(0600))
	}
}
Example #2
0
func newAuditEntrySink(st *state.State, logDir string) audit.AuditEntrySinkFn {
	persistFn := st.PutAuditEntryFn()
	fileSinkFn := audit.NewLogFileSink(logDir)
	return func(entry audit.AuditEntry) error {
		// We don't care about auditing anything but user actions.
		if _, err := names.ParseUserTag(entry.OriginName); err != nil {
			return nil
		}
		// TODO(wallyworld) - Pinger requests should not originate as a user action.
		if strings.HasPrefix(entry.Operation, "Pinger:") {
			return nil
		}
		persistErr := persistFn(entry)
		sinkErr := fileSinkFn(entry)
		if persistErr == nil {
			return errors.Annotate(sinkErr, "cannot save audit record to file")
		}
		if sinkErr == nil {
			return errors.Annotate(persistErr, "cannot save audit record to database")
		}
		return errors.Annotate(persistErr, "cannot save audit record to file or database")
	}
}