cpflow 4.1.0 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +7 -7
- data/docs/commands.md +16 -0
- data/docs/terraform/details.md +415 -0
- data/docs/terraform/example/.controlplane/controlplane.yml +29 -0
- data/docs/terraform/example/.controlplane/templates/app.yml +38 -0
- data/docs/terraform/example/.controlplane/templates/postgres.yml +30 -0
- data/docs/terraform/example/.controlplane/templates/rails.yml +26 -0
- data/docs/terraform/overview.md +105 -0
- data/lib/command/base.rb +29 -5
- data/lib/command/base_sub_command.rb +15 -0
- data/lib/command/generate.rb +1 -1
- data/lib/command/ps.rb +1 -1
- data/lib/command/ps_stop.rb +2 -1
- data/lib/command/run.rb +1 -1
- data/lib/command/terraform/base.rb +35 -0
- data/lib/command/terraform/generate.rb +99 -0
- data/lib/command/terraform/import.rb +79 -0
- data/lib/core/controlplane.rb +3 -3
- data/lib/core/shell.rb +9 -4
- data/lib/core/terraform_config/agent.rb +31 -0
- data/lib/core/terraform_config/audit_context.rb +31 -0
- data/lib/core/terraform_config/base.rb +25 -0
- data/lib/core/terraform_config/dsl.rb +102 -0
- data/lib/core/terraform_config/generator.rb +184 -0
- data/lib/core/terraform_config/gvc.rb +63 -0
- data/lib/core/terraform_config/identity.rb +35 -0
- data/lib/core/terraform_config/local_variable.rb +30 -0
- data/lib/core/terraform_config/policy.rb +151 -0
- data/lib/core/terraform_config/provider.rb +22 -0
- data/lib/core/terraform_config/required_provider.rb +23 -0
- data/lib/core/terraform_config/secret.rb +138 -0
- data/lib/core/terraform_config/volume_set.rb +155 -0
- data/lib/core/terraform_config/workload/main.tf +316 -0
- data/lib/core/terraform_config/workload/required_providers.tf +8 -0
- data/lib/core/terraform_config/workload/variables.tf +263 -0
- data/lib/core/terraform_config/workload.rb +132 -0
- data/lib/cpflow/version.rb +1 -1
- data/lib/cpflow.rb +50 -9
- data/lib/generator_templates/templates/postgres.yml +1 -1
- data/lib/patches/array.rb +8 -0
- data/lib/patches/hash.rb +47 -0
- data/lib/patches/string.rb +34 -0
- data/script/update_command_docs +6 -2
- metadata +33 -3
| @@ -0,0 +1,184 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TerraformConfig
         | 
| 4 | 
            +
              class Generator # rubocop:disable Metrics/ClassLength
         | 
| 5 | 
            +
                SUPPORTED_TEMPLATE_KINDS = %w[gvc secret identity policy volumeset workload auditctx agent].freeze
         | 
| 6 | 
            +
                WORKLOAD_SPEC_KEYS = %i[
         | 
| 7 | 
            +
                  type
         | 
| 8 | 
            +
                  containers
         | 
| 9 | 
            +
                  identity_link
         | 
| 10 | 
            +
                  default_options
         | 
| 11 | 
            +
                  local_options
         | 
| 12 | 
            +
                  rollout_options
         | 
| 13 | 
            +
                  security_options
         | 
| 14 | 
            +
                  load_balancer
         | 
| 15 | 
            +
                  firewall_config
         | 
| 16 | 
            +
                  support_dynamic_tags
         | 
| 17 | 
            +
                  job
         | 
| 18 | 
            +
                ].freeze
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                class InvalidTemplateError < ArgumentError; end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                attr_reader :config, :template
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def initialize(config:, template:)
         | 
| 25 | 
            +
                  @config = config
         | 
| 26 | 
            +
                  @template = template.deep_underscore_keys.deep_symbolize_keys
         | 
| 27 | 
            +
                  validate_template_kind!
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def tf_configs
         | 
