1package App::Netdisco::Web::API::Objects;
2
3use Dancer ':syntax';
4use Dancer::Plugin::DBIC;
5use Dancer::Plugin::Swagger;
6use Dancer::Plugin::Auth::Extensible;
7
8use Try::Tiny;
9
10swagger_path {
11  tags => ['Objects'],
12  path => setting('api_base').'/object/device/{ip}',
13  description => 'Returns a row from the device table',
14  parameters  => [
15    ip => {
16      description => 'Canonical IP of the Device. Use Search methods to find this.',
17      required => 1,
18      in => 'path',
19    },
20  ],
21  responses => { default => {} },
22}, get '/api/v1/object/device/:ip' => require_role api => sub {
23  my $device = try { schema('netdisco')->resultset('Device')
24    ->find( params->{ip} ) } or send_error('Bad Device', 404);
25  return to_json $device->TO_JSON;
26};
27
28foreach my $rel (qw/device_ips vlans ports modules port_vlans wireless_ports ssids powered_ports/) {
29    swagger_path {
30      tags => ['Objects'],
31      path => setting('api_base')."/object/device/{ip}/$rel",
32      description => "Returns $rel rows for a given device",
33      parameters  => [
34        ip => {
35          description => 'Canonical IP of the Device. Use Search methods to find this.',
36          required => 1,
37          in => 'path',
38        },
39      ],
40      responses => { default => {} },
41    }, get "/api/v1/object/device/:ip/$rel" => require_role api => sub {
42      my $rows = try { schema('netdisco')->resultset('Device')
43        ->find( params->{ip} )->$rel } or send_error('Bad Device', 404);
44      return to_json [ map {$_->TO_JSON} $rows->all ];
45    };
46}
47
48swagger_path {
49  tags => ['Objects'],
50  description => 'Returns a row from the device_port table',
51  path => setting('api_base').'/object/device/{ip}/port/{port}',
52  parameters  => [
53    ip => {
54      description => 'Canonical IP of the Device. Use Search methods to find this.',
55      required => 1,
56      in => 'path',
57    },
58    port => {
59      description => 'Name of the port. Use the ".../device/{ip}/ports" method to find these.',
60      required => 1,
61      in => 'path',
62    },
63  ],
64  responses => { default => {} },
65}, get qr{/api/v1/object/device/(?<ip>[^/]+)/port/(?<port>[^/]+)$} => require_role api => sub {
66  my $params = captures;
67  my $port = try { schema('netdisco')->resultset('DevicePort')
68    ->find( $$params{port}, $$params{ip} ) }
69    or send_error('Bad Device or Port', 404);
70  return to_json $port->TO_JSON;
71};
72
73foreach my $rel (qw/nodes active_nodes nodes_with_age active_nodes_with_age vlans logs/) {
74    swagger_path {
75      tags => ['Objects'],
76      description => "Returns $rel rows for a given port",
77      path => setting('api_base')."/object/device/{ip}/port/{port}/$rel",
78      parameters  => [
79        ip => {
80          description => 'Canonical IP of the Device. Use Search methods to find this.',
81          required => 1,
82          in => 'path',
83        },
84        port => {
85          description => 'Name of the port. Use the ".../device/{ip}/ports" method to find these.',
86          required => 1,
87          in => 'path',
88        },
89      ],
90      responses => { default => {} },
91    }, get qq{/api/v1/object/device/(?<ip>[^/]+)/port/(?<port>[^/]+)/$rel} => require_role api => sub {
92      my $params = captures;
93      my $rows = try { schema('netdisco')->resultset('DevicePort')
94        ->find( $$params{port}, $$params{ip} )->$rel }
95        or send_error('Bad Device or Port', 404);
96      return to_json [ map {$_->TO_JSON} $rows->all ];
97    };
98}
99
100foreach my $rel (qw/power properties ssid wireless agg_master neighbor last_node/) {
101    swagger_path {
102      tags => ['Objects'],
103      description => "Returns the related $rel table entry for a given port",
104      path => setting('api_base')."/object/device/{ip}/port/{port}/$rel",
105      parameters  => [
106        ip => {
107          description => 'Canonical IP of the Device. Use Search methods to find this.',
108          required => 1,
109          in => 'path',
110        },
111        port => {
112          description => 'Name of the port. Use the ".../device/{ip}/ports" method to find these.',
113          required => 1,
114          in => 'path',
115        },
116      ],
117      responses => { default => {} },
118    }, get qq{/api/v1/object/device/(?<ip>[^/]+)/port/(?<port>[^/]+)/$rel} => require_role api => sub {
119      my $params = captures;
120      my $row = try { schema('netdisco')->resultset('DevicePort')
121        ->find( $$params{port}, $$params{ip} )->$rel }
122        or send_error('Bad Device or Port', 404);
123      return to_json $row->TO_JSON;
124    };
125}
126
127swagger_path {
128  tags => ['Objects'],
129  path => setting('api_base').'/object/device/{ip}/nodes',
130  description => "Returns the nodes found on a given Device",
131  parameters  => [
132    ip => {
133      description => 'Canonical IP of the Device. Use Search methods to find this.',
134      required => 1,
135      in => 'path',
136    },
137    active_only => {
138      description => 'Restrict results to active Nodes only',
139      type => 'boolean',
140      default => 'true',
141      in => 'query',
142    },
143  ],
144  responses => { default => {} },
145}, get '/api/v1/object/device/:ip/nodes' => require_role api => sub {
146  my $active = (params->{active_only} and ('true' eq params->{active_only})) ? 1 : 0;
147  my $rows = try { schema('netdisco')->resultset('Node')
148    ->search({ switch => params->{ip}, ($active ? (-bool => 'active') : ()) }) }
149    or send_error('Bad Device', 404);
150  return to_json [ map {$_->TO_JSON} $rows->all ];
151};
152
153swagger_path {
154  tags => ['Objects'],
155  path => setting('api_base').'/object/vlan/{vlan}/nodes',
156  description => "Returns the nodes found in a given VLAN",
157  parameters  => [
158    vlan => {
159      description => 'VLAN number',
160      type => 'integer',
161      required => 1,
162      in => 'path',
163    },
164    active_only => {
165      description => 'Restrict results to active Nodes only',
166      type => 'boolean',
167      default => 'true',
168      in => 'query',
169    },
170  ],
171  responses => { default => {} },
172}, get '/api/v1/object/vlan/:vlan/nodes' => require_role api => sub {
173  my $active = (params->{active_only} and ('true' eq params->{active_only})) ? 1 : 0;
174  my $rows = try { schema('netdisco')->resultset('Node')
175    ->search({ vlan => params->{vlan}, ($active ? (-bool => 'active') : ()) }) }
176    or send_error('Bad VLAN', 404);
177  return to_json [ map {$_->TO_JSON} $rows->all ];
178};
179
180true;
181