使用块有条件地设置选项

Set options conditionally with block

我正在构建一个模块,该模块提供一些使用 Fog gem 与 AWS CloudWatch 服务交互的功能。如果您不指定凭据,它将自动使用 ENV 中设置的任何内容或使用代码所在实例的 IAM 角色 运行。其他时候,我想明确传递凭证以访问其他 AWS 账户。这是一个示例 class 演示我希望它如何工作:

class MyAlarmGetter
  include CloudWatchClient

  default_account_alarms = get_all_alarms

  other_account_alarms = with_aws_credentials(account2) do
    get_all_alarms
  end

  def account2
    {
      aws_access_key_id: 'abc123',
      aws_secret_access_key: 'abc123'
    }
  end
end

到目前为止,这是模块的样子:

module CloudWatchClient
  def with_aws_credentials(creds)
    # Set credentials here!
    yield
  end

  def get_all_alarms
    cloud_watch_client.alarms.all
  end

  def cloud_watch_client(creds = ENV['FOG_CREDENTIAL'] ? {} : { use_iam_profile: true })
    Fog::AWS::CloudWatch.new(creds)
  end
end

我一直在想办法只覆盖 with_aws_credentials 块上下文中的默认凭据。

要支持这种接口,您可以将 creds 参数保存到实例变量中,例如@creds

module CloudWatchClient
  def with_aws_credentials(creds)
    # set given context
    @creds = creds

    result = yield

    # reset context
    @creds = nil

    result 
  end

  def get_all_alarms
    cloud_watch_client.alarms.all
  end

  def cloud_watch_client(creds = ENV['FOG_CREDENTIAL'] ? {} : { use_iam_profile: true })
    # check if context is given and use it
    creds = @creds || creds

    Fog::AWS::CloudWatch.new(creds)
  end
end

上面的代码只是一个示例,对您的代码进行了最少的调整。