| 31 | 
            +
                  tf_config.locals.merge(filename => tf_config)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                private
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def validate_template_kind!
         | 
| 37 | 
            +
                  return if SUPPORTED_TEMPLATE_KINDS.include?(kind)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  raise InvalidTemplateError, "Unsupported template kind: #{kind}"
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def filename
         | 
| 43 | 
            +
                  case kind
         | 
| 44 | 
            +
                  when "gvc"
         | 
| 45 | 
            +
                    "gvc.tf"
         | 
| 46 | 
            +
                  when "workload"
         | 
| 47 | 
            +
                    "#{template[:name]}.tf"
         | 
| 48 | 
            +
                  when "auditctx"
         | 
| 49 | 
            +
                    "audit_contexts.tf"
         | 
| 50 | 
            +
                  else
         | 
| 51 | 
            +
                    "#{kind.pluralize}.tf"
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                def tf_config
         | 
| 56 | 
            +
                  @tf_config ||= config_class.new(**config_params)
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                def config_class
         | 
| 60 | 
            +
                  case kind
         | 
| 61 | 
            +
                  when "volumeset"
         | 
| 62 | 
            +
                    TerraformConfig::VolumeSet
         | 
| 63 | 
            +
                  when "auditctx"
         | 
| 64 | 
            +
                    TerraformConfig::AuditContext
         | 
| 65 | 
            +
                  else
         | 
| 66 | 
            +
                    TerraformConfig.const_get(kind.capitalize)
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                def config_params
         | 
| 71 | 
            +
                  send("#{kind}_config_params")
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def gvc_config_params
         | 
| 75 | 
            +
                  template
         | 
| 76 | 
            +
                    .slice(:name, :description, :tags)
         | 
| 77 | 
            +
                    .merge(
         | 
| 78 | 
            +
                      env: gvc_env,
         | 
| 79 | 
            +
                      pull_secrets: gvc_pull_secrets,
         | 
| 80 | 
            +
                      locations: gvc_locations,
         | 
| 81 | 
            +
                      domain: template.dig(:spec, :domain),
         | 
| 82 | 
            +
                      load_balancer: template.dig(:spec, :load_balancer)
         | 
| 83 | 
            +
                    )
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                def identity_config_params
         | 
| 87 | 
            +
                  template.slice(:name, :description, :tags).merge(gvc: gvc)
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                def secret_config_params
         | 
| 91 | 
            +
                  template.slice(:name, :description, :type, :data, :tags)
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                def policy_config_params
         | 
| 95 | 
            +
                  template
         | 
| 96 | 
            +
                    .slice(:name, :description, :tags, :target, :target_kind, :target_query)
         | 
| 97 | 
            +
                    .merge(gvc: gvc, target_links: policy_target_links, bindings: policy_bindings)
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                def volumeset_config_params
         | 
| 101 | 
            +
                  specs = %i[
         | 
| 102 | 
            +
                    initial_capacity
         | 
| 103 | 
            +
                    performance_class
         | 
| 104 | 
            +
                    file_system_type
         | 
| 105 | 
            +
                    storage_class_suffix
         | 
| 106 | 
            +
                    snapshots
         | 
| 107 | 
            +
                    autoscaling
         | 
| 108 | 
            +
                  ].to_h { |key| [key, template.dig(:spec, key)] }
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                  template.slice(:name, :description, :tags).merge(gvc: gvc).merge(specs)
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                def auditctx_config_params
         | 
| 114 | 
            +
                  template.slice(:name, :description, :tags)
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                def agent_config_params
         | 
| 118 | 
            +
                  template.slice(:name, :description, :tags)
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                def workload_config_params
         | 
| 122 | 
            +
                  template
         | 
| 123 | 
            +
                    .slice(:name, :description, :tags)
         | 
| 124 | 
            +
                    .merge(gvc: gvc)
         | 
| 125 | 
            +
                    .merge(workload_spec_params)
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                def workload_spec_params # rubocop:disable Metrics/MethodLength
         | 
