Module: Chef::DSL::RestResource

Defined in:
lib/chef/dsl/rest_resource.rb

Overview

DSL methods for configuring REST resource behavior. These methods are available when a custom resource uses the ‘core::rest_resource’ partial.

Instance Method Summary collapse

Instance Method Details

#rest_api_collection(rest_api_collection = NOT_PASSED) ⇒ String

Define the REST API collection URL

Sets the base URL for the collection of resources. This URL is used for:

  • GET requests to list all resources

  • POST requests to create new resources

Examples:

rest_api_collection '/api/v1/users'
# GET  /api/v1/users      # List all users
# POST /api/v1/users      # Create new user

Parameters:

  • rest_api_collection (String, NOT_PASSED) (defaults to: NOT_PASSED)

    The collection URL path

    • String: Must be an absolute path starting with ‘/’

    • NOT_PASSED: Acts as getter, returns current collection URL

Returns:

  • (String)

    The current collection URL

Raises:

  • (ArgumentError)

    If the path doesn’t start with ‘/’



93
94
95
96
97
98
99
100
101
# File 'lib/chef/dsl/rest_resource.rb', line 93

def rest_api_collection(rest_api_collection = NOT_PASSED)
  unless rest_api_collection.equal?(NOT_PASSED)
    raise ArgumentError, "You must pass an absolute path to rest_api_collection" unless rest_api_collection.start_with? "/"

    @rest_api_collection = rest_api_collection
  end

  @rest_api_collection || inherited_accessor(:rest_api_collection)
end

#rest_api_document(rest_api_document = NOT_PASSED, first_element_only: false) ⇒ String

Define the REST API document URL with RFC 6570 template support

Sets the URL pattern for individual resource documents. The URL can include RFC 6570 URI templates that will be expanded using property values. This URL is used for:

  • GET requests to retrieve a specific resource

  • PATCH/PUT requests to update a resource

  • DELETE requests to remove a resource

Examples:

Path-based URL

rest_api_document '/api/v1/users/{username}'
# With username='john':
# GET    /api/v1/users/john
# PATCH  /api/v1/users/john
# DELETE /api/v1/users/john

Query-based URL

rest_api_document '/api/v1/users?name={username}&email={email}'
# With username='john', email='john@example.com':
# GET /api/v1/users?name=john&email=john@example.com

With first_element_only

rest_api_document '/api/v1/users?name={username}', first_element_only: true
# API returns: [{"name": "john", ...}]
# Resource sees: {"name": "john", ...}

Parameters:

  • rest_api_document (String, NOT_PASSED) (defaults to: NOT_PASSED)

    The document URL pattern

    • String: Must be an absolute path starting with ‘/’

    • Can include RFC 6570 templates like property_name

    • NOT_PASSED: Acts as getter, returns current document URL

  • first_element_only (Boolean) (defaults to: false)

    If true and API returns array, extract first element only

Returns:

  • (String)

    The current document URL pattern

Raises:

  • (ArgumentError)

    If the path doesn’t start with ‘/’

See Also:



141
142
143
144
145
146
147
148
149
150
151
# File 'lib/chef/dsl/rest_resource.rb', line 141

def rest_api_document(rest_api_document = NOT_PASSED, first_element_only: false)
  unless rest_api_document.equal?(NOT_PASSED)
    raise ArgumentError, "You must pass an absolute path to rest_api_document" unless rest_api_document.start_with? "/"

    @rest_api_document = rest_api_document
    @rest_api_document_first_element_only = first_element_only
  end
  @rest_api_document ||
    inherited_accessor(:rest_api_document) ||
    (rest_api_collection && rest_identity_property ? "#{rest_api_collection}/{#{rest_identity_property}}" : nil)
end

#rest_api_document_first_element_only(rest_api_document_first_element_only = NOT_PASSED) ⇒ Object



238
239
240
241
242
243
# File 'lib/chef/dsl/rest_resource.rb', line 238

def rest_api_document_first_element_only(rest_api_document_first_element_only = NOT_PASSED)
  unless rest_api_document_first_element_only.equal?(NOT_PASSED)
    @rest_api_document_first_element_only = rest_api_document_first_element_only
  end
  @rest_api_document_first_element_only || inherited_accessor(:rest_api_document_first_element_only)
end

#rest_api_endpoint(rest_api_endpoint = NOT_PASSED) ⇒ String?

Define the base URL for the REST API

Sets the base endpoint URL that is prepended to all collection and document URLs. This allows resource definitions to be self-contained without requiring the Train transport endpoint to be pre-configured.

Examples:

rest_api_endpoint "https://api.example.com"
rest_api_collection "/api/v1/users"
# GET https://api.example.com/api/v1/users

Parameters:

  • rest_api_endpoint (String, NOT_PASSED) (defaults to: NOT_PASSED)

    The base URL of the REST API

    • NOT_PASSED: Acts as getter, returns current endpoint URL

Returns:

  • (String, nil)

    The current endpoint URL



260
261
262
263
# File 'lib/chef/dsl/rest_resource.rb', line 260

def rest_api_endpoint(rest_api_endpoint = NOT_PASSED)
  @rest_api_endpoint = rest_api_endpoint unless rest_api_endpoint.equal?(NOT_PASSED)
  @rest_api_endpoint || inherited_accessor(:rest_api_endpoint)
end

#rest_identity_map(rest_identity_map = NOT_PASSED) ⇒ Hash?

Define explicit identity mapping for resource identification

Explicitly specifies which JSON fields and resource properties uniquely identify a resource. Use this when automatic identity inference from the document URL is insufficient or when dealing with composite keys.

