From 91755f225d309a0ce820eb4eb47ddafd50bd1ee4 Mon Sep 17 00:00:00 2001 From: ParthaI <47887552+ParthaI@users.noreply.github.com> Date: Fri, 9 Aug 2024 13:33:46 +0530 Subject: [PATCH] Add table linode_firewall Closes #54 (#58) --- docs/tables/linode_firewall.md | 155 ++++++++++++++++++++++++++++++++ linode/plugin.go | 1 + linode/table_linode_firewall.go | 73 +++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 docs/tables/linode_firewall.md create mode 100644 linode/table_linode_firewall.go diff --git a/docs/tables/linode_firewall.md b/docs/tables/linode_firewall.md new file mode 100644 index 0000000..7a433f0 --- /dev/null +++ b/docs/tables/linode_firewall.md @@ -0,0 +1,155 @@ +--- +title: "Steampipe Table: linode_firewall - Query Linode Firewalls using SQL" +description: "Allows users to query Linode Firewalls, providing detailed information about each firewall's configuration, status, and rules." +--- + +# Table: linode_firewall - Query Linode Firewalls using SQL + +Linode Firewalls provide a layer of security by controlling the traffic to and from your Linode instances. They allow you to define rules that either allow or block traffic based on specific criteria, helping you protect your infrastructure from unauthorized access and attacks. + +## Table Usage Guide + +The `linode_firewall` table allows system administrators and DevOps engineers to query and manage the firewalls associated with their Linode instances. Through this table, you can explore firewall-specific details such as creation and update times, current status, and associated rules. + +## Examples + +### Basic info +Retrieve a list of all firewalls in your Linode account to get an overview of your security infrastructure. + +```sql+postgres +select + id, + created, + updated, + label +from + linode_firewall; +``` + +```sql+sqlite +select + id, + created, + updated, + label +from + linode_firewall; +``` + +### Firewalls that are enabled +Explore the enabled firewalls to ensure that your security configurations are active and properly managed. + +```sql+postgres +select + label, + status, + created, + updated +from + linode_firewall +where + status = 'enabled'; +``` + +```sql+sqlite +select + label, + status, + created, + updated +from + linode_firewall +where + status = 'enabled'; +``` + +### Recently updated firewalls +List all firewalls that have been updated in the last 30 days to track recent changes in your security settings. + +```sql+postgres +select + label, + updated, + status +from + linode_firewall +where + updated >= current_date - interval '30 days'; +``` + +```sql+sqlite +select + label, + updated, + status +from + linode_firewall +where + updated >= date('now', '-30 days'); +``` + +### Get inbound rule details of firewalls +This query retrieves detailed information about the inbound rules configured for each Linode firewall, including label, ports, action, protocol, description, and addresses. + +```sql+postgres +select + f.id, + f.label, + i ->> 'label' as inbound_label, + i ->> 'ports' as inbound_ports, + i ->> 'action' as inbound_action, + i ->> 'protocol' as inbound_protocol, + i ->> 'description' as inbound_description, + i -> 'addresses' as inbound_addresses +from + linode_firewall as f, + jsonb_array_elements(rules -> 'inbound') as i; +``` + +```sql+sqlite +select + f.id, + f.label, + json_extract(i.value, '$.label') as inbound_label, + json_extract(i.value, '$.ports') as inbound_ports, + json_extract(i.value, '$.action') as inbound_action, + json_extract(i.value, '$.protocol') as inbound_protocol, + json_extract(i.value, '$.description') as inbound_description, + json_extract(i.value, '$.addresses') as inbound_addresses +from + linode_firewall as f, + json_each(rules -> 'inbound') as i; +``` + +### Get outbound rule details of firewalls +This query retrieves detailed information about the outbound rules configured for each Linode firewall, including label, ports, action, protocol, description, and addresses. + +```sql+postgres +select + f.id, + f.label, + o ->> 'label' as outbound_label, + o ->> 'ports' as outbound_ports, + o ->> 'action' as outbound_action, + o ->> 'protocol' as outbound_protocol, + o ->> 'description' as outbound_description, + o -> 'addresses' as outbound_addresses +from + linode_firewall as f, + jsonb_array_elements(rules -> 'outbound') as o; +``` + +```sql+sqlite +select + f.id, + f.label, + json_extract(o.value, '$.label') as outbound_label, + json_extract(o.value, '$.ports') as outbound_ports, + json_extract(o.value, '$.action') as outbound_action, + json_extract(o.value, '$.protocol') as outbound_protocol, + json_extract(o.value, '$.description') as outbound_description, + json_extract(o.value, '$.addresses') as outbound_addresses +from + linode_firewall as f, + json_each(rules -> 'outbound') as o; +``` \ No newline at end of file diff --git a/linode/plugin.go b/linode/plugin.go index c32f9b0..9cc0bea 100644 --- a/linode/plugin.go +++ b/linode/plugin.go @@ -23,6 +23,7 @@ func Plugin(ctx context.Context) *plugin.Plugin { "linode_domain": tableLinodeDomain(ctx), "linode_domain_record": tableLinodeDomainRecord(ctx), "linode_event": tableLinodeEvent(ctx), + "linode_firewall": tableLinodeFirewall(ctx), "linode_image": tableLinodeImage(ctx), "linode_instance": tableLinodeInstance(ctx), "linode_kubernetes_cluster": tableLinodeKubernetesCluster(ctx), diff --git a/linode/table_linode_firewall.go b/linode/table_linode_firewall.go new file mode 100644 index 0000000..f417018 --- /dev/null +++ b/linode/table_linode_firewall.go @@ -0,0 +1,73 @@ +package linode + +import ( + "context" + + "github.com/linode/linodego" + "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" + "github.com/turbot/steampipe-plugin-sdk/v5/plugin" +) + +func tableLinodeFirewall(ctx context.Context) *plugin.Table { + return &plugin.Table{ + Name: "linode_firewall", + Description: "Firewalls in the Linode account.", + List: &plugin.ListConfig{ + Hydrate: listFirewalls, + }, + Get: &plugin.GetConfig{ + KeyColumns: plugin.SingleColumn("id"), + Hydrate: getFirewall, + }, + Columns: commonColumns([]*plugin.Column{ + // Top columns + {Name: "id", Type: proto.ColumnType_INT, Description: "The unique ID of this Firewall."}, + {Name: "created", Type: proto.ColumnType_TIMESTAMP, Description: "The date and time this firewall was created."}, + {Name: "updated", Type: proto.ColumnType_TIMESTAMP, Description: "The date and time this firewall was updated."}, + {Name: "label", Type: proto.ColumnType_STRING, Description: "The firewall’s label is for display purposes only."}, + {Name: "status", Type: proto.ColumnType_STRING, Description: "The status of the firewall. Possible values are 'enabled', 'disabled', or 'deleted'."}, + {Name: "tags", Type: proto.ColumnType_JSON, Description: "Tags applied to this firewall."}, + {Name: "rules", Type: proto.ColumnType_JSON, Description: "The rules associated with the firewall."}, + }), + } +} + +func listFirewalls(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { + conn, err := connect(ctx, d) + if err != nil { + plugin.Logger(ctx).Error("linode_firewall.listFirewall", "connection_error", err) + return nil, err + } + + opts := linodego.ListOptions{} + + items, err := conn.ListFirewalls(ctx, &opts) + if err != nil { + plugin.Logger(ctx).Error("linode_firewall.listFirewall", "query_error", err, "opts", opts) + return nil, err + } + for _, i := range items { + d.StreamListItem(ctx, i) + + // Context may get cancelled due to manual cancellation or if the limit has been reached + if d.RowsRemaining(ctx) == 0 { + return nil, nil + } + } + return nil, nil +} + +func getFirewall(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { + conn, err := connect(ctx, d) + if err != nil { + plugin.Logger(ctx).Error("linode_firewall.getFirewall", "connection_error", err) + return nil, err + } + id := int(d.EqualsQuals["id"].GetInt64Value()) + item, err := conn.GetFirewall(ctx, id) + if err != nil { + plugin.Logger(ctx).Error("linode_firewall.getFirewall", "query_error", err) + return nil, err + } + return item, err +}