| 129 | 
            +
                  WORKLOAD_SPEC_KEYS.to_h do |key|
         | 
| 130 | 
            +
                    arg_name =
         | 
| 131 | 
            +
                      case key
         | 
| 132 | 
            +
                      when :default_options then :options
         | 
| 133 | 
            +
                      when :firewall_config then :firewall_spec
         | 
| 134 | 
            +
                      else key
         | 
| 135 | 
            +
                      end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                    value = template.dig(:spec, key)
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                    if value
         | 
| 140 | 
            +
                      case key
         | 
| 141 | 
            +
                      when :local_options
         | 
| 142 | 
            +
                        value[:location] = value.delete(:location).split("/").last
         | 
| 143 | 
            +
                      when :security_options
         | 
| 144 | 
            +
                        value[:file_system_group_id] = value.delete(:filesystem_group_id)
         | 
| 145 | 
            +
                      end
         | 
| 146 | 
            +
                    end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                    [arg_name, value]
         | 
| 149 | 
            +
                  end
         | 
| 150 | 
            +
                end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                # GVC name matches application name
         | 
| 153 | 
            +
                def gvc
         | 
| 154 | 
            +
                  "cpln_gvc.#{config.app}.name"
         | 
| 155 | 
            +
                end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                def gvc_pull_secrets
         | 
| 158 | 
            +
                  template.dig(:spec, :pull_secret_links)&.map { |secret_link| "cpln_secret.#{secret_link.split('/').last}.name" }
         | 
| 159 | 
            +
                end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                def gvc_env
         | 
| 162 | 
            +
                  template.dig(:spec, :env).to_h { |env_var| [env_var[:name], env_var[:value]] }
         | 
| 163 | 
            +
                end
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                def gvc_locations
         | 
| 166 | 
            +
                  template.dig(:spec, :static_placement, :location_links)&.map { |location_link| location_link.split("/").last }
         | 
| 167 | 
            +
                end
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                def policy_target_links
         | 
| 170 | 
            +
                  template[:target_links]&.map { |target_link| target_link.split("/").last }
         | 
| 171 | 
            +
                end
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                def policy_bindings
         | 
| 174 | 
            +
                  template[:bindings]&.map do |data|
         | 
| 175 | 
            +
                    principal_links = data.delete(:principal_links)&.map { |link| link.delete_prefix("//") }
         | 
| 176 | 
            +
                    data.merge(principal_links: principal_links)
         | 
| 177 | 
            +
                  end
         | 
| 178 | 
            +
                end
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                def kind
         | 
| 181 | 
            +
                  @kind ||= template[:kind]
         | 
| 182 | 
            +
                end
         | 
| 183 | 
            +
              end
         | 
| 184 | 
            +
            end
         | 
| @@ -0,0 +1,63 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TerraformConfig
         | 
| 4 | 
            +
              class Gvc < Base
         | 
| 5 | 
            +
                attr_reader :name, :description, :tags, :domain, :locations, :pull_secrets, :env, :load_balancer
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize( # rubocop:disable Metrics/ParameterLists
         | 
| 8 | 
            +
                  name:,
         | 
| 9 | 
            +
                  description: nil,
         | 
| 10 | 
            +
                  tags: nil,
         | 
| 11 | 
            +
                  domain: nil,
         | 
| 12 | 
            +
                  locations: nil,
         | 
| 13 | 
            +
                  pull_secrets: nil,
         | 
| 14 | 
            +
                  env: nil,
         | 
| 15 | 
            +
                  load_balancer: nil
         | 
| 16 | 
            +
                )
         | 
| 17 | 
            +
                  super()
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  @name = name
         | 
| 20 | 
            +
                  @description = description
         | 
| 21 | 
            +
                  @tags = tags
         | 
| 22 | 
            +
                  @domain = domain
         | 
| 23 | 
            +
                  @locations = locations
         | 
| 24 | 
            +
                  @pull_secrets = pull_secrets
         | 
| 25 | 
            +
                  @env = env
         | 
