Exemplo n.º 1
0
            public async Task <Result> Handle(Command message, CancellationToken cancellationToken)
            {
                using (var unit = await _context.Database.BeginTransactionAsync(cancellationToken))
                {
                    var jobId = await _context.Jobs
                                .Where(x => x.Jid == message.Jid)
                                .Select(x => (Guid?)x.Id)
                                .SingleOrDefaultAsync(cancellationToken);

                    var jobExists = jobId != null;
                    if (!jobExists)
                    {
                        Logger.Trace($"Job with a jid {message.Jid} has never been seen, it will be recorded.");

                        var job = new Job
                        {
                            Jid       = message.Jid,
                            Arguments = message.Arguments,
                            Function  = message.Function
                        };
                        _context.Jobs.Add(job);
                        await _context.SaveChangesAsync(cancellationToken);

                        jobId = job.Id;
                    }

                    unit.Commit();

                    return(new Result
                    {
                        JobId = jobId.Value
                    });
                }
            }
Exemplo n.º 2
0
            public async Task ProcessEvent(Command message)
            {
                Logger.Trace($"Processing job created event for jid {message.Jid}.");

                var job = await _mediator.Send(new JobSeen.Command
                {
                    Jid       = message.Jid,
                    Function  = message.Data.Function,
                    Arguments = message.Data.Arguments
                });

                using (var unit = await _context.Database.BeginTransactionAsync())
                {
                    var creationEvent = new JobCreationEvent
                    {
                        JobId          = job.JobId,
                        Minions        = message.Data.Minions,
                        MissingMinions = message.Data.Missing,
                        Targets        = message.Data.Target,
                        TargetType     = message.Data.TargetType,
                        User           = message.Data.User,
                        Timestamp      = message.Data.Timestamp
                    };
                    _context.JobCreationEvents.Add(creationEvent);
                    await _context.SaveChangesAsync();

                    unit.Commit();
                }

                Logger.Info($"Job {message.Jid} was committed.");
            }
Exemplo n.º 3
0
            public async Task <Result> Handle(Command message, CancellationToken cancellationToken)
            {
                Logger.Warn($"Got unknown tag {message.Tag} with {message.Data}.");

                _context.UnknownEvents.Add(new UnknownEvent
                {
                    Data = message.Data,
                    Tag  = message.Tag
                });
                await _context.SaveChangesAsync(cancellationToken);

                return(new Result());
            }
Exemplo n.º 4
0
            public async Task <Result> Handle(Command message, CancellationToken cancellationToken)
            {
                Logger.Info($"Attempting to update server settings with {message.Settings.Count} values.");

                var existingSettings
                    = message.Settings.Values
                      .Where(x => x.Version.HasValue)
                      .Select(x => new ServerSetting
                {
                    Key         = x.Key.ToLower(),
                    Value       = x.Value,
                    Version     = x.Version ?? 0,
                    LastUpdated = DateTimeOffset.Now
                })
                      .ToList();

                var newSettings
                    = message.Settings.Values
                      .Where(x => !x.Version.HasValue)
                      .Select(x => new ServerSetting
                {
                    Key         = x.Key.ToLower(),
                    Value       = x.Value,
                    LastUpdated = DateTimeOffset.Now
                })
                      .ToList();

                using (var unit = await _context.Database.BeginTransactionAsync(cancellationToken))
                {
                    _context.ServerSettings.AttachRange(existingSettings);
                    foreach (var existingSetting in existingSettings)
                    {
                        _context.Entry(existingSetting).Property(x => x.Value).IsModified       = true;
                        _context.Entry(existingSetting).Property(x => x.LastUpdated).IsModified = true;
                        _context.Entry(existingSetting).Property(x => x.Version).IsModified     = false;
                    }

                    _context.ServerSettings.AddRange(newSettings);

                    await _context.SaveChangesAsync(cancellationToken);

                    await _notify.Notify(ChannelConstants.ConfigurationChangedChannel, cancellationToken);

                    unit.Commit();
                }

                Logger.Info($"Successfully updated server settings, {existingSettings.Count} values updated, {newSettings.Count} values added.");

                return(new Result());
            }
Exemplo n.º 5
0
            public async Task <Result> Handle(Command message, CancellationToken cancellationToken)
            {
                using (var unit = await _context.Database.BeginTransactionAsync(cancellationToken))
                {
                    var task = new AdHocTask
                    {
                        Tag      = message.Tag,
                        Metadata = new Dictionary <string, string>
                        {
                            { "jid", message.Jid },
                            { "minions", string.Join(",", message.Minions) }
                        },
                        StartedOn = DateTimeOffset.Now,
                        Status    = BackgroundTaskStatus.Queued
                    };

                    _context.AdHocTasks.Add(task);
                    await _context.SaveChangesAsync(cancellationToken);

                    var taskId = task.Id;
                    Logger.Info($"Queuing monitoring of job {message.Jid}'s execution, tracking with task {taskId}.");

                    _jobClient.Enqueue <Handler>(x => x.Process(message, taskId));

                    unit.Commit();

                    await _mediator.PublishEvent($"v1:tasks:{taskId}:new",
                                                 ("taskId", taskId.ToString())
                                                 );

                    return(new Result
                    {
                        TaskId = taskId
                    });
                }
            }
