From 03b33614ad5bd86d7bb788d5b758831c2a19738a Mon Sep 17 00:00:00 2001 From: Borys_Levytskyi Date: Sat, 24 Apr 2021 11:08:37 +0300 Subject: [PATCH] Improve VPC view --- src/core/components/BinaryString.tsx | 10 ++++++- src/core/formatter.test.ts | 7 +++++ src/core/formatter.ts | 29 +++++++++++++++++++ src/networking/components/SubnetView.tsx | 20 ++++++------- src/networking/components/VpcView.css | 12 ++++++++ src/networking/components/VpcView.tsx | 36 ++++++++++++++++++------ src/networking/models.ts | 9 +++--- 7 files changed, 98 insertions(+), 25 deletions(-) diff --git a/src/core/components/BinaryString.tsx b/src/core/components/BinaryString.tsx index 61f1c8b..1dc566c 100644 --- a/src/core/components/BinaryString.tsx +++ b/src/core/components/BinaryString.tsx @@ -5,7 +5,8 @@ export type BinaryStringViewProps = { binaryString: string; onFlipBit?: (input: FlipBitEventArg) => void; emphasizeBytes?: boolean; - className?:string + className?:string; + disableHighlight?:boolean }; export type FlipBitEventArg = { @@ -50,8 +51,15 @@ export default class BinaryStringView extends React.Component { + var className = c == '1' ? `one${css}` : `zero${css}`; + + if(disableHighlight) + className = css; + return this.onBitClick(i, e)}>{c} }); } diff --git a/src/core/formatter.test.ts b/src/core/formatter.test.ts index b26f553..f0d16b1 100644 --- a/src/core/formatter.test.ts +++ b/src/core/formatter.test.ts @@ -10,4 +10,11 @@ describe("formatter", () => { it('pads left', () => { expect(formatter.padLeft("1", 3, " ")).toBe(" 1"); }); + + it('splits ip address by mask', () => { + const ip = "11000000.10101000.00000001.00000001"; + expect(formatter.splitByMasks(ip, 2, 3)).toEqual({vpc:"11", subnet:"0", hosts:"00000.10101000.00000001.00000001"}); + expect(formatter.splitByMasks(ip, 8, 16)).toEqual({vpc:"11000000", subnet:".10101000", hosts:".00000001.00000001"}); + expect(formatter.splitByMasks(ip, 8, 22)).toEqual({vpc:"11000000", subnet:".10101000.000000", hosts:"01.00000001"}); + }) }); \ No newline at end of file diff --git a/src/core/formatter.ts b/src/core/formatter.ts index f62ecea..2e5cd04 100644 --- a/src/core/formatter.ts +++ b/src/core/formatter.ts @@ -20,6 +20,35 @@ const formatter = { }, emBin(number: number) { return this.padLeft(this.bin(number), 8, '0'); + }, + + splitByMasks(ipAddrBin: string, mask1: number, mask2: number) : {vpc: string, subnet: string, hosts:string} { + + var res = []; + var tmp : string[] = []; + var mask = 0; + var b = mask1; + + ipAddrBin.split('').forEach(ch => { + + tmp.push(ch); + + if(ch === ".") { + return; + } + + mask++; + + if(mask == b) { + b = mask2; + res.push(tmp.join('')); + tmp = []; + } + }); + + if(tmp.length > 0) res.push(tmp.join('')); + + return { vpc: res[0], subnet: res[1], hosts: res[2]}; } }; diff --git a/src/networking/components/SubnetView.tsx b/src/networking/components/SubnetView.tsx index 7ee7d97..169ffdc 100644 --- a/src/networking/components/SubnetView.tsx +++ b/src/networking/components/SubnetView.tsx @@ -11,28 +11,28 @@ function SubnetView(props : {subnet : SubnetCommand}) { const [subnet, setSubnet] = useState(props.subnet); const incrementMask = () => { - const newInput = new IpAddressWithSubnetMask(subnet.input.ipAddress, subnet.input.maskBits+1); + const newInput = new IpAddressWithSubnetMask(subnet.cidr.ipAddress, subnet.cidr.maskBits+1); setSubnet(new SubnetCommand(newInput)); }; const decrementMask = () => { - const newInput = new IpAddressWithSubnetMask(subnet.input.ipAddress, subnet.input.maskBits-1); + const newInput = new IpAddressWithSubnetMask(subnet.cidr.ipAddress, subnet.cidr.maskBits-1); setSubnet(new SubnetCommand(newInput)); } return - - - - + + + + @@ -41,9 +41,9 @@ function SubnetView(props : {subnet : SubnetCommand}) { diff --git a/src/networking/components/VpcView.css b/src/networking/components/VpcView.css index 8f9c26c..deedb20 100644 --- a/src/networking/components/VpcView.css +++ b/src/networking/components/VpcView.css @@ -7,6 +7,18 @@ margin-bottom: 20px; } +.vpc-view { + margin-bottom: 20px; +} + +.vpc-view .host-part { + color: teal; +} + +.vpc-view .subnet-part { + color:mediumseagreen; +} + .vpc-view .part { border-bottom: solid 1px; } diff --git a/src/networking/components/VpcView.tsx b/src/networking/components/VpcView.tsx index a88a445..a8c65f1 100644 --- a/src/networking/components/VpcView.tsx +++ b/src/networking/components/VpcView.tsx @@ -5,10 +5,14 @@ import { getNetworkAddress, getBroadCastAddress, createSubnetMaskIp, getAddressS import { chunkifyString } from '../../core/utils'; import IpAddressBinaryString from './IpAddressBinaryString'; import { IpAddress, IpAddressWithSubnetMask, SubnetCommand, VpcCommand } from '../models'; -import { padLeft } from '../../core/formatter'; +import formatter, { padLeft } from '../../core/formatter'; + +type ViewMode = "color" | "table"; function SubnetView(props : {vpc : VpcCommand}) { + const mode : ViewMode = "color"; + const [vpc, setVpc] = useState(VpcModel.create(props.vpc)); const subnetMaskSize = vpc.cidr.maskBits + vpc.subnetBits; @@ -17,15 +21,25 @@ function SubnetView(props : {vpc : VpcCommand}) { const lastPart = padLeft("0", 32 - (vpc.cidr.maskBits + vpc.subnetBits), "0"); const maxSubnets = Math.pow(2, vpc.subnetBits); const hostsPerSubnet = getAddressSpaceSize(subnetMaskSize); + const networkAddress = getNetworkAddress(vpc.cidr); const decrSubnet = () => setVpc(vpc.changeSubnetBits(vpc.subnetBits-1)); - const incrSubnet = () => setVpc(vpc.changeSubnetBits(vpc.subnetBits+1)); + const incrSubnet = () => setVpc(vpc.changeSubnetBits(vpc.subnetBits+1)); const incrVpc = () => setVpc(vpc.changeVpcCidr(new IpAddressWithSubnetMask(vpc.cidr.ipAddress, vpc.cidr.maskBits+1))); const decrVpc = () => setVpc(vpc.changeVpcCidr(new IpAddressWithSubnetMask(vpc.cidr.ipAddress, vpc.cidr.maskBits-1))); + + const split = formatter.splitByMasks(networkAddress.toBinaryString(), vpc.cidr.maskBits, subnetMaskSize); + return +
-
+
+ + + +
+
Network Size - {subnet.input.getAdressSpaceSize()} + {subnet.cidr.getAdressSpaceSize()}
- - {subnet.input.maskBits} - + + {subnet.cidr.maskBits} +
- diff --git a/src/networking/models.ts b/src/networking/models.ts index 02ab9de..cc53215 100644 --- a/src/networking/models.ts +++ b/src/networking/models.ts @@ -1,5 +1,4 @@ import {emBin} from "../core/formatter"; -import { numberParser } from "../expression/numberParser"; import { getAddressSpaceSize } from "./subnet-utils"; export type OctetNumber = 1 | 2 | 3 | 4; @@ -73,13 +72,13 @@ export class IpAddress { } export class SubnetCommand { - input: IpAddressWithSubnetMask; // TODO: rename to cidr - constructor(definition: IpAddressWithSubnetMask) { - this.input = definition; + cidr: IpAddressWithSubnetMask; // TODO: rename to cidr + constructor(cidr: IpAddressWithSubnetMask) { + this.cidr = cidr; } toString() { - return this.input.toString(); + return this.cidr.toString(); } }
@@ -42,12 +56,12 @@ function SubnetView(props : {vpc : VpcCommand}) { - + - + @@ -70,15 +84,19 @@ function SubnetView(props : {vpc : VpcCommand}) { VPC CIDR Mask: - /{vpc.cidr.maskBits} + + /{vpc.cidr.maskBits} +
- Subnet CIDR Mask: + + Subnet CIDR Mask: - /{subnetMaskSize} + + /{subnetMaskSize} +