#include #include #include #include #include #include enum { SELECTOR_TYPE_IP, SELECTOR_TYPE_POD_NAME }; // Assigns a type depending if addr matchs IP regex void findAddressType(char *addr, int *type) { regex_t ip_addr_regex; int result = regcomp( &ip_addr_regex, "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+(/[0-9][0-9]?)?$", REG_EXTENDED); if (result == 1) { // REGEX FAILED TO COMPILE return; } int match = !regexec(&ip_addr_regex, addr, 0, NULL, 0); if (match) { // NO MATCH *type = SELECTOR_TYPE_IP; return; } *type = SELECTOR_TYPE_POD_NAME; } void checkArgs(char *sourceaddr, int *sourcetype, char *destaddr, int *desttype) { findAddressType(sourceaddr, sourcetype); findAddressType(destaddr, desttype); } void writeFile(char *outputfilename, char *policy_type, char *sourceaddr, int sourcetype, char *destaddr, int desttype, int port, char *protocol) { const char *ingress_yaml_template = "apiVersion: networking.k8s.io/v1\n" "kind: NetworkPolicy\n" "metadata:\n" " name: test-network-policy\n" " namespace: policy-demo\n" "spec:\n" " podSelector:\n" " matchLabels:\n" " run: %s\n" //destination " policyTypes:\n" " - Ingress\n" " ingress:\n" " - from:\n%s" //source " ports:\n" " - protocol: %s\n" " port: %d\n"; const char *egress_yaml_template = "apiVersion: networking.k8s.io/v1\n" "kind: NetworkPolicy\n" "metadata:\n" " name: test-network-policy\n" " namespace: policy-demo\n" "spec:\n" " podSelector:\n" " matchLabels:\n" " run: %s\n" //source " policyTypes:\n" " - Egress\n" " egress:\n" " - to:\n%s" //destination " ports:\n" " - protocol: %s\n" " port: %d\n" " - to:\n" // WE MUST ALLOW ACCESS TO KUBERNETES DNS SERVER, OTHERWISE POD NAMES WILL NOT RESOLVE TO THEIR IP " - ipBlock:\n" " cidr: 0.0.0.0/0\n" " ports:\n" " - protocol: UDP\n" " port: 53\n" " - protocol: TCP\n" " port: 53\n"; const char *ip_template = " - ipBlock:\n" " cidr: %s\n"; const char *pod_template = " - podSelector:\n" " matchLabels:\n" " run: %s\n"; const char *source_template = sourcetype == SELECTOR_TYPE_IP ? ip_template : pod_template; const char *destination_template = desttype == SELECTOR_TYPE_IP ? ip_template : pod_template; char outputBuf[2000], source_template_filled[1000], destination_template_filled[1000]; sprintf(source_template_filled, source_template, sourceaddr); sprintf(destination_template_filled, destination_template, destaddr); if(strcmp(policy_type, "egress") == 0){ sprintf(outputBuf, egress_yaml_template, sourceaddr, destination_template_filled, protocol, port); } else if(strcmp(policy_type, "ingress") == 0){ sprintf(outputBuf, ingress_yaml_template, destaddr, source_template_filled, protocol, port); } // puts("----------------------"); // printf("%s\n", ingress_template_filled); // puts("----------------------"); // printf("%s\n", egress_template_filled); // puts("----------------------"); // printf("%s\n", outputBuf); // puts("----------------------"); FILE *outputFile = fopen(outputfilename, "w"); fputs(outputBuf, outputFile); fclose(outputFile); } int main(int argc, char *argv[]) { //source, destination, port, protocal and policy if (argc < 5) { fprintf(stderr, "Usage:\t %s policytype sourceip destinationip port " "protocol [-o outputfile]\n", argv[0]); fprintf(stderr, "\tor %s policytype sourcepod destinationpod port " "protocol [-o outputfile]\n", argv[0]); fprintf(stderr, "\nExample:\t%s ingress access nginx 80 TCP " "-o test.yaml\n", argv[0]); fprintf(stderr, "\t\t%s egress nginx access 5978 TCP\n", argv[0]); return EX_USAGE; } int opt; char output[200] = ""; while ((opt = getopt(argc, argv, "o:")) != -1) { switch (opt) { case 'o': strcpy(output, optarg); break; } } if (strlen(output) == 0) { strcpy(output, "ingress-egress-nginx.yaml"); } char *policy_type = argv[optind]; char *sourceaddr = argv[optind + 1]; char *destaddr = argv[optind + 2]; int port; sscanf(argv[optind + 3], "%d", &port); char *protocol = argv[optind + 4]; int sourcetype, desttype; checkArgs(sourceaddr, &sourcetype, destaddr, &desttype); writeFile(output, policy_type, sourceaddr, sourcetype, destaddr, desttype, port, protocol); char cmd[100]; sprintf(cmd, "kubectl apply -f ./%s", output); printf("%s\n", cmd); system(cmd); return 0; }