Exemplo n.º 6
0
            public async Task ProcessEvent(Command message)
            {
                Logger.Info($"Processing authentication event for minion {message.Slug}.");

                var minionSeenResult = await _mediator.Send(new MinionSeen.Command
                {
                    Slug      = message.Slug,
                    Timestamp = message.Timestamp
                });

                var publicKeyHash = GetPublicKeyFingerprint(message.PublicKey);

                Logger.Debug($"Found public key fingerprint to be {publicKeyHash}.");

                using (var unit = await _context.Database.BeginTransactionAsync())
                {
                    var minion = await _context.Minions.FindAsync(minionSeenResult.MinionId);

                    minion.LastAuthentication = message.Timestamp;

                    var authEvent = new MinionAuthenticationEvent
                    {
                        MinionId      = minion.Id,
                        Action        = message.Action,
                        PublicKey     = message.PublicKey,
                        PublicKeyHash = publicKeyHash,
                        Success       = message.Success,
                        Timestamp     = message.Timestamp
                    };
                    _context.MinionAuthenticationEvents.Add(authEvent);

                    await _context.SaveChangesAsync();

                    unit.Commit();
                }

                await _mediator.PublishEvent(
                    $"v1:minions:{message.Slug}:authenticated",
                    ("minionId", message.Slug)
                    );

                Logger.Info("Processing authentication event for minion completed.");
            }
Exemplo n.º 7
0
            public async Task <Result> Handle(Command message, CancellationToken cancellationToken)
            {
                Logger.Trace($"Minion {message.Slug} seen at {message.Timestamp}.");

                using (var unit = await _context.Database.BeginTransactionAsync(cancellationToken))
                {
                    var minion = await _context.Minions
                                 .SingleOrDefaultAsync(x => x.MinionSlug == message.Slug, cancellationToken);

                    var minionDiscovered = minion == null;
                    if (minionDiscovered)
                    {
                        Logger.Info($"Minion {message.Slug} is unknown, it will be recorded.");
                        minion = new Minion
                        {
                            MinionSlug = message.Slug
                        };
                        _context.Minions.Add(minion);
                    }

                    minion.LastSeen = message.Timestamp;

                    await _context.SaveChangesAsync(cancellationToken);

                    unit.Commit();

                    if (minionDiscovered)
                    {
                        await _mediator.Publish(new MinionDiscovered.Notification
                        {
                            MinionSlug = message.Slug
                        }, cancellationToken);
                    }

                    return(new Result
                    {
                        MinionId = minion.Id
                    });
                }
            }
Exemplo n.º 8
0
            public async Task Process()
            {
                Logger.Info("Processing cleanup of grain generations.");

                using (var unit = await _context.Database.BeginTransactionAsync())
                {
                    var grainIds = await(from grain in _context.MinionGrains
                                         from minion in _context.Minions.Where(x => x.GrainGeneration == grain.Generation).DefaultIfEmpty()
                                         where minion == null
                                         select grain.Id).ToListAsync();

                    var grains = grainIds.Select(x => new MinionGrain
                    {
                        Id = x
                    });
                    _context.MinionGrains.RemoveRange(grains);
                    await _context.SaveChangesAsync();

                    unit.Commit();

                    Logger.Info($"Removed {grainIds.Count} grains from old generations.");
                }
            }
Exemplo n.º 9
0
        public async Task Process(JobReturnSaved.Notification notification)
        {
            Logger.Info($"Processing grains return for {notification.MinionReturnEventId}.");

            using (var unit = await _context.Database.BeginTransactionAsync())
            {
                var bulk = await(from returnEvent in _context.MinionReturnEvents.Where(x => x.Id == notification.MinionReturnEventId)
                                 let m = returnEvent.Minion
                                         select new
                {
                    ReturnEvent = returnEvent,
                    MinionId    = m.Id,
                    m.MinionSlug,
                    MinionVersion          = m.Version,
                    MinionLastGrainRefresh = m.LastGrainRefresh
                }).SingleOrDefaultAsync();

                var grainsAreStale = bulk.MinionLastGrainRefresh >= bulk.ReturnEvent.Timestamp;
                if (grainsAreStale)
                {
                    Logger.Info("Grain data is more stale than existing grain data, will ignore return event.");
                    return;
                }

                var minion = new Minion
                {
                    Id      = bulk.MinionId,
                    Version = bulk.MinionVersion
                };
                _context.Attach(minion);

                var generation = Guid.NewGuid();
                var grainsJson = bulk.ReturnEvent.ReturnData;
                var grains     = _jsonFlattener.Flatten(grainsJson);

                var minionGrains = grains.Select(x => new MinionGrain
                {
                    MinionId   = bulk.MinionId,
                    Generation = generation,
                    Path       = x.Key,
                    Values     = x.Value.ToList(),
                    Timestamp  = bulk.ReturnEvent.Timestamp
                }).ToList();

                var minionGrainValues = minionGrains.Select(
                    g => g.Values.Select(x => new MinionGrainValue
                {
                    MinionGrain = g,
                    Value       = x
                })
                    ).SelectMany(x => x);

                _context.MinionGrains.AddRange(minionGrains);
                _context.MinionGrainValues.AddRange(minionGrainValues);
                minion.GrainGeneration  = generation;
                minion.LastGrainRefresh = bulk.ReturnEvent.Timestamp;

                await _context.SaveChangesAsync();

                unit.Commit();

                Logger.Debug($"Commited {grains.Count} grains under generation {generation}.");

                await _mediator.PublishEvent(
                    $"v1:minions:{bulk.MinionSlug}:grains:updated",
                    ("minionId", bulk.MinionSlug)
                    );
            }
        }