Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F73771
network.rs
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Subscribers
None
network.rs
View Options
use
std
::
sync
::
Arc
;
use
axum
::
{
extract
::
{
Path
,
State
},
http
::
StatusCode
,
response
::
IntoResponse
,
Json
,
};
use
serde
::
{
Deserialize
,
Serialize
};
use
store
::
network
::
{
BasicAssigner
,
BasicProvider
,
NetRange
,
RangeAssigner
};
use
crate
::
AppState
;
#[derive(Serialize, Deserialize)]
pub
struct
CreateNetworkRequest
{
pub
name
:
String
,
pub
cidr
:
String
,
pub
provider_type
:
Option
<
String
>
,
pub
provider_config
:
Option
<
serde_json
::
Value
>
,
pub
assigner_type
:
Option
<
String
>
,
pub
assigner_config
:
Option
<
serde_json
::
Value
>
,
}
pub
async
fn
get_networks
(
State
(
state
)
:
State
<
Arc
<
AppState
>>
)
->
impl
IntoResponse
{
let
networks
=
state
.
collar
.
store
.
networks
();
match
networks
.
list
()
{
Ok
(
network_list
)
=>
(
StatusCode
::
OK
,
Json
(
network_list
)).
into_response
(),
Err
(
e
)
=>
(
StatusCode
::
INTERNAL_SERVER_ERROR
,
format!
(
"Failed to list networks: {:?}"
,
e
)).
into_response
(),
}
}
pub
async
fn
post_networks
(
State
(
state
)
:
State
<
Arc
<
AppState
>>
,
Json
(
req
)
:
Json
<
CreateNetworkRequest
>
)
->
impl
IntoResponse
{
let
networks
=
state
.
collar
.
store
.
networks
();
// Parse the CIDR
let
netrange
=
match
NetRange
::
from_cidr
(
&
req
.
cidr
)
{
Ok
(
range
)
=>
range
,
Err
(
e
)
=>
return
(
StatusCode
::
BAD_REQUEST
,
format!
(
"Invalid CIDR '{}': {:?}"
,
req
.
cidr
,
e
)).
into_response
(),
};
// Create basic provider with optional config
let
provider
=
if
let
Some
(
config
)
=
req
.
provider_config
{
BasicProvider
::
new
().
with_config
(
"config"
,
&
config
.
to_string
())
}
else
{
BasicProvider
::
new
()
};
// Handle different assigner types with separate create calls
let
result
=
if
let
Some
(
assigner_type
)
=
req
.
assigner_type
{
match
assigner_type
.
as_str
()
{
"basic"
=>
{
let
mut
basic_assigner
=
BasicAssigner
::
new
(
"sequential"
);
if
let
Some
(
config
)
=
req
.
assigner_config
{
basic_assigner
=
basic_assigner
.
with_config
(
"config"
,
&
config
.
to_string
());
}
networks
.
create
(
&
req
.
name
,
netrange
,
provider
,
Some
(
basic_assigner
))
},
"range"
=>
{
if
let
Some
(
config
)
=
req
.
assigner_config
{
if
let
Some
(
range_name
)
=
config
.
get
(
"range_name"
).
and_then
(
|
v
|
v
.
as_str
())
{
let
mut
range_assigner
=
RangeAssigner
::
with_range_name
(
range_name
);
if
let
Some
(
extra_config
)
=
config
.
get
(
"config"
)
{
range_assigner
=
range_assigner
.
with_config
(
"config"
,
&
extra_config
.
to_string
());
}
networks
.
create
(
&
req
.
name
,
netrange
,
provider
,
Some
(
range_assigner
))
}
else
{
return
(
StatusCode
::
BAD_REQUEST
,
"Range assigner requires 'range_name' in config"
.
to_string
()).
into_response
();
}
}
else
{
return
(
StatusCode
::
BAD_REQUEST
,
"Range assigner requires config with 'range_name'"
.
to_string
()).
into_response
();
}
},
_
=>
return
(
StatusCode
::
BAD_REQUEST
,
format!
(
"Unknown assigner type: {}"
,
assigner_type
)).
into_response
(),
}
}
else
{
networks
.
create
(
&
req
.
name
,
netrange
,
provider
,
None
::
<
BasicAssigner
>
)
};
// Handle the result
match
result
{
Ok
(
_
)
=>
(
StatusCode
::
OK
,
format!
(
"Created network '{}'"
,
req
.
name
)).
into_response
(),
Err
(
e
)
=>
(
StatusCode
::
INTERNAL_SERVER_ERROR
,
format!
(
"Failed to create network '{}': {:?}"
,
req
.
name
,
e
)).
into_response
(),
}
}
pub
async
fn
get_network
(
State
(
state
)
:
State
<
Arc
<
AppState
>>
,
Path
(
name
)
:
Path
<
String
>
)
->
impl
IntoResponse
{
let
networks
=
state
.
collar
.
store
.
networks
();
match
networks
.
get
(
&
name
)
{
Ok
(
Some
(
network
))
=>
{
let
network_json
=
serde_json
::
json
!
({
"name"
:
network
.
name
,
"netrange"
:
match
network
.
netrange
{
NetRange
::
V4
{
addr
,
prefix
}
=>
{
serde_json
::
json
!
({
"type"
:
"v4"
,
"addr"
:
addr
.
to_string
(),
"prefix"
:
prefix
})
},
NetRange
::
V6
{
addr
,
prefix
}
=>
{
serde_json
::
json
!
({
"type"
:
"v6"
,
"addr"
:
addr
.
to_string
(),
"prefix"
:
prefix
})
}
},
"provider_type"
:
network
.
provider_type
,
"provider_config"
:
serde_json
::
from_str
::
<
serde_json
::
Value
>
(
&
network
.
provider_config
).
unwrap_or
(
serde_json
::
Value
::
Null
),
"assigner_type"
:
network
.
assigner_type
,
"assigner_config"
:
network
.
assigner_config
.
as_ref
()
.
and_then
(
|
config
|
serde_json
::
from_str
::
<
serde_json
::
Value
>
(
config
).
ok
())
.
unwrap_or
(
serde_json
::
Value
::
Null
)
});
(
StatusCode
::
OK
,
Json
(
network_json
)).
into_response
()
},
Ok
(
None
)
=>
(
StatusCode
::
NOT_FOUND
,
format!
(
"Network '{}' not found"
,
name
)).
into_response
(),
Err
(
e
)
=>
(
StatusCode
::
INTERNAL_SERVER_ERROR
,
format!
(
"Failed to get network '{}': {:?}"
,
name
,
e
)).
into_response
(),
}
}
pub
async
fn
delete_network
(
State
(
state
)
:
State
<
Arc
<
AppState
>>
,
Path
(
name
)
:
Path
<
String
>
)
->
impl
IntoResponse
{
let
networks
=
state
.
collar
.
store
.
networks
();
match
networks
.
delete
(
&
name
)
{
Ok
(
true
)
=>
(
StatusCode
::
OK
,
format!
(
"Deleted network '{}'"
,
name
)).
into_response
(),
Ok
(
false
)
=>
(
StatusCode
::
NOT_FOUND
,
format!
(
"Network '{}' not found"
,
name
)).
into_response
(),
Err
(
e
)
=>
(
StatusCode
::
INTERNAL_SERVER_ERROR
,
format!
(
"Failed to delete network '{}': {:?}"
,
name
,
e
)).
into_response
(),
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jun 9, 11:45 AM (11 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
47644
Default Alt Text
network.rs (5 KB)
Attached To
rCOLLAR collar
Event Timeline
Log In to Comment