예제 #1
0
        private async Task UpdateSecretsAsync(string thumbprintFromManifest, string x509StoreNameFromManifest, CancellationToken cancellationToken)
        {
            BackupRestoreTrace.TraceSource.WriteInfo(TraceType, String.Format("Updating secrets using the new thumbprint {0}", thumbprintFromManifest));
            using (var transaction = this.StateManager.CreateTransaction())
            {
                try
                {
                    var policyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this);

                    var workItemQueue = await WorkItemQueue.CreateOrGetWorkItemQueue(this);

                    var policies = await policyStore.GetValuesAsync(Common.Constants.StoreTimeOut, cancellationToken, transaction);

                    foreach (var policy in policies)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        var updatedStorage = this.UpdateSecretInStorage(policy.Storage, thumbprintFromManifest, x509StoreNameFromManifest, cancellationToken);
                        var newPolicy      = policy.ToBuilder()
                                             .WithBackupStorage(updatedStorage)
                                             .UpdateUniqueId()
                                             .Build();

                        if (!await policyStore.UpdateValueAsync(policy.Name, policy, newPolicy, Common.Constants.StoreTimeOut, cancellationToken, transaction))
                        {
                            throw new InvalidOperationException(String.Format("Failed to update secret for policy with name {0}", newPolicy.Name));
                        }

                        if (newPolicy.BackupEnabledSet.Count > 0)
                        {
                            await workItemQueue.AddWorkItem(
                                new UpdateEnablementWorkItem(newPolicy.BackupEnabledSet.ToList(),
                                                             new WorkItemInfo
                            {
                                WorkItemType = WorkItemPropogationType.UpdateBackupPolicy,
                                BackupPolicyUpdateGuid = newPolicy.UniqueId
                            }), Common.Constants.StoreTimeOut, cancellationToken, transaction);
                        }
                    }

                    // Update the config store
                    var configStore = await ConfigStore.CreateOrGetConfigStore(this);

                    await configStore.UpdateValueAsync(Common.Constants.SecretUpdateInProgress, String.Empty, Common.Constants.StoreTimeOut, cancellationToken, transaction);

                    await configStore.UpdateValueAsync(Common.Constants.EncryptionCertThumbprintKey, thumbprintFromManifest, Common.Constants.StoreTimeOut, cancellationToken, transaction);

                    await transaction.CommitAsync();

                    BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "All secrets updated with manifest {0}", thumbprintFromManifest);
                    FabricEvents.Events.BRSSecretsUpdated(TraceType, thumbprintFromManifest);
                }
                catch (Exception ex)
                {
                    BackupRestoreTrace.TraceSource.WriteExceptionAsWarning(TraceType, ex, "Exception encountered while updating secrets");
                    throw;
                }
            }
        }
예제 #2
0
        public async Task InitializeAsync()
        {
            // Read the state and update the config in the store and trigger update callback if needed

            // Check if the secret certificate has been updated or not
            // Get the current certificate from store
            string thumbprintFromManifest, x509StoreNameFromManifest;
            var    updateSecrets = false;
            var    configStore   = await ConfigStore.CreateOrGetConfigStore(this.statefulService);

            using (var transaction = this.statefulService.StateManager.CreateTransaction())
            {
                var val = await configStore.GetValueAsync(Common.Constants.SecretUpdateInProgress, transaction);

                // Check explicitly if the configured secret in manifest and the secret stored in ConfigStore are same or not
                var thumbprintFromStore = await configStore.GetValueAsync(Common.Constants.EncryptionCertThumbprintKey, transaction);

                // Initialize and fetch the thumbprint configured in manifest
                this.GetConfigFromNativeConfigStore(out thumbprintFromManifest, out x509StoreNameFromManifest);

                if (String.IsNullOrEmpty(val))
                {
                    if (String.IsNullOrEmpty(thumbprintFromManifest))
                    {
                        thumbprintFromManifest = null;
                    }

                    if (String.IsNullOrEmpty(thumbprintFromStore))
                    {
                        thumbprintFromStore = null;
                    }

                    // Thumbprint for encryption cert has changed, let's update secrets
                    if (!String.Equals(thumbprintFromManifest, thumbprintFromStore, StringComparison.InvariantCultureIgnoreCase))
                    {
                        BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "The existing and new thumprints dont match, existing {0}, new {1}, triggering secrets udpate", thumbprintFromStore, thumbprintFromManifest);
                        updateSecrets = true;
                    }
                }
                else
                {
                    BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Detected update in progress flag, triggering secrets update");
                    // There is an update in progress, let's update secrets
                    updateSecrets = true;
                }

                if (updateSecrets)
                {
                    // Set secret update in progress flag by setting some random guid value.
                    await configStore.UpdateValueAsync(Common.Constants.SecretUpdateInProgress, Guid.NewGuid().ToString(), transaction);
                }

                await transaction.CommitAsync();
            }

            lock (Lock)
            {
                EncryprtionCertThumprint = thumbprintFromManifest;
                EncryptionCertStoreName  = x509StoreNameFromManifest;
            }

            if (updateSecrets)
            {
                BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Invoking update cert callback");

                // Trigger the update secrets callback
                this.updateCertCallback(thumbprintFromManifest, x509StoreNameFromManifest, this.runAsyncCancellationToken);
            }
        }