| 26 | 
            +
                  @load_balancer = load_balancer&.deep_underscore_keys&.deep_symbolize_keys
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def importable?
         | 
| 30 | 
            +
                  true
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def reference
         | 
| 34 | 
            +
                  "cpln_gvc.#{name}"
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def to_tf
         | 
| 38 | 
            +
                  block :resource, :cpln_gvc, name do
         | 
| 39 | 
            +
                    argument :name, name
         | 
| 40 | 
            +
                    argument :description, description, optional: true
         | 
| 41 | 
            +
                    argument :tags, tags, optional: true
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    argument :domain, domain, optional: true
         | 
| 44 | 
            +
                    argument :locations, locations, optional: true
         | 
| 45 | 
            +
                    argument :pull_secrets, pull_secrets, optional: true
         | 
| 46 | 
            +
                    argument :env, env, optional: true
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                    load_balancer_tf
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                private
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def load_balancer_tf
         | 
| 55 | 
            +
                  return if load_balancer.nil?
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  block :load_balancer do
         | 
| 58 | 
            +
                    argument :dedicated, load_balancer.fetch(:dedicated)
         | 
| 59 | 
            +
                    argument :trusted_proxies, load_balancer.fetch(:trusted_proxies, nil), optional: true
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TerraformConfig
         | 
| 4 | 
            +
              class Identity < Base
         | 
| 5 | 
            +
                attr_reader :gvc, :name, :description, :tags
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(gvc:, name:, description: nil, tags: nil)
         | 
| 8 | 
            +
                  super()
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  @gvc = gvc
         | 
| 11 | 
            +
                  @name = name
         | 
| 12 | 
            +
                  @description = description
         | 
| 13 | 
            +
                  @tags = tags
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def importable?
         | 
| 17 | 
            +
                  true
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def reference
         | 
| 21 | 
            +
                  "cpln_identity.#{name}"
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def to_tf
         | 
| 25 | 
            +
                  block :resource, :cpln_identity, name do
         | 
| 26 | 
            +
                    argument :gvc, gvc
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    argument :name, name
         | 
| 29 | 
            +
                    argument :description, description, optional: true
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    argument :tags, tags, optional: true
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TerraformConfig
         | 
| 4 | 
            +
              class LocalVariable < Base
         | 
| 5 | 
            +
                VARIABLE_NAME_REGEX = /\A[a-zA-Z][a-zA-Z0-9_]*\z/.freeze
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                attr_reader :variables
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def initialize(**variables)
         | 
| 10 | 
            +
                  super()
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  @variables = variables
         | 
| 13 | 
            +
                  validate_variables!
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def to_tf
         | 
| 17 | 
            +
                  block :locals do
         | 
| 18 | 
            +
                    variables.each do |var, value|
         | 
| 19 | 
            +
                      argument var, value
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                private
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def validate_variables!
         | 
| 27 | 
            +
                  raise ArgumentError, "Variables cannot be empty" if variables.empty?
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,151 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TerraformConfig
         | 
| 4 | 
            +
              class Policy < Base # rubocop:disable Metrics/ClassLength
         | 
| 5 | 
            +
                TARGET_KINDS = %w[
         | 
| 6 | 
            +
                  agent auditctx cloudaccount domain group gvc identity image ipset kubernetes location
         | 
| 7 | 
            +
                  org policy quota secret serviceaccount task user volumeset workload
         | 
| 8 | 
            +
                ].freeze
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                GVC_REQUIRED_TARGET_KINDS = %w[identity workload volumeset].freeze
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                attr_reader :name, :description, :tags, :target_kind, :gvc, :target, :target_links, :target_query, :bindings
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def initialize( # rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
         | 
| 15 | 
            +
                  name:,
         | 
| 16 | 
            +
                  description: nil,
         | 
| 17 | 
            +
                  tags: nil,
         | 
| 18 | 
            +
                  target_kind: nil,
         | 
| 19 | 
            +
                  gvc: nil,
         | 
| 20 | 
            +
                  target: nil,
         | 
| 21 | 
            +
                  target_links: nil,
         | 
| 22 | 
            +
                  target_query: nil,
         | 
| 23 | 
            +
                  bindings: nil
         | 
| 24 | 
            +
                )
         | 