If not specified, the identity is automatically inferred from RFC 6570 templates in the document URL.

Examples:

Simple identity

property :username, String, identity: true
rest_identity_map({ 'username' => :username })

Composite identity

property :name, String
property :namespace, String

rest_identity_map({
  'name' => :name,
  'namespace' => :namespace
})

Nested identity fields

property :user_id, String
property :org_id, String

rest_identity_map({
  'user.id' => :user_id,
  'organization.id' => :org_id
})

Parameters:

  • rest_identity_map (Hash, NOT_PASSED) (defaults to: NOT_PASSED)

    Mapping of JSON paths to properties

    • Hash: Keys are JMESPath-like strings, values are property symbols

    • NOT_PASSED: Acts as getter, returns current identity mapping

Returns:

  • (Hash, nil)

    The current identity mapping or nil if using auto-inference



189
190
191
192
# File 'lib/chef/dsl/rest_resource.rb', line 189

def rest_identity_map(rest_identity_map = NOT_PASSED)
  @rest_identity_map = rest_identity_map unless rest_identity_map.equal?(NOT_PASSED)
  @rest_identity_map || inherited_accessor(:rest_identity_map)
end

#rest_identity_property(property = NOT_PASSED) ⇒ Symbol?

Declare the property that uniquely identifies a resource in the REST API

Sets the identity property for the resource and auto-generates the document URL as “##rest_api_collection/property” when no explicit rest_api_document is provided. This is a convenience alternative to setting rest_api_document manually.

Examples:

rest_api_collection "/api/v1/users"
rest_identity_property :username
# Auto-generates rest_api_document as "/api/v1/users/{username}"

Parameters:

  • property (Symbol, NOT_PASSED) (defaults to: NOT_PASSED)

    The property name used as the resource identifier

    • NOT_PASSED: Acts as getter, returns current identity property

Returns:

  • (Symbol, nil)

    The current identity property name



281
282
283
284
# File 'lib/chef/dsl/rest_resource.rb', line 281

def rest_identity_property(property = NOT_PASSED)
  @rest_identity_property = property unless property.equal?(NOT_PASSED)
  @rest_identity_property || inherited_accessor(:rest_identity_property)
end

#rest_post_only_properties(rest_post_only_properties = NOT_PASSED) ⇒ Array<Symbol>

Declare properties that should only be sent during resource creation

Specifies which properties should only be included in POST (create) requests and excluded from PATCH/PUT (update) requests. This is useful for properties that can only be set during initial creation or would cause errors if included in updates.

Examples:

Single property

property :password, String, sensitive: true
property :username, String

rest_post_only_properties :password
# Password only sent when creating user, not when updating

Multiple properties

property :password, String, sensitive: true
property :initial_role, String
property :username, String

rest_post_only_properties [:password, :initial_role]

Common use cases

# Passwords that can't be updated via API
rest_post_only_properties :admin_password

# Resource size that can't be changed after creation
rest_post_only_properties :disk_size_gb

# Initialization parameters
rest_post_only_properties [:template_id, :source_snapshot]

Parameters:

  • rest_post_only_properties (Symbol, Array<Symbol>, NOT_PASSED) (defaults to: NOT_PASSED)

    Properties to mark

    • Symbol: Single property name

    • Array<Symbol>: Multiple property names

    • NOT_PASSED: Acts as getter, returns current post-only properties

Returns:

  • (Array<Symbol>)

    Current list of post-only properties (empty array if none)



231
232
233
234
235
236
# File 'lib/chef/dsl/rest_resource.rb', line 231

def rest_post_only_properties(rest_post_only_properties = NOT_PASSED)
  unless rest_post_only_properties.equal?(NOT_PASSED)
    @rest_post_only_properties = Array(rest_post_only_properties).map(&:to_sym)
  end
  @rest_post_only_properties || inherited_accessor(:rest_post_only_properties) || []
end

#rest_property_map(rest_property_map = NOT_PASSED) ⇒ Hash

Define property mapping between resource properties and JSON API fields

Maps resource properties to their corresponding locations in the JSON API payload. Supports both simple 1:1 mappings and complex transformations.

Examples:

Simple 1:1 mapping

rest_property_map [:username, :email, :role]
# Equivalent to: { username: 'username', email: 'email', role: 'role' }

Nested JSON paths

rest_property_map({
  username: 'user.name',
  email: 'user.contact.email',
  role: 'permissions.role'
})

Custom mapping functions

rest_property_map({
  username: 'username',
  tags: :tags_mapping  # Calls tags_from_json and tags_to_json methods
})

Parameters:

  • rest_property_map (Hash, Array, NOT_PASSED) (defaults to: NOT_PASSED)

    The property mapping configuration

    • Hash: Keys are property symbols, values are JMESPath strings or symbol references

    • Array: Simple 1:1 mapping (property name matches JSON field name)

    • NOT_PASSED: Acts as getter, returns current mapping

Returns:

  • (Hash)

    The current property mapping

See Also:

  • Method that uses this mapping to extract values
  • Method that uses this mapping to create JSON


66
67
68
69
70
71
72
73
# File 'lib/chef/dsl/rest_resource.rb', line 66

def rest_property_map(rest_property_map = NOT_PASSED)
  unless rest_property_map.equal?(NOT_PASSED)
    rest_property_map = rest_property_map.to_h { |k| [k.to_sym, k] } if rest_property_map.is_a? Array

    @rest_property_map = rest_property_map
  end
  @rest_property_map || inherited_accessor(:rest_property_map)
end