From 04145e58773d5a511ddff52f914eea2d4bc8b988 Mon Sep 17 00:00:00 2001 From: alpineriveredge Date: Mon, 4 Mar 2024 23:19:10 +0900 Subject: [PATCH] Add managed_prefix_list resource --- doc/_resource_types/managed_prefix_list.md | 32 +++++++++++ doc/resource_types.md | 46 +++++++++++++++- lib/awspec/command/generate.rb | 2 +- lib/awspec/generator.rb | 1 + .../generator/doc/type/managed_prefix_list.rb | 19 +++++++ .../generator/spec/managed_prefix_list.rb | 54 +++++++++++++++++++ lib/awspec/helper/finder/ec2.rb | 12 +++++ lib/awspec/helper/type.rb | 2 +- lib/awspec/matcher.rb | 3 ++ lib/awspec/matcher/have_cidr.rb | 11 ++++ lib/awspec/stub/managed_prefix_list.rb | 41 ++++++++++++++ lib/awspec/type/managed_prefix_list.rb | 34 ++++++++++++ .../spec/managed_prefix_list_spec.rb | 29 ++++++++++ spec/type/managed_prefix_list_spec.rb | 12 +++++ 14 files changed, 294 insertions(+), 4 deletions(-) create mode 100644 doc/_resource_types/managed_prefix_list.md create mode 100644 lib/awspec/generator/doc/type/managed_prefix_list.rb create mode 100644 lib/awspec/generator/spec/managed_prefix_list.rb create mode 100644 lib/awspec/matcher/have_cidr.rb create mode 100644 lib/awspec/stub/managed_prefix_list.rb create mode 100644 lib/awspec/type/managed_prefix_list.rb create mode 100644 spec/generator/spec/managed_prefix_list_spec.rb create mode 100644 spec/type/managed_prefix_list_spec.rb diff --git a/doc/_resource_types/managed_prefix_list.md b/doc/_resource_types/managed_prefix_list.md new file mode 100644 index 00000000..b102f5e3 --- /dev/null +++ b/doc/_resource_types/managed_prefix_list.md @@ -0,0 +1,32 @@ +### exist + +```ruby +describe managed_prefix_list('my-managed-prefix-list') do + it { should exist } +end +``` + +### have_cidr + +```ruby +describe managed_prefix_list('my-managed-prefix-list') do + it { should have_cidr('10.0.0.0/16') } + it { should have_cidr('192.168.0.0/24').desc('dev') } +end +``` + +### its(:entries_count) + +```ruby +describe managed_prefix_list('my-managed-prefix-list') do + its(:entries_count) { should eq 2 } +end +``` + +### have_tag + +```ruby +describe managed_prefix_list('my-managed-prefix-list') do + it { should have_tag('env').value('dev') } +end +``` diff --git a/doc/resource_types.md b/doc/resource_types.md index 9ff47f92..0bb3afb4 100644 --- a/doc/resource_types.md +++ b/doc/resource_types.md @@ -52,6 +52,7 @@ | [lambda](#lambda) | [launch_configuration](#launch_configuration) | [launch_template](#launch_template) +| [managed_prefix_list](#managed_prefix_list) | [mq](#mq) | [msk](#msk) | [nat_gateway](#nat_gateway) @@ -466,7 +467,7 @@ describe cloudformation_stack('my-cloudformation-stack') do end ``` -### its(:stack_id), its(:stack_name), its(:change_set_id), its(:description), its(:parameters), its(:creation_time), its(:deletion_time), its(:last_updated_time), its(:rollback_configuration), its(:stack_status), its(:stack_status_reason), its(:disable_rollback), its(:notification_arns), its(:timeout_in_minutes), its(:capabilities), its(:role_arn), its(:enable_termination_protection), its(:parent_id), its(:root_id), its(:drift_information), its(:retain_except_on_create) +### its(:stack_id), its(:stack_name), its(:change_set_id), its(:description), its(:parameters), its(:creation_time), its(:deletion_time), its(:last_updated_time), its(:rollback_configuration), its(:stack_status), its(:stack_status_reason), its(:disable_rollback), its(:notification_arns), its(:timeout_in_minutes), its(:capabilities), its(:role_arn), its(:enable_termination_protection), its(:parent_id), its(:root_id), its(:drift_information), its(:retain_except_on_create), its(:detailed_status) ## cloudfront_distribution CloudfrontDistribution resource type. @@ -2411,6 +2412,47 @@ end ``` ### its(:launch_template_id), its(:launch_template_name), its(:create_time), its(:created_by), its(:default_version_number), its(:latest_version_number), its(:tags) +## managed_prefix_list + +ManagedPrefixList resource type. + +### exist + +```ruby +describe managed_prefix_list('my-managed-prefix-list') do + it { should exist } +end +``` + + +### have_cidr + +```ruby +describe managed_prefix_list('my-managed-prefix-list') do + it { should have_cidr('10.0.0.0/16') } + it { should have_cidr('192.168.0.0/24').desc('dev') } +end +``` + + +### have_tag + +```ruby +describe managed_prefix_list('my-managed-prefix-list') do + it { should have_tag('env').value('dev') } +end +``` + +### its(:entries_count) + +```ruby +describe managed_prefix_list('my-managed-prefix-list') do + its(:entries_count) { should eq 2 } +end +``` + + +### its(:prefix_list_id), its(:address_family), its(:state), its(:state_message), its(:prefix_list_arn), its(:prefix_list_name), its(:max_entries), its(:version), its(:owner_id) ## mq MQ resource type. @@ -2978,7 +3020,7 @@ describe rds_db_cluster('my-rds-db-cluster') do end ``` -### its(:allocated_storage), its(:availability_zones), its(:backup_retention_period), its(:character_set_name), its(:database_name), its(:db_cluster_identifier), its(:db_cluster_parameter_group), its(:db_subnet_group), its(:status), its(:automatic_restart_time), its(:percent_progress), its(:earliest_restorable_time), its(:endpoint), its(:reader_endpoint), its(:custom_endpoints), its(:multi_az), its(:engine), its(:engine_version), its(:latest_restorable_time), its(:port), its(:master_username), its(:db_cluster_option_group_memberships), its(:preferred_backup_window), its(:preferred_maintenance_window), its(:replication_source_identifier), its(:read_replica_identifiers), its(:status_infos), its(:hosted_zone_id), its(:storage_encrypted), its(:kms_key_id), its(:db_cluster_resource_id), its(:db_cluster_arn), its(:associated_roles), its(:iam_database_authentication_enabled), its(:clone_group_id), its(:cluster_create_time), its(:earliest_backtrack_time), its(:backtrack_window), its(:backtrack_consumed_change_records), its(:enabled_cloudwatch_logs_exports), its(:capacity), its(:engine_mode), its(:scaling_configuration_info), its(:rds_custom_cluster_configuration), its(:deletion_protection), its(:http_endpoint_enabled), its(:activity_stream_mode), its(:activity_stream_status), its(:activity_stream_kms_key_id), its(:activity_stream_kinesis_stream_name), its(:copy_tags_to_snapshot), its(:cross_account_clone), its(:domain_memberships), its(:tag_list), its(:global_write_forwarding_status), its(:global_write_forwarding_requested), its(:pending_modified_values), its(:db_cluster_instance_class), its(:storage_type), its(:iops), its(:publicly_accessible), its(:auto_minor_version_upgrade), its(:monitoring_interval), its(:monitoring_role_arn), its(:performance_insights_enabled), its(:performance_insights_kms_key_id), its(:performance_insights_retention_period), its(:serverless_v2_scaling_configuration), its(:network_type), its(:db_system_id), its(:master_user_secret), its(:io_optimized_next_allowed_modification_time), its(:local_write_forwarding_status), its(:aws_backup_recovery_point_arn), its(:limitless_database), its(:storage_throughput) +### its(:allocated_storage), its(:availability_zones), its(:backup_retention_period), its(:character_set_name), its(:database_name), its(:db_cluster_identifier), its(:db_cluster_parameter_group), its(:db_subnet_group), its(:status), its(:automatic_restart_time), its(:percent_progress), its(:earliest_restorable_time), its(:endpoint), its(:reader_endpoint), its(:custom_endpoints), its(:multi_az), its(:engine), its(:engine_version), its(:latest_restorable_time), its(:port), its(:master_username), its(:db_cluster_option_group_memberships), its(:preferred_backup_window), its(:preferred_maintenance_window), its(:replication_source_identifier), its(:read_replica_identifiers), its(:status_infos), its(:hosted_zone_id), its(:storage_encrypted), its(:kms_key_id), its(:db_cluster_resource_id), its(:db_cluster_arn), its(:associated_roles), its(:iam_database_authentication_enabled), its(:clone_group_id), its(:cluster_create_time), its(:earliest_backtrack_time), its(:backtrack_window), its(:backtrack_consumed_change_records), its(:enabled_cloudwatch_logs_exports), its(:capacity), its(:engine_mode), its(:scaling_configuration_info), its(:rds_custom_cluster_configuration), its(:deletion_protection), its(:http_endpoint_enabled), its(:activity_stream_mode), its(:activity_stream_status), its(:activity_stream_kms_key_id), its(:activity_stream_kinesis_stream_name), its(:copy_tags_to_snapshot), its(:cross_account_clone), its(:domain_memberships), its(:tag_list), its(:global_write_forwarding_status), its(:global_write_forwarding_requested), its(:pending_modified_values), its(:db_cluster_instance_class), its(:storage_type), its(:iops), its(:publicly_accessible), its(:auto_minor_version_upgrade), its(:monitoring_interval), its(:monitoring_role_arn), its(:performance_insights_enabled), its(:performance_insights_kms_key_id), its(:performance_insights_retention_period), its(:serverless_v2_scaling_configuration), its(:network_type), its(:db_system_id), its(:master_user_secret), its(:io_optimized_next_allowed_modification_time), its(:local_write_forwarding_status), its(:aws_backup_recovery_point_arn), its(:limitless_database), its(:storage_throughput), its(:certificate_details) ## rds_db_cluster_parameter_group RdsDbClusterParameterGroup resource type. diff --git a/lib/awspec/command/generate.rb b/lib/awspec/command/generate.rb index 7a963fdb..94228d7b 100644 --- a/lib/awspec/command/generate.rb +++ b/lib/awspec/command/generate.rb @@ -65,7 +65,7 @@ def s3_bucket(bucket_name = nil) types_for_generate_all = %w[ cloudwatch_alarm cloudwatch_event directconnect ebs efs elasticsearch iam_group iam_policy iam_role iam_user kms lambda - acm cloudwatch_logs eip codebuild elasticache + acm cloudwatch_logs eip codebuild elasticache managed_prefix_list ] types_for_generate_all.each do |type| diff --git a/lib/awspec/generator.rb b/lib/awspec/generator.rb index 0722b522..134a59e0 100644 --- a/lib/awspec/generator.rb +++ b/lib/awspec/generator.rb @@ -43,6 +43,7 @@ require 'awspec/generator/spec/rds_proxy' require 'awspec/generator/spec/rds_db_cluster' require 'awspec/generator/spec/rds_global_cluster' +require 'awspec/generator/spec/managed_prefix_list' # Doc require 'awspec/generator/doc/type' diff --git a/lib/awspec/generator/doc/type/managed_prefix_list.rb b/lib/awspec/generator/doc/type/managed_prefix_list.rb new file mode 100644 index 00000000..8071f547 --- /dev/null +++ b/lib/awspec/generator/doc/type/managed_prefix_list.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Awspec::Generator + module Doc + module Type + class ManagedPrefixList < Base + def initialize + super + @type_name = 'ManagedPrefixList' + @type = Awspec::Type::ManagedPrefixList.new('my-managed-prefix-list') + @ret = @type.resource_via_client + @matchers = ['its(:entries_count)'] + @ignore_matchers = [] + @describes = [] + end + end + end + end +end diff --git a/lib/awspec/generator/spec/managed_prefix_list.rb b/lib/awspec/generator/spec/managed_prefix_list.rb new file mode 100644 index 00000000..8ffe6e0d --- /dev/null +++ b/lib/awspec/generator/spec/managed_prefix_list.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module Awspec::Generator + module Spec + class ManagedPrefixList + include Awspec::Helper::Finder + def select_all_managed_prefix_lists + res = ec2_client.describe_managed_prefix_lists + res.prefix_lists + end + + def generate_all + prefix_lists = select_all_managed_prefix_lists + raise 'Not Found Managed Prefix List.' if prefix_lists.empty? + + specs = prefix_lists.map do |prefix_list| + entries = select_managed_prefix_list_entries(prefix_list.prefix_list_id) + content = ERB.new(managed_prefix_list_spec_template, nil, '-').result(binding).gsub(/^\n/, '') + end + specs.join("\n") + end + + def managed_prefix_list_spec_template + <<-'EOF' +describe managed_prefix_list('<%= prefix_list.prefix_list_name %>') do + it { should exist } +<% entries.each do |entry| %> +<% if entry.description.nil? %> + it { should have_cidr('<%= entry.cidr %>') } +<% else %> + it { should have_cidr('<%= entry.cidr %>').desc('<%= entry.description %>') } +<% end %> +<% end %> + its(:entries_count) { should eq <%= entries.length %> } + its(:prefix_list_id) { should eq '<%= prefix_list.prefix_list_id %>' } + its(:address_family) { should eq '<%= prefix_list.address_family %>' } + its(:state) { should eq '<%= prefix_list.state %>' } + its(:prefix_list_arn) { should eq '<%= prefix_list.prefix_list_arn %>' } +<% if prefix_list.max_entries %> + its(:max_entries) { should eq <%= prefix_list.max_entries %> } +<% end %> +<% if prefix_list.version %> + its(:version) { should eq <%= prefix_list.version %> } +<% end %> + its(:owner_id) { should eq '<%= prefix_list.owner_id %>' } +<% prefix_list.tags.each do |tag| %> + it { should have_tag('<%= tag.key %>').value('<%= tag.value %>') } +<% end %> +end +EOF + end + end + end +end diff --git a/lib/awspec/helper/finder/ec2.rb b/lib/awspec/helper/finder/ec2.rb index f8eba788..f634d4c8 100644 --- a/lib/awspec/helper/finder/ec2.rb +++ b/lib/awspec/helper/finder/ec2.rb @@ -228,6 +228,18 @@ def find_tgw_attachments_by_tgw_id(tgw_id) }) res.transit_gateway_attachments end + + def find_managed_prefix_list(prefix_list_name) + res = ec2_client.describe_managed_prefix_lists({ + filters: [{ name: 'prefix-list-name', + values: [prefix_list_name] }] + }) + res.prefix_lists.single_resource(prefix_list_name) + end + + def select_managed_prefix_list_entries(prefix_list_id) + ec2_client.get_managed_prefix_list_entries({ prefix_list_id: prefix_list_id }).data.entries + end end end end diff --git a/lib/awspec/helper/type.rb b/lib/awspec/helper/type.rb index e49fe7d9..7df4c52f 100644 --- a/lib/awspec/helper/type.rb +++ b/lib/awspec/helper/type.rb @@ -24,7 +24,7 @@ module Type internet_gateway acm cloudwatch_logs dynamodb_table eip sqs ssm_parameter cloudformation_stack codebuild sns_topic redshift redshift_cluster_parameter_group codedeploy codedeploy_deployment_group secretsmanager msk transit_gateway cognito_identity_pool cognito_user_pool vpc_endpoints - transfer_server + transfer_server managed_prefix_list ] ACCOUNT_ATTRIBUTES = %w[ diff --git a/lib/awspec/matcher.rb b/lib/awspec/matcher.rb index b585accd..15185a28 100644 --- a/lib/awspec/matcher.rb +++ b/lib/awspec/matcher.rb @@ -90,3 +90,6 @@ require 'awspec/matcher/have_env_vars' require 'awspec/matcher/have_env_var' require 'awspec/matcher/have_env_var_value' + +# ManagedPrefixList +require 'awspec/matcher/have_cidr' diff --git a/lib/awspec/matcher/have_cidr.rb b/lib/awspec/matcher/have_cidr.rb new file mode 100644 index 00000000..6cd5f47f --- /dev/null +++ b/lib/awspec/matcher/have_cidr.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +RSpec::Matchers.define :have_cidr do |cidr| + match do |type| + type.has_cidr?(cidr, @desc) + end + + chain :desc do |desc| + @desc = desc + end +end diff --git a/lib/awspec/stub/managed_prefix_list.rb b/lib/awspec/stub/managed_prefix_list.rb new file mode 100644 index 00000000..5507199d --- /dev/null +++ b/lib/awspec/stub/managed_prefix_list.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +Aws.config[:ec2] = { + stub_responses: { + describe_managed_prefix_lists: { + next_token: nil, + prefix_lists: [ + { + prefix_list_id: 'pl-12345678', + address_family: 'IPv4', + state: 'create-complete', + state_message: nil, + prefix_list_arn: 'arn:aws:ec2:ap-northeast-1:aws:prefix-list/pl-12345678', + prefix_list_name: 'my-managed-prefix-list', + max_entries: 2, + version: 1, + tags: [ + { + key: 'env', + value: 'dev' + } + ], + owner_id: '123456789012' + } + ] + }, + get_managed_prefix_list_entries: { + next_toke: nil, + entries: [ + { + cidr: '10.0.0.0/16', + description: 'test' + }, + { + cidr: '192.168.0.0/24', + description: 'dev' + } + ] + } + } +} diff --git a/lib/awspec/type/managed_prefix_list.rb b/lib/awspec/type/managed_prefix_list.rb new file mode 100644 index 00000000..a961bd33 --- /dev/null +++ b/lib/awspec/type/managed_prefix_list.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Awspec::Type + class ManagedPrefixList < ResourceBase + aws_resource Aws::EC2::Types::ManagedPrefixList + tags_allowed + + def resource_via_client + @resource_via_client ||= find_managed_prefix_list(@display_name) + end + + def id + @id ||= resource_via_client.prefix_list_id if resource_via_client + end + + def entries + @entries ||= select_managed_prefix_list_entries(id) + end + + def has_cidr?(cidr, description = nil) + entries.find do |entry| + if description.nil? + entry.cidr == cidr + else + entry.cidr == cidr && entry.description == description + end + end + end + + def entries_count + entries.length + end + end +end diff --git a/spec/generator/spec/managed_prefix_list_spec.rb b/spec/generator/spec/managed_prefix_list_spec.rb new file mode 100644 index 00000000..d17d5176 --- /dev/null +++ b/spec/generator/spec/managed_prefix_list_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Awspec::Generator::Spec::ManagedPrefixList' do + before do + Awspec::Stub.load 'managed_prefix_list' + end + let(:managed_prefix_list) { Awspec::Generator::Spec::ManagedPrefixList.new } + it 'generate spec' do + spec = <<-'EOF' +describe managed_prefix_list('my-managed-prefix-list') do + it { should exist } + it { should have_cidr('10.0.0.0/16').desc('test') } + it { should have_cidr('192.168.0.0/24').desc('dev') } + its(:entries_count) { should eq 2 } + its(:prefix_list_id) { should eq 'pl-12345678' } + its(:address_family) { should eq 'IPv4' } + its(:state) { should eq 'create-complete' } + its(:prefix_list_arn) { should eq 'arn:aws:ec2:ap-northeast-1:aws:prefix-list/pl-12345678' } + its(:max_entries) { should eq 2 } + its(:version) { should eq 1 } + its(:owner_id) { should eq '123456789012' } + it { should have_tag('env').value('dev') } +end +EOF + expect(managed_prefix_list.generate_all.to_s.gsub(/\n/, "\n")).to eq spec + end +end diff --git a/spec/type/managed_prefix_list_spec.rb b/spec/type/managed_prefix_list_spec.rb new file mode 100644 index 00000000..35472775 --- /dev/null +++ b/spec/type/managed_prefix_list_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'spec_helper' +Awspec::Stub.load 'managed_prefix_list' + +describe managed_prefix_list('my-managed-prefix-list') do + it { should exist } + it { should have_cidr('10.0.0.0/16') } + it { should have_cidr('192.168.0.0/24').desc('dev') } + its(:entries_count) { should eq 2 } + it { should have_tag('env').value('dev') } +end