| 25 | 
            +
                  super()
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  @name = name
         | 
| 28 | 
            +
                  @description = description
         | 
| 29 | 
            +
                  @tags = tags
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  @target_kind = target_kind
         | 
| 32 | 
            +
                  validate_target_kind!
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  @gvc = gvc
         | 
| 35 | 
            +
                  validate_gvc!
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  @target = target
         | 
| 38 | 
            +
                  @target_links = target_links
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  @target_query = target_query&.deep_underscore_keys&.deep_symbolize_keys
         | 
| 41 | 
            +
                  @bindings = bindings&.map { |data| data.deep_underscore_keys.deep_symbolize_keys }
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def importable?
         | 
| 45 | 
            +
                  true
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def reference
         | 
| 49 | 
            +
                  "cpln_policy.#{name}"
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def to_tf
         | 
| 53 | 
            +
                  block :resource, :cpln_policy, name do
         | 
| 54 | 
            +
                    argument :name, name
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    %i[description tags target_kind gvc target target_links].each do |arg_name|
         | 
| 57 | 
            +
                      argument arg_name, send(arg_name), optional: true
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    bindings_tf
         | 
| 61 | 
            +
                    target_query_tf
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                private
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def validate_target_kind!
         | 
| 68 | 
            +
                  return if target_kind.nil? || TARGET_KINDS.include?(target_kind.to_s)
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  raise ArgumentError, "Invalid target kind given - #{target_kind}"
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                def validate_gvc!
         | 
| 74 | 
            +
                  return unless GVC_REQUIRED_TARGET_KINDS.include?(target_kind.to_s) && gvc.nil?
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  raise ArgumentError, "`gvc` is required for `#{target_kind}` target kind"
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def bindings_tf
         | 
| 80 | 
            +
                  return if bindings.nil?
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  bindings.each do |binding_data|
         | 
| 83 | 
            +
                    block :binding do
         | 
| 84 | 
            +
                      argument :permissions, binding_data.fetch(:permissions, nil), optional: true
         | 
| 85 | 
            +
                      argument :principal_links, binding_data.fetch(:principal_links, nil), optional: true
         | 
| 86 | 
            +
                    end
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                def target_query_tf
         | 
| 91 | 
            +
                  return if target_query.nil?
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  fetch_type = target_query.fetch(:fetch, nil)
         | 
| 94 | 
            +
                  validate_fetch_type!(fetch_type) if fetch_type
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  block :target_query do
         | 
| 97 | 
            +
                    argument :fetch, fetch_type, optional: true
         | 
| 98 | 
            +
                    target_query_spec_tf
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                def validate_fetch_type!(fetch_type)
         | 
| 103 | 
            +
                  return if %w[links items].include?(fetch_type.to_s)
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  raise ArgumentError, "Invalid fetch type - #{fetch_type}. Should be either `links` or `items`"
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                def target_query_spec_tf
         | 
| 109 | 
            +
                  spec = target_query.fetch(:spec, nil)
         | 
| 110 | 
            +
                  return if spec.nil?
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  match_type = spec.fetch(:match, nil)
         | 
| 113 | 
            +
                  validate_match_type!(match_type) if match_type
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                  block :spec do
         | 
| 116 | 
            +
                    argument :match, match_type, optional: true
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                    target_query_spec_terms_tf(spec)
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                def validate_match_type!(match_type)
         | 
| 123 | 
            +
                  return if %w[all any none].include?(match_type.to_s)
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                  raise ArgumentError, "Invalid match type - #{match_type}. Should be either `all`, `any` or `none`"
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                def target_query_spec_terms_tf(spec)
         | 
| 129 | 
            +
                  terms = spec.fetch(:terms, nil)
         | 
| 130 | 
            +
                  return if terms.nil?
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                  terms.each do |term|
         | 
| 133 | 
            +
                    validate_term!(term)
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                    block :terms do
         | 
| 136 | 
            +
                      %i[op property rel tag value].each do |arg_name|
         | 
| 137 | 
            +
                        argument arg_name, term.fetch(arg_name, nil), optional: true
         | 
| 138 | 
            +
                      end
         | 
| 139 | 
            +
                    end
         | 
| 140 | 
            +
                  end
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                def validate_term!(term)
         | 
| 144 | 
            +
                  return if (%i[property rel tag] & term.keys).count == 1
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                  raise ArgumentError,
         | 
| 147 | 
            +
                        "Each term in `target_query.spec.terms` must contain exactly one of the following attributes: " \
         | 
| 148 | 
            +
                        "`property`, `rel`, or `tag`."
         | 
| 149 | 
            +
                end
         | 
| 150 | 
            +
              end
         | 
| 151 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TerraformConfig
         | 
| 4 | 
            +
              class Provider < Base
         | 
| 5 | 
            +
                attr_reader :name, :options
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(name:, **options)
         | 
| 8 | 
            +
                  super()
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  @name = name
         | 
| 11 | 
            +
                  @options = options
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def to_tf
         | 
| 15 | 
            +
                  block :provider, name do
         | 
| 16 | 
            +
                    options.each do |option, value|
         | 
| 17 | 
            +
                      argument option, value
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TerraformConfig
         | 
| 4 | 
            +
              class RequiredProvider < Base
         | 
| 5 | 
            +
                attr_reader :name, :org, :options
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(name:, org:, **options)
         | 
| 8 | 
            +
                  super()
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  @name = name
         | 
| 11 | 
            +
                  @org = org
         | 
| 12 | 
            +
                  @options = options
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def to_tf
         | 
| 16 | 
            +
                  block :terraform do
         | 
| 17 | 
            +
                    block :required_providers do
         | 
| 18 | 
            +
                      argument name, options
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,138 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TerraformConfig
         | 
| 4 | 
            +
              class Secret < Base # rubocop:disable Metrics/ClassLength
         | 
| 5 | 
            +
                REQUIRED_DATA_KEYS = {
         | 
| 6 | 
            +
                  "aws" => %i[secret_key access_key],
         | 
| 7 | 
            +
                  "azure-connector" => %i[url code],
         | 
| 8 | 
            +
                  "ecr" => %i[secret_key access_key repos],
         | 
| 9 | 
            +
                  "keypair" => %i[secret_key],
         | 
| 10 | 
            +
                  "nats-account" => %i[account_id private_key],
         | 
| 11 | 
            +
                  "opaque" => %i[payload],
         | 
| 12 | 
            +
                  "tls" => %i[key cert],
         | 
| 13 | 
            +
                  "userpass" => %i[username password],
         | 
| 14 | 
            +
                  "dictionary" => []
         | 
| 15 | 
            +
                }.freeze
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                attr_reader :name, :type, :data, :description, :tags
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def initialize(name:, type:, data:, description: nil, tags: nil)
         | 
| 20 | 
            +
                  super()
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  @name = name
         | 
| 23 | 
            +
                  @type = type
         | 
| 24 | 
            +
                  @description = description
         | 
| 25 | 
            +
                  @tags = tags
         | 
| 26 | 
            +
                  @data = prepare_data(type: type, data: data)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def importable?
         | 
| 30 | 
            +
                  true
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def reference
         | 
| 34 | 
            +
                  "cpln_secret.#{name}"
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def to_tf
         | 
| 38 | 
            +
                  block :resource, :cpln_secret, name do
         | 
| 39 | 
            +
                    argument :name, name
         | 
| 40 | 
            +
                    argument :description, description, optional: true
         | 
| 41 | 
            +
                    argument :tags, tags, optional: true
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    secret_data
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                private
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def prepare_data(type:, data:)
         | 
| 50 | 
            +
                  return data unless data.is_a?(Hash)
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  data.deep_underscore_keys.deep_symbolize_keys.tap do |prepared_data|
         | 
| 53 | 
            +
                    validate_required_data_keys!(type: type, data: prepared_data)
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def validate_required_data_keys!(type:, data:)
         | 
| 58 | 
            +
                  required_keys = REQUIRED_DATA_KEYS[type] || []
         | 
| 59 | 
            +
                  missing_keys = required_keys - data.keys
         | 
| 60 | 
            +
                  raise ArgumentError, "Missing required data keys for #{type}: #{missing_keys.join(', ')}" if missing_keys.any?
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                def secret_data
         | 
| 64 | 
            +
                  case type
         | 
| 65 | 
            +
                  when "azure-sdk", "dictionary", "docker", "gcp"
         | 
| 66 | 
            +
                    argument type.underscore, data, optional: true
         | 
| 67 | 
            +
                  when "azure-connector", "aws", "ecr", "keypair", "nats-account", "opaque", "tls", "userpass"
         | 
| 68 | 
            +
                    send("#{type.underscore}_tf")
         | 
| 69 | 
            +
                  else
         | 
| 70 | 
            +
                    raise "Invalid secret type given - #{type}"
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def aws_tf
         | 
| 75 | 
            +
                  aws_based_tf(:aws)
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                def ecr_tf
         | 
| 79 | 
            +
                  aws_based_tf(:ecr, repos: data.fetch(:repos))
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                def azure_connector_tf
         | 
| 83 | 
            +
                  block :azure_connector do
         | 
| 84 | 
            +
                    argument :url, data.fetch(:url)
         | 
| 85 | 
            +
                    argument :code, data.fetch(:code)
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                def keypair_tf
         | 
| 90 | 
            +
                  block :keypair do
         | 
| 91 | 
            +
                    argument :secret_key, data.fetch(:secret_key)
         | 
| 92 | 
            +
                    argument :public_key, data.fetch(:public_key, nil), optional: true
         | 
| 93 | 
            +
                    argument :passphrase, data.fetch(:passphrase, nil), optional: true
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                def nats_account_tf
         | 
| 98 | 
            +
                  block :nats_account do
         | 
| 99 | 
            +
                    argument :account_id, data.fetch(:account_id)
         | 
| 100 | 
            +
                    argument :private_key, data.fetch(:private_key)
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                def opaque_tf
         | 
| 105 | 
            +
                  block :opaque do
         | 
| 106 | 
            +
                    argument :payload, data.fetch(:payload)
         | 
| 107 | 
            +
                    argument :encoding, data.fetch(:encoding, nil), optional: true
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                def tls_tf
         | 
| 112 | 
            +
                  block :tls do
         | 
| 113 | 
            +
                    argument :key, data.fetch(:key)
         | 
| 114 | 
            +
                    argument :cert, data.fetch(:cert)
         | 
| 115 | 
            +
                    argument :chain, data.fetch(:chain, nil), optional: true
         | 
| 116 | 
            +
                  end
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                def userpass_tf
         | 
| 120 | 
            +
                  block :userpass do
         | 
| 121 | 
            +
                    argument :username, data.fetch(:username)
         | 
| 122 | 
            +
                    argument :password, data.fetch(:password)
         | 
| 123 | 
            +
                    argument :encoding, data.fetch(:encoding, nil), optional: true
         | 
| 124 | 
            +
                  end
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                def aws_based_tf(name, **kwargs)
         | 
| 128 | 
            +
                  block name do
         | 
| 129 | 
            +
                    argument :secret_key, data.fetch(:secret_key)
         | 
| 130 | 
            +
                    argument :access_key, data.fetch(:access_key)
         | 
| 131 | 
            +
                    argument :role_arn, data.fetch(:role_arn, nil), optional: true
         | 
| 132 | 
            +
                    argument :external_id, data.fetch(:external_id, nil), optional: true
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                    kwargs.each { |key, value| argument key, value }
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
              end
         | 
| 138 | 
            +
